Skip to content

Commit 956db07

Browse files
committed
Don't fall back to crate-level opaque type definitions.
That would just hide bugs, as it works accidentally if the opaque type is defined at the crate level.
1 parent 72e74d7 commit 956db07

File tree

2 files changed

+36
-32
lines changed

2 files changed

+36
-32
lines changed

compiler/rustc_infer/src/infer/mod.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog};
1010

1111
use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine};
1212

13-
use hir::def_id::CRATE_DEF_ID;
1413
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1514
use rustc_data_structures::sync::Lrc;
1615
use rustc_data_structures::undo_log::Rollback;
@@ -291,7 +290,12 @@ pub struct InferCtxt<'a, 'tcx> {
291290

292291
/// The `DefId` of the item in whose context we are performing inference or typeck.
293292
/// It is used to check whether an opaque type use is a defining use.
294-
pub defining_use_anchor: LocalDefId,
293+
///
294+
/// If it is `None`, we can't resolve opaque types here and need to bubble up
295+
/// the obligation. This frequently happens for
296+
/// short lived InferCtxt within queries. The opaque type obligations are forwarded
297+
/// to the outside until the end up in an `InferCtxt` for typeck or borrowck.
298+
pub defining_use_anchor: Option<LocalDefId>,
295299

296300
/// During type-checking/inference of a body, `in_progress_typeck_results`
297301
/// contains a reference to the typeck results being built up, which are
@@ -547,7 +551,7 @@ impl<'tcx> fmt::Display for FixupError<'tcx> {
547551
pub struct InferCtxtBuilder<'tcx> {
548552
tcx: TyCtxt<'tcx>,
549553
fresh_typeck_results: Option<RefCell<ty::TypeckResults<'tcx>>>,
550-
defining_use_anchor: LocalDefId,
554+
defining_use_anchor: Option<LocalDefId>,
551555
}
552556

553557
pub trait TyCtxtInferExt<'tcx> {
@@ -556,11 +560,7 @@ pub trait TyCtxtInferExt<'tcx> {
556560

557561
impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
558562
fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
559-
InferCtxtBuilder {
560-
tcx: self,
561-
defining_use_anchor: CRATE_DEF_ID,
562-
fresh_typeck_results: None,
563-
}
563+
InferCtxtBuilder { tcx: self, defining_use_anchor: None, fresh_typeck_results: None }
564564
}
565565
}
566566

@@ -580,7 +580,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
580580
/// (via `with_fresh_in_progress_typeck_results`) and for the inference context used
581581
/// in mir borrowck.
582582
pub fn with_opaque_type_inference(mut self, defining_use_anchor: LocalDefId) -> Self {
583-
self.defining_use_anchor = defining_use_anchor;
583+
self.defining_use_anchor = Some(defining_use_anchor);
584584
self
585585
}
586586

compiler/rustc_infer/src/infer/opaque_types.rs

+27-23
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
328328
},
329329
});
330330
}
331+
332+
fn opaque_type_origin(&self, def_id: LocalDefId) -> Option<hir::OpaqueTyOrigin> {
333+
let tcx = self.tcx;
334+
let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
335+
let parent_def_id = self.defining_use_anchor?;
336+
let item_kind = &tcx.hir().expect_item(def_id).kind;
337+
let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item_kind else {
338+
span_bug!(
339+
tcx.def_span(def_id),
340+
"weird opaque type: {:#?}",
341+
item_kind
342+
)
343+
};
344+
let in_definition_scope = match *origin {
345+
// Async `impl Trait`
346+
hir::OpaqueTyOrigin::AsyncFn(parent) => parent == parent_def_id,
347+
// Anonymous `impl Trait`
348+
hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
349+
// Named `type Foo = impl Bar;`
350+
hir::OpaqueTyOrigin::TyAlias => {
351+
may_define_opaque_type(tcx, parent_def_id, opaque_hir_id)
352+
}
353+
};
354+
in_definition_scope.then_some(*origin)
355+
}
331356
}
332357

333358
// Visitor that requires that (almost) all regions in the type visited outlive
@@ -459,31 +484,10 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
459484
// }
460485
// ```
461486
if let Some(def_id) = def_id.as_local() {
462-
let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
463-
let parent_def_id = self.infcx.defining_use_anchor;
464-
let item_kind = &tcx.hir().expect_item(def_id).kind;
465-
let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item_kind else {
466-
span_bug!(
467-
self.value_span,
468-
"weird opaque type: {:#?}, {:#?}",
469-
ty.kind(),
470-
item_kind
471-
)
472-
};
473-
let in_definition_scope = match *origin {
474-
// Async `impl Trait`
475-
hir::OpaqueTyOrigin::AsyncFn(parent) => parent == parent_def_id,
476-
// Anonymous `impl Trait`
477-
hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
478-
// Named `type Foo = impl Bar;`
479-
hir::OpaqueTyOrigin::TyAlias => {
480-
may_define_opaque_type(tcx, parent_def_id, opaque_hir_id)
481-
}
482-
};
483-
if in_definition_scope {
487+
if let Some(origin) = self.infcx.opaque_type_origin(def_id) {
484488
let opaque_type_key =
485489
OpaqueTypeKey { def_id: def_id.to_def_id(), substs };
486-
return self.fold_opaque_ty(ty, opaque_type_key, *origin);
490+
return self.fold_opaque_ty(ty, opaque_type_key, origin);
487491
}
488492

489493
debug!(

0 commit comments

Comments
 (0)