Skip to content

Commit d72008e

Browse files
committed
Make DefiningAnchor::Bind only store the opaque types that may be constrained, instead of the current infcx root item.
This makes `Bind` almost always be empty, so we can start forwarding it to queries, allowing us to remove `Bubble` entirely
1 parent ef32456 commit d72008e

Some content is hidden

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

45 files changed

+312
-225
lines changed

compiler/rustc_borrowck/src/consumers.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,10 @@ pub fn get_body_with_borrowck_facts(
106106
options: ConsumerOptions,
107107
) -> BodyWithBorrowckFacts<'_> {
108108
let (input_body, promoted) = tcx.mir_promoted(def);
109-
let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def)).build();
109+
let infcx = tcx
110+
.infer_ctxt()
111+
.with_opaque_type_inference(DefiningAnchor::Bind(tcx.opaque_types_defined_by(def)))
112+
.build();
110113
let input_body: &Body<'_> = &input_body.borrow();
111114
let promoted: &IndexSlice<_, _> = &promoted.borrow();
112115
*super::do_mir_borrowck(&infcx, input_body, promoted, Some(options)).1.unwrap()

compiler/rustc_borrowck/src/lib.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,12 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
127127

128128
let hir_owner = tcx.local_def_id_to_hir_id(def).owner;
129129

130-
let infcx =
131-
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)).build();
130+
let infcx = tcx
131+
.infer_ctxt()
132+
.with_opaque_type_inference(DefiningAnchor::Bind(
133+
tcx.opaque_types_defined_by(hir_owner.def_id),
134+
))
135+
.build();
132136
let promoted: &IndexSlice<_, _> = &promoted.borrow();
133137
let opt_closure_req = do_mir_borrowck(&infcx, input_body, promoted, None).0;
134138
debug!("mir_borrowck done");

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,9 @@ fn check_opaque_type_well_formed<'tcx>(
317317
let infcx = tcx
318318
.infer_ctxt()
319319
.with_next_trait_solver(next_trait_solver)
320-
.with_opaque_type_inference(DefiningAnchor::Bind(parent_def_id))
320+
.with_opaque_type_inference(DefiningAnchor::Bind(
321+
tcx.opaque_types_defined_by(parent_def_id),
322+
))
321323
.build();
322324
let ocx = ObligationCtxt::new(&infcx);
323325
let identity_args = GenericArgs::identity_for_item(tcx, def_id);

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,9 @@ fn check_opaque_meets_bounds<'tcx>(
346346

347347
let infcx = tcx
348348
.infer_ctxt()
349-
.with_opaque_type_inference(DefiningAnchor::Bind(defining_use_anchor))
349+
.with_opaque_type_inference(DefiningAnchor::Bind(
350+
tcx.opaque_types_defined_by(defining_use_anchor),
351+
))
350352
.build();
351353
let ocx = ObligationCtxt::new(&infcx);
352354

@@ -1570,7 +1572,9 @@ pub(super) fn check_coroutine_obligations(
15701572
.ignoring_regions()
15711573
// Bind opaque types to type checking root, as they should have been checked by borrowck,
15721574
// but may show up in some cases, like when (root) obligations are stalled in the new solver.
1573-
.with_opaque_type_inference(DefiningAnchor::Bind(typeck.hir_owner.def_id))
1575+
.with_opaque_type_inference(DefiningAnchor::Bind(
1576+
tcx.opaque_types_defined_by(typeck.hir_owner.def_id),
1577+
))
15741578
.build();
15751579

15761580
let mut fulfillment_cx = <dyn TraitEngine<'_>>::new(&infcx);

compiler/rustc_hir_typeck/src/inherited.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ impl<'tcx> Inherited<'tcx> {
7979
let infcx = tcx
8080
.infer_ctxt()
8181
.ignoring_regions()
82-
.with_opaque_type_inference(DefiningAnchor::Bind(def_id))
82+
.with_opaque_type_inference(DefiningAnchor::Bind(tcx.opaque_types_defined_by(def_id)))
8383
.build();
8484
let typeck_results = RefCell::new(ty::TypeckResults::new(hir_owner));
8585

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ pub struct InferCtxt<'tcx> {
252252
///
253253
/// Its default value is `DefiningAnchor::Error`, this way it is easier to catch errors that
254254
/// might come up during inference or typeck.
255-
pub defining_use_anchor: DefiningAnchor,
255+
pub defining_use_anchor: DefiningAnchor<'tcx>,
256256

257257
/// Whether this inference context should care about region obligations in
258258
/// the root universe. Most notably, this is used during hir typeck as region
@@ -619,7 +619,7 @@ impl fmt::Display for FixupError {
619619
/// Used to configure inference contexts before their creation.
620620
pub struct InferCtxtBuilder<'tcx> {
621621
tcx: TyCtxt<'tcx>,
622-
defining_use_anchor: DefiningAnchor,
622+
defining_use_anchor: DefiningAnchor<'tcx>,
623623
considering_regions: bool,
624624
skip_leak_check: bool,
625625
/// Whether we are in coherence mode.
@@ -650,7 +650,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
650650
/// It is only meant to be called in two places, for typeck
651651
/// (via `Inherited::build`) and for the inference context used
652652
/// in mir borrowck.
653-
pub fn with_opaque_type_inference(mut self, defining_use_anchor: DefiningAnchor) -> Self {
653+
pub fn with_opaque_type_inference(mut self, defining_use_anchor: DefiningAnchor<'tcx>) -> Self {
654654
self.defining_use_anchor = defining_use_anchor;
655655
self
656656
}

compiler/rustc_infer/src/infer/opaque_types.rs

Lines changed: 3 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -373,28 +373,14 @@ impl<'tcx> InferCtxt<'tcx> {
373373
/// in its defining scope.
374374
#[instrument(skip(self), level = "trace", ret)]
375375
pub fn opaque_type_origin(&self, def_id: LocalDefId) -> Option<OpaqueTyOrigin> {
376-
let opaque_hir_id = self.tcx.local_def_id_to_hir_id(def_id);
377-
let parent_def_id = match self.defining_use_anchor {
376+
let defined_opaque_types = match self.defining_use_anchor {
378377
DefiningAnchor::Bubble | DefiningAnchor::Error => return None,
379378
DefiningAnchor::Bind(bind) => bind,
380379
};
381380

382381
let origin = self.tcx.opaque_type_origin(def_id);
383-
let in_definition_scope = match origin {
384-
// Async `impl Trait`
385-
hir::OpaqueTyOrigin::AsyncFn(parent) => parent == parent_def_id,
386-
// Anonymous `impl Trait`
387-
hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
388-
// Named `type Foo = impl Bar;`
389-
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => {
390-
if in_assoc_ty {
391-
self.tcx.opaque_types_defined_by(parent_def_id).contains(&def_id)
392-
} else {
393-
may_define_opaque_type(self.tcx, parent_def_id, opaque_hir_id)
394-
}
395-
}
396-
};
397-
in_definition_scope.then_some(origin)
382+
383+
defined_opaque_types.contains(&def_id).then_some(origin)
398384
}
399385
}
400386

@@ -652,43 +638,3 @@ impl<'tcx> InferCtxt<'tcx> {
652638
}
653639
}
654640
}
655-
656-
/// Returns `true` if `opaque_hir_id` is a sibling or a child of a sibling of `def_id`.
657-
///
658-
/// Example:
659-
/// ```ignore UNSOLVED (is this a bug?)
660-
/// # #![feature(type_alias_impl_trait)]
661-
/// pub mod foo {
662-
/// pub mod bar {
663-
/// pub trait Bar { /* ... */ }
664-
/// pub type Baz = impl Bar;
665-
///
666-
/// # impl Bar for () {}
667-
/// fn f1() -> Baz { /* ... */ }
668-
/// }
669-
/// fn f2() -> bar::Baz { /* ... */ }
670-
/// }
671-
/// ```
672-
///
673-
/// Here, `def_id` is the `LocalDefId` of the defining use of the opaque type (e.g., `f1` or `f2`),
674-
/// and `opaque_hir_id` is the `HirId` of the definition of the opaque type `Baz`.
675-
/// For the above example, this function returns `true` for `f1` and `false` for `f2`.
676-
fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_hir_id: hir::HirId) -> bool {
677-
let mut hir_id = tcx.local_def_id_to_hir_id(def_id);
678-
679-
// Named opaque types can be defined by any siblings or children of siblings.
680-
let scope = tcx.hir().get_defining_scope(opaque_hir_id);
681-
// We walk up the node tree until we hit the root or the scope of the opaque type.
682-
while hir_id != scope && hir_id != hir::CRATE_HIR_ID {
683-
hir_id = tcx.hir().get_parent_item(hir_id).into();
684-
}
685-
// Syntactically, we are allowed to define the concrete type if:
686-
let res = hir_id == scope;
687-
trace!(
688-
"may_define_opaque_type(def={:?}, opaque_node={:?}) = {}",
689-
tcx.hir_node(hir_id),
690-
tcx.hir_node(opaque_hir_id),
691-
res
692-
);
693-
res
694-
}

compiler/rustc_middle/src/mir/type_foldable.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! `TypeFoldable` implementations for MIR types
22
33
use rustc_ast::InlineAsmTemplatePiece;
4+
use rustc_hir::def_id::LocalDefId;
45

56
use super::*;
67

@@ -44,6 +45,15 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx [Span] {
4445
}
4546
}
4647

48+
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx [LocalDefId] {
49+
fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
50+
self,
51+
_folder: &mut F,
52+
) -> Result<Self, F::Error> {
53+
Ok(self)
54+
}
55+
}
56+
4757
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<PlaceElem<'tcx>> {
4858
fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
4959
self,

compiler/rustc_middle/src/traits/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,10 +1001,10 @@ pub enum CodegenObligationError {
10011001
/// opaques are replaced with inference vars eagerly in the old solver (e.g.
10021002
/// in projection, and in the signature during function type-checking).
10031003
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
1004-
pub enum DefiningAnchor {
1005-
/// Define opaques which are in-scope of the `LocalDefId`. Also, eagerly
1006-
/// replace opaque types in `replace_opaque_types_with_inference_vars`.
1007-
Bind(LocalDefId),
1004+
pub enum DefiningAnchor<'tcx> {
1005+
/// Define opaques which are in-scope of the current item being analyzed.
1006+
/// Also, eagerly replace these opaque types in `replace_opaque_types_with_inference_vars`.
1007+
Bind(&'tcx [LocalDefId]),
10081008
/// In contexts where we don't currently know what opaques are allowed to be
10091009
/// defined, such as (old solver) canonical queries, we will simply allow
10101010
/// opaques to be defined, but "bubble" them up in the canonical response or

compiler/rustc_middle/src/traits/solve.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ pub enum MaybeCause {
105105
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
106106
pub struct QueryInput<'tcx, T> {
107107
pub goal: Goal<'tcx, T>,
108-
pub anchor: DefiningAnchor,
108+
pub anchor: DefiningAnchor<'tcx>,
109109
pub predefined_opaques_in_body: PredefinedOpaques<'tcx>,
110110
}
111111

0 commit comments

Comments
 (0)