Skip to content

Commit fb0a5a5

Browse files
committed
Auto merge of #156341 - matthiaskrgr:rollup-MPIc60x, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #156141 (Resolve some cases of #132279 by using the right typing mode in the next solver) - #156244 (fix incorrect suggestions in private import diagnostic) - #156306 (Move tests consts) - #156333 (Avoid invalid spans in dotdotdot rest pattern suggestions) - #156337 (rustc-dev-guide subtree update)
2 parents 8068e2f + 53526f5 commit fb0a5a5

48 files changed

Lines changed: 604 additions & 131 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

compiler/rustc_const_eval/src/check_consts/qualifs.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_errors::ErrorGuaranteed;
99
use rustc_hir::LangItem;
1010
use rustc_infer::infer::TyCtxtInferExt;
1111
use rustc_middle::mir::*;
12-
use rustc_middle::ty::{self, AdtDef, Ty};
12+
use rustc_middle::ty::{self, AdtDef, Ty, TypingMode};
1313
use rustc_middle::{bug, mir};
1414
use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt};
1515
use tracing::instrument;
@@ -100,13 +100,14 @@ impl Qualif for HasMutInterior {
100100
// Instead we invoke an obligation context manually, and provide the opaque type inference settings
101101
// that allow the trait solver to just error out instead of cycling.
102102
let freeze_def_id = cx.tcx.require_lang_item(LangItem::Freeze, cx.body.span);
103-
// FIXME(#132279): Once we've got a typing mode which reveals opaque types using the HIR
104-
// typeck results without causing query cycles, we should use this here instead of defining
105-
// opaque types.
106-
let typing_env = ty::TypingEnv::new(
107-
cx.typing_env.param_env,
108-
ty::TypingMode::analysis_in_body(cx.tcx, cx.body.source.def_id().expect_local()),
109-
);
103+
let did = cx.body.source.def_id().expect_local();
104+
105+
let typing_env = if cx.tcx.use_typing_mode_borrowck() {
106+
cx.typing_env
107+
} else {
108+
ty::TypingEnv::new(cx.typing_env.param_env, TypingMode::analysis_in_body(cx.tcx, did))
109+
};
110+
110111
let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(typing_env);
111112
let ocx = ObligationCtxt::new(&infcx);
112113
let obligation = Obligation::new(

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,35 @@ pub struct InferCtxt<'tcx> {
320320
pub obligation_inspector: Cell<Option<ObligationInspector<'tcx>>>,
321321
}
322322

323+
impl<'tcx> Drop for InferCtxt<'tcx> {
324+
fn drop(&mut self) {
325+
let mut inner = self.inner.borrow_mut();
326+
let opaque_type_storage = &mut inner.opaque_type_storage;
327+
328+
// No need for the drop bomb when we're in TypingMode::Borrowck, and the InferCtxt doesn't consider regions.
329+
// This is okay since in `Borrowck`, the only reason we care about opaques is in relation to regions.
330+
// In some places *after* typeck, like in lints we use `TypingMode::Borrowck`
331+
// to prevent defining opaque types and we simply don't care about regions.
332+
match self.typing_mode_raw() {
333+
TypingMode::Coherence
334+
| TypingMode::Analysis { .. }
335+
| TypingMode::PostBorrowckAnalysis { .. }
336+
| TypingMode::PostAnalysis => {}
337+
// In erased mode, the opaque type storage is always empty
338+
TypingMode::ErasedNotCoherence(..) => {}
339+
TypingMode::Borrowck { .. } => {
340+
if !self.considering_regions {
341+
return;
342+
}
343+
}
344+
}
345+
346+
if !opaque_type_storage.is_empty() {
347+
ty::tls::with(|tcx| tcx.dcx().delayed_bug(format!("{opaque_type_storage:?}")));
348+
}
349+
}
350+
}
351+
323352
/// See the `error_reporting` module for more details.
324353
#[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable)]
325354
pub enum ValuePairs<'tcx> {

compiler/rustc_infer/src/infer/opaque_types/table.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::ops::Deref;
33
use rustc_data_structures::fx::FxIndexMap;
44
use rustc_data_structures::undo_log::UndoLogs;
55
use rustc_middle::bug;
6-
use rustc_middle::ty::{self, OpaqueTypeKey, ProvisionalHiddenType, Ty};
6+
use rustc_middle::ty::{OpaqueTypeKey, ProvisionalHiddenType, Ty};
77
use tracing::instrument;
88

99
use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog};
@@ -121,14 +121,6 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
121121
}
122122
}
123123

124-
impl<'tcx> Drop for OpaqueTypeStorage<'tcx> {
125-
fn drop(&mut self) {
126-
if !self.is_empty() {
127-
ty::tls::with(|tcx| tcx.dcx().delayed_bug(format!("{:?}", self.opaque_types)));
128-
}
129-
}
130-
}
131-
132124
pub struct OpaqueTypeTable<'a, 'tcx> {
133125
storage: &'a mut OpaqueTypeStorage<'tcx>,
134126

compiler/rustc_lint/src/context.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -633,9 +633,14 @@ impl<'tcx> LateContext<'tcx> {
633633
/// The typing mode of the currently visited node. Use this when
634634
/// building a new `InferCtxt`.
635635
pub fn typing_mode(&self) -> TypingMode<'tcx> {
636-
// FIXME(#132279): In case we're in a body, we should use a typing
637-
// mode which reveals the opaque types defined by that body.
638-
TypingMode::non_body_analysis()
636+
if let Some(body_id) = self.enclosing_body
637+
&& self.tcx.use_typing_mode_borrowck()
638+
{
639+
let def_id = self.tcx.hir_enclosing_body_owner(body_id.hir_id);
640+
TypingMode::borrowck(self.tcx, def_id)
641+
} else {
642+
TypingMode::non_body_analysis()
643+
}
639644
}
640645

641646
pub fn typing_env(&self) -> TypingEnv<'tcx> {

compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
8484
}
8585

8686
let def_id = opaque.def_id.to_def_id();
87-
let infcx = &cx.tcx.infer_ctxt().build(cx.typing_mode());
87+
let infcx = &cx.tcx.infer_ctxt().ignoring_regions().build(cx.typing_mode());
8888
// For every projection predicate in the opaque type's explicit bounds,
8989
// check that the type that we're assigning actually satisfies the bounds
9090
// of the associated type.

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -413,13 +413,36 @@ impl<'tcx> Body<'tcx> {
413413
}
414414

415415
pub fn typing_env(&self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> {
416-
match self.phase {
417-
// FIXME(#132279): we should reveal the opaques defined in the body during analysis.
418-
MirPhase::Built | MirPhase::Analysis(_) => TypingEnv::new(
419-
tcx.param_env(self.source.def_id()),
420-
ty::TypingMode::non_body_analysis(),
421-
),
422-
MirPhase::Runtime(_) => TypingEnv::post_analysis(tcx, self.source.def_id()),
416+
if tcx.use_typing_mode_borrowck() {
417+
match self.phase {
418+
MirPhase::Built if let Some(def_id) = self.source.def_id().as_local() => {
419+
TypingEnv::new(
420+
tcx.param_env(self.source.def_id()),
421+
ty::TypingMode::borrowck(tcx, def_id),
422+
)
423+
}
424+
MirPhase::Analysis(_) if let Some(def_id) = self.source.def_id().as_local() => {
425+
TypingEnv::new(
426+
tcx.param_env(self.source.def_id()),
427+
ty::TypingMode::post_borrowck_analysis(tcx, def_id),
428+
)
429+
}
430+
MirPhase::Built | MirPhase::Analysis(_) => {
431+
// This branch happens for drop glue and fn ptr shims.
432+
// FIXME: why do we do any of this analysis on drop glue etc?
433+
// This should ideally all be skipped.
434+
TypingEnv::post_analysis(tcx, self.source.def_id())
435+
}
436+
MirPhase::Runtime(_) => TypingEnv::post_analysis(tcx, self.source.def_id()),
437+
}
438+
} else {
439+
match self.phase {
440+
MirPhase::Built | MirPhase::Analysis(_) => TypingEnv::new(
441+
tcx.param_env(self.source.def_id()),
442+
ty::TypingMode::non_body_analysis(),
443+
),
444+
MirPhase::Runtime(_) => TypingEnv::post_analysis(tcx, self.source.def_id()),
445+
}
423446
}
424447
}
425448

compiler/rustc_middle/src/ty/layout.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -528,12 +528,6 @@ pub trait HasTyCtxt<'tcx>: HasDataLayout {
528528

529529
pub trait HasTypingEnv<'tcx> {
530530
fn typing_env(&self) -> ty::TypingEnv<'tcx>;
531-
532-
/// FIXME(#132279): This method should not be used as in the future
533-
/// everything should take a `TypingEnv` instead. Remove it as that point.
534-
fn param_env(&self) -> ty::ParamEnv<'tcx> {
535-
self.typing_env().param_env
536-
}
537531
}
538532

539533
impl<'tcx> HasDataLayout for TyCtxt<'tcx> {

compiler/rustc_parse/src/errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3238,7 +3238,7 @@ pub(crate) struct DotDotDotRestPattern {
32383238
#[suggestion(
32393239
"for a rest pattern, use `..` instead of `...`",
32403240
style = "verbose",
3241-
code = "",
3241+
code = "..",
32423242
applicability = "machine-applicable"
32433243
)]
32443244
pub suggestion: Option<Span>,

compiler/rustc_parse/src/parser/pat.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -920,7 +920,7 @@ impl<'a> Parser<'a> {
920920
// The user probably mistook `...` for a rest pattern `..`.
921921
self.dcx().emit_err(DotDotDotRestPattern {
922922
span: lo,
923-
suggestion: Some(lo.with_lo(lo.hi() - BytePos(1))),
923+
suggestion: Some(lo),
924924
var_args: None,
925925
});
926926
PatKind::Rest

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2307,7 +2307,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
23072307

23082308
self.mention_default_field_values(source, ident, &mut err);
23092309

2310-
let mut not_publicly_reexported = false;
23112310
if let Some((this_res, outer_ident)) = outermost_res {
23122311
let mut import_suggestions = self.lookup_import_candidates(
23132312
outer_ident,
@@ -2332,7 +2331,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
23322331
);
23332332
// If we suggest importing a public re-export, don't point at the definition.
23342333
if point_to_def && ident.span != outer_ident.span {
2335-
not_publicly_reexported = true;
23362334
let label = errors::OuterIdentIsNotPubliclyReexported {
23372335
span: outer_ident.span,
23382336
outer_ident_descr: this_res.descr(),
@@ -2408,7 +2406,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
24082406
let first_binding = decl;
24092407
let mut next_binding = Some(decl);
24102408
let mut next_ident = ident;
2411-
let mut path = vec![];
24122409
while let Some(binding) = next_binding {
24132410
let name = next_ident;
24142411
next_binding = match binding.kind {
@@ -2428,18 +2425,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
24282425
};
24292426

24302427
match binding.kind {
2431-
DeclKind::Import { import, .. } => {
2432-
for segment in import.module_path.iter().skip(1) {
2433-
// Don't include `{{root}}` in suggestions - it's an internal symbol
2434-
// that should never be shown to users.
2435-
if segment.ident.name != kw::PathRoot {
2436-
path.push(segment.ident);
2437-
}
2438-
}
2439-
sugg_paths.push((
2440-
path.iter().cloned().chain(std::iter::once(ident)).collect::<Vec<_>>(),
2441-
true, // re-export
2442-
));
2428+
DeclKind::Import { source_decl, import, .. } => {
2429+
// Don't include `{{root}}` in suggestions - it's an internal symbol
2430+
// that should never be shown to users.
2431+
let path = import
2432+
.module_path
2433+
.iter()
2434+
.filter(|seg| seg.ident.name != kw::PathRoot)
2435+
.map(|seg| seg.ident.clone())
2436+
.chain(std::iter::once(ident))
2437+
.collect::<Vec<_>>();
2438+
let through_reexport = !matches!(source_decl.kind, DeclKind::Def(_));
2439+
sugg_paths.push((path, through_reexport));
24432440
}
24442441
DeclKind::Def(_) => {}
24452442
}
@@ -2472,25 +2469,34 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
24722469
};
24732470
err.subdiagnostic(note);
24742471
}
2475-
// We prioritize shorter paths, non-core imports and direct imports over the alternatives.
2476-
sugg_paths.sort_by_key(|(p, reexport)| (p.len(), p[0].name == sym::core, *reexport));
2477-
for (sugg, reexport) in sugg_paths {
2478-
if not_publicly_reexported {
2472+
// The suggestion replaces `dedup_span` with a path reaching the failing ident.
2473+
// That's valid only when
2474+
// 1) the failing ident is the imported leaf, otherwise `as` renames and trailing segments
2475+
// get dropped, and
2476+
// 2) the use isn't nested, otherwise `dedup_span` is one ident in `{...}`.
2477+
//
2478+
// See issue #156060.
2479+
let can_replace_use =
2480+
!single_nested && !outermost_res.is_some_and(|(_, outer)| outer.span != ident.span);
2481+
if can_replace_use {
2482+
// We prioritize shorter paths, non-core imports and direct imports over the
2483+
// alternatives.
2484+
sugg_paths.sort_by_key(|(p, reexport)| (p.len(), p[0].name == sym::core, *reexport));
2485+
for (sugg, reexport) in sugg_paths {
2486+
if sugg.len() <= 1 {
2487+
// A single path segment suggestion is wrong. This happens on circular
2488+
// imports. `tests/ui/imports/issue-55884-2.rs`
2489+
continue;
2490+
}
2491+
let path = join_path_idents(sugg);
2492+
let sugg = if reexport {
2493+
errors::ImportIdent::ThroughReExport { span: dedup_span, ident, path }
2494+
} else {
2495+
errors::ImportIdent::Directly { span: dedup_span, ident, path }
2496+
};
2497+
err.subdiagnostic(sugg);
24792498
break;
24802499
}
2481-
if sugg.len() <= 1 {
2482-
// A single path segment suggestion is wrong. This happens on circular imports.
2483-
// `tests/ui/imports/issue-55884-2.rs`
2484-
continue;
2485-
}
2486-
let path = join_path_idents(sugg);
2487-
let sugg = if reexport {
2488-
errors::ImportIdent::ThroughReExport { span: dedup_span, ident, path }
2489-
} else {
2490-
errors::ImportIdent::Directly { span: dedup_span, ident, path }
2491-
};
2492-
err.subdiagnostic(sugg);
2493-
break;
24942500
}
24952501

24962502
err.emit();

0 commit comments

Comments
 (0)