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.
This commit is contained in:
parent
72e74d7b9c
commit
956db072a8
2 changed files with 36 additions and 32 deletions
|
@ -10,7 +10,6 @@ pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog};
|
||||||
|
|
||||||
use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine};
|
use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine};
|
||||||
|
|
||||||
use hir::def_id::CRATE_DEF_ID;
|
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_data_structures::undo_log::Rollback;
|
use rustc_data_structures::undo_log::Rollback;
|
||||||
|
@ -291,7 +290,12 @@ pub struct InferCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
/// The `DefId` of the item in whose context we are performing inference or typeck.
|
/// The `DefId` of the item in whose context we are performing inference or typeck.
|
||||||
/// It is used to check whether an opaque type use is a defining use.
|
/// It is used to check whether an opaque type use is a defining use.
|
||||||
pub defining_use_anchor: LocalDefId,
|
///
|
||||||
|
/// If it is `None`, we can't resolve opaque types here and need to bubble up
|
||||||
|
/// the obligation. This frequently happens for
|
||||||
|
/// short lived InferCtxt within queries. The opaque type obligations are forwarded
|
||||||
|
/// to the outside until the end up in an `InferCtxt` for typeck or borrowck.
|
||||||
|
pub defining_use_anchor: Option<LocalDefId>,
|
||||||
|
|
||||||
/// During type-checking/inference of a body, `in_progress_typeck_results`
|
/// During type-checking/inference of a body, `in_progress_typeck_results`
|
||||||
/// contains a reference to the typeck results being built up, which are
|
/// contains a reference to the typeck results being built up, which are
|
||||||
|
@ -547,7 +551,7 @@ impl<'tcx> fmt::Display for FixupError<'tcx> {
|
||||||
pub struct InferCtxtBuilder<'tcx> {
|
pub struct InferCtxtBuilder<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
fresh_typeck_results: Option<RefCell<ty::TypeckResults<'tcx>>>,
|
fresh_typeck_results: Option<RefCell<ty::TypeckResults<'tcx>>>,
|
||||||
defining_use_anchor: LocalDefId,
|
defining_use_anchor: Option<LocalDefId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TyCtxtInferExt<'tcx> {
|
pub trait TyCtxtInferExt<'tcx> {
|
||||||
|
@ -556,11 +560,7 @@ pub trait TyCtxtInferExt<'tcx> {
|
||||||
|
|
||||||
impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
|
impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
|
||||||
fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
|
fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
|
||||||
InferCtxtBuilder {
|
InferCtxtBuilder { tcx: self, defining_use_anchor: None, fresh_typeck_results: None }
|
||||||
tcx: self,
|
|
||||||
defining_use_anchor: CRATE_DEF_ID,
|
|
||||||
fresh_typeck_results: None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,7 +580,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
||||||
/// (via `with_fresh_in_progress_typeck_results`) and for the inference context used
|
/// (via `with_fresh_in_progress_typeck_results`) and for the inference context used
|
||||||
/// in mir borrowck.
|
/// in mir borrowck.
|
||||||
pub fn with_opaque_type_inference(mut self, defining_use_anchor: LocalDefId) -> Self {
|
pub fn with_opaque_type_inference(mut self, defining_use_anchor: LocalDefId) -> Self {
|
||||||
self.defining_use_anchor = defining_use_anchor;
|
self.defining_use_anchor = Some(defining_use_anchor);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -328,6 +328,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn opaque_type_origin(&self, def_id: LocalDefId) -> Option<hir::OpaqueTyOrigin> {
|
||||||
|
let tcx = self.tcx;
|
||||||
|
let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
|
let parent_def_id = self.defining_use_anchor?;
|
||||||
|
let item_kind = &tcx.hir().expect_item(def_id).kind;
|
||||||
|
let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item_kind else {
|
||||||
|
span_bug!(
|
||||||
|
tcx.def_span(def_id),
|
||||||
|
"weird opaque type: {:#?}",
|
||||||
|
item_kind
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let in_definition_scope = match *origin {
|
||||||
|
// Async `impl Trait`
|
||||||
|
hir::OpaqueTyOrigin::AsyncFn(parent) => parent == parent_def_id,
|
||||||
|
// Anonymous `impl Trait`
|
||||||
|
hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
|
||||||
|
// Named `type Foo = impl Bar;`
|
||||||
|
hir::OpaqueTyOrigin::TyAlias => {
|
||||||
|
may_define_opaque_type(tcx, parent_def_id, opaque_hir_id)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
in_definition_scope.then_some(*origin)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Visitor that requires that (almost) all regions in the type visited outlive
|
// Visitor that requires that (almost) all regions in the type visited outlive
|
||||||
|
@ -459,31 +484,10 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||||
// }
|
// }
|
||||||
// ```
|
// ```
|
||||||
if let Some(def_id) = def_id.as_local() {
|
if let Some(def_id) = def_id.as_local() {
|
||||||
let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
if let Some(origin) = self.infcx.opaque_type_origin(def_id) {
|
||||||
let parent_def_id = self.infcx.defining_use_anchor;
|
|
||||||
let item_kind = &tcx.hir().expect_item(def_id).kind;
|
|
||||||
let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item_kind else {
|
|
||||||
span_bug!(
|
|
||||||
self.value_span,
|
|
||||||
"weird opaque type: {:#?}, {:#?}",
|
|
||||||
ty.kind(),
|
|
||||||
item_kind
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let in_definition_scope = match *origin {
|
|
||||||
// Async `impl Trait`
|
|
||||||
hir::OpaqueTyOrigin::AsyncFn(parent) => parent == parent_def_id,
|
|
||||||
// Anonymous `impl Trait`
|
|
||||||
hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
|
|
||||||
// Named `type Foo = impl Bar;`
|
|
||||||
hir::OpaqueTyOrigin::TyAlias => {
|
|
||||||
may_define_opaque_type(tcx, parent_def_id, opaque_hir_id)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if in_definition_scope {
|
|
||||||
let opaque_type_key =
|
let opaque_type_key =
|
||||||
OpaqueTypeKey { def_id: def_id.to_def_id(), substs };
|
OpaqueTypeKey { def_id: def_id.to_def_id(), substs };
|
||||||
return self.fold_opaque_ty(ty, opaque_type_key, *origin);
|
return self.fold_opaque_ty(ty, opaque_type_key, origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue