Skip to content

Commit

Permalink
Don't fall back to crate-level opaque type definitions.
Browse files Browse the repository at this point in the history
That would just hide bugs, as it works accidentally if the opaque type
is defined at the crate level.
  • Loading branch information
oli-obk committed Jan 12, 2022
1 parent 72e74d7 commit 956db07
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 32 deletions.
18 changes: 9 additions & 9 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog};

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::sync::Lrc;
use rustc_data_structures::undo_log::Rollback;
Expand Down Expand Up @@ -291,7 +290,12 @@ pub struct InferCtxt<'a, 'tcx> {

/// 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.
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`
/// contains a reference to the typeck results being built up, which are
Expand Down Expand Up @@ -547,7 +551,7 @@ impl<'tcx> fmt::Display for FixupError<'tcx> {
pub struct InferCtxtBuilder<'tcx> {
tcx: TyCtxt<'tcx>,
fresh_typeck_results: Option<RefCell<ty::TypeckResults<'tcx>>>,
defining_use_anchor: LocalDefId,
defining_use_anchor: Option<LocalDefId>,
}

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

impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
InferCtxtBuilder {
tcx: self,
defining_use_anchor: CRATE_DEF_ID,
fresh_typeck_results: None,
}
InferCtxtBuilder { tcx: self, defining_use_anchor: None, fresh_typeck_results: None }
}
}

Expand All @@ -580,7 +580,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
/// (via `with_fresh_in_progress_typeck_results`) and for the inference context used
/// in mir borrowck.
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
}

Expand Down
50 changes: 27 additions & 23 deletions compiler/rustc_infer/src/infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -459,31 +484,10 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
// }
// ```
if let Some(def_id) = def_id.as_local() {
let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(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 {
if let Some(origin) = self.infcx.opaque_type_origin(def_id) {
let opaque_type_key =
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!(
Expand Down

0 comments on commit 956db07

Please sign in to comment.