Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't fall back to crate-level opaque type definitions. #92045

Merged
merged 1 commit into from
Jan 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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