Skip to content

Commit 4ccbb7d

Browse files
committed
Auto merge of #121796 - oli-obk:eager_opaque_checks3, r=lcnr
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 (not done in this PR) The only behaviour change is in diagnostics. r? `@lcnr` `@compiler-errors`
2 parents 6554a56 + b0328c2 commit 4ccbb7d

Some content is hidden

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

48 files changed

+322
-251
lines changed

compiler/rustc_borrowck/src/consumers.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ 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.infer_ctxt().with_opaque_type_inference(DefiningAnchor::bind(tcx, def)).build();
110110
let input_body: &Body<'_> = &input_body.borrow();
111111
let promoted: &IndexSlice<_, _> = &promoted.borrow();
112112
*super::do_mir_borrowck(&infcx, input_body, promoted, Some(options)).1.unwrap()

compiler/rustc_borrowck/src/lib.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
126126
return tcx.arena.alloc(result);
127127
}
128128

129-
let hir_owner = tcx.local_def_id_to_hir_id(def).owner;
130-
131-
let infcx =
132-
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)).build();
129+
let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::bind(tcx, def)).build();
133130
let promoted: &IndexSlice<_, _> = &promoted.borrow();
134131
let opt_closure_req = do_mir_borrowck(&infcx, input_body, promoted, None).0;
135132
debug!("mir_borrowck done");

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -311,13 +311,13 @@ fn check_opaque_type_well_formed<'tcx>(
311311
parent_def_id = tcx.local_parent(parent_def_id);
312312
}
313313

314-
// FIXME(-Znext-solver): We probably should use `DefiningAnchor::Error`
314+
// FIXME(-Znext-solver): We probably should use `DefiningAnchor::Bind(&[])`
315315
// and prepopulate this `InferCtxt` with known opaque values, rather than
316316
// using the `Bind` anchor here. For now it's fine.
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(tcx, parent_def_id))
321321
.build();
322322
let ocx = ObligationCtxt::new(&infcx);
323323
let identity_args = GenericArgs::identity_for_item(tcx, def_id);

compiler/rustc_hir_analysis/src/check/check.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ fn check_opaque_meets_bounds<'tcx>(
347347

348348
let infcx = tcx
349349
.infer_ctxt()
350-
.with_opaque_type_inference(DefiningAnchor::Bind(defining_use_anchor))
350+
.with_opaque_type_inference(DefiningAnchor::bind(tcx, defining_use_anchor))
351351
.build();
352352
let ocx = ObligationCtxt::new(&infcx);
353353

@@ -1558,7 +1558,7 @@ pub(super) fn check_coroutine_obligations(
15581558
.ignoring_regions()
15591559
// Bind opaque types to type checking root, as they should have been checked by borrowck,
15601560
// but may show up in some cases, like when (root) obligations are stalled in the new solver.
1561-
.with_opaque_type_inference(DefiningAnchor::Bind(typeck.hir_owner.def_id))
1561+
.with_opaque_type_inference(DefiningAnchor::bind(tcx, typeck.hir_owner.def_id))
15621562
.build();
15631563

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

compiler/rustc_hir_typeck/src/inherited.rs

+1-1
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, def_id))
8383
.build();
8484
let typeck_results = RefCell::new(ty::TypeckResults::new(hir_owner));
8585

compiler/rustc_infer/src/infer/mod.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,10 @@ pub struct InferCtxt<'tcx> {
242242
/// short lived InferCtxt within queries. The opaque type obligations are forwarded
243243
/// to the outside until the end up in an `InferCtxt` for typeck or borrowck.
244244
///
245-
/// Its default value is `DefiningAnchor::Error`, this way it is easier to catch errors that
245+
/// Its default value is `DefiningAnchor::Bind(&[])`, which means no opaque types may be defined.
246+
/// This way it is easier to catch errors that
246247
/// might come up during inference or typeck.
247-
pub defining_use_anchor: DefiningAnchor,
248+
pub defining_use_anchor: DefiningAnchor<'tcx>,
248249

249250
/// Whether this inference context should care about region obligations in
250251
/// the root universe. Most notably, this is used during hir typeck as region
@@ -605,7 +606,7 @@ impl fmt::Display for FixupError {
605606
/// Used to configure inference contexts before their creation.
606607
pub struct InferCtxtBuilder<'tcx> {
607608
tcx: TyCtxt<'tcx>,
608-
defining_use_anchor: DefiningAnchor,
609+
defining_use_anchor: DefiningAnchor<'tcx>,
609610
considering_regions: bool,
610611
skip_leak_check: bool,
611612
/// Whether we are in coherence mode.
@@ -620,7 +621,7 @@ impl<'tcx> TyCtxt<'tcx> {
620621
fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
621622
InferCtxtBuilder {
622623
tcx: self,
623-
defining_use_anchor: DefiningAnchor::Error,
624+
defining_use_anchor: DefiningAnchor::Bind(ty::List::empty()),
624625
considering_regions: true,
625626
skip_leak_check: false,
626627
intercrate: false,
@@ -636,7 +637,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
636637
/// It is only meant to be called in two places, for typeck
637638
/// (via `Inherited::build`) and for the inference context used
638639
/// in mir borrowck.
639-
pub fn with_opaque_type_inference(mut self, defining_use_anchor: DefiningAnchor) -> Self {
640+
pub fn with_opaque_type_inference(mut self, defining_use_anchor: DefiningAnchor<'tcx>) -> Self {
640641
self.defining_use_anchor = defining_use_anchor;
641642
self
642643
}
@@ -1208,13 +1209,11 @@ impl<'tcx> InferCtxt<'tcx> {
12081209

12091210
#[instrument(level = "debug", skip(self), ret)]
12101211
pub fn take_opaque_types(&self) -> opaque_types::OpaqueTypeMap<'tcx> {
1211-
debug_assert_ne!(self.defining_use_anchor, DefiningAnchor::Error);
12121212
std::mem::take(&mut self.inner.borrow_mut().opaque_type_storage.opaque_types)
12131213
}
12141214

12151215
#[instrument(level = "debug", skip(self), ret)]
12161216
pub fn clone_opaque_types(&self) -> opaque_types::OpaqueTypeMap<'tcx> {
1217-
debug_assert_ne!(self.defining_use_anchor, DefiningAnchor::Error);
12181217
self.inner.borrow().opaque_type_storage.opaque_types.clone()
12191218
}
12201219

compiler/rustc_infer/src/infer/opaque_types/mod.rs

+4-61
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,6 @@ impl<'tcx> InferCtxt<'tcx> {
150150
}
151151
}
152152
DefiningAnchor::Bubble => {}
153-
DefiningAnchor::Error => {
154-
return None;
155-
}
156153
}
157154
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() {
158155
// We could accept this, but there are various ways to handle this situation, and we don't
@@ -378,28 +375,14 @@ impl<'tcx> InferCtxt<'tcx> {
378375
/// in its defining scope.
379376
#[instrument(skip(self), level = "trace", ret)]
380377
pub fn opaque_type_origin(&self, def_id: LocalDefId) -> Option<OpaqueTyOrigin> {
381-
let opaque_hir_id = self.tcx.local_def_id_to_hir_id(def_id);
382-
let parent_def_id = match self.defining_use_anchor {
383-
DefiningAnchor::Bubble | DefiningAnchor::Error => return None,
378+
let defined_opaque_types = match self.defining_use_anchor {
379+
DefiningAnchor::Bubble => return None,
384380
DefiningAnchor::Bind(bind) => bind,
385381
};
386382

387383
let origin = self.tcx.opaque_type_origin(def_id);
388-
let in_definition_scope = match origin {
389-
// Async `impl Trait`
390-
hir::OpaqueTyOrigin::AsyncFn(parent) => parent == parent_def_id,
391-
// Anonymous `impl Trait`
392-
hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
393-
// Named `type Foo = impl Bar;`
394-
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => {
395-
if in_assoc_ty {
396-
self.tcx.opaque_types_defined_by(parent_def_id).contains(&def_id)
397-
} else {
398-
may_define_opaque_type(self.tcx, parent_def_id, opaque_hir_id)
399-
}
400-
}
401-
};
402-
in_definition_scope.then_some(origin)
384+
385+
defined_opaque_types.contains(&def_id).then_some(origin)
403386
}
404387
}
405388

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

compiler/rustc_middle/src/mir/type_foldable.rs

+10
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 ty::List<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

+15-9
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ pub mod util;
1212
use crate::infer::canonical::Canonical;
1313
use crate::mir::ConstraintCategory;
1414
use crate::ty::abstract_const::NotConstEvaluatable;
15-
use crate::ty::GenericArgsRef;
1615
use crate::ty::{self, AdtKind, Ty};
16+
use crate::ty::{GenericArgsRef, TyCtxt};
1717

1818
use rustc_data_structures::sync::Lrc;
1919
use rustc_errors::{Applicability, Diag, EmissionGuarantee};
@@ -1001,10 +1001,14 @@ 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+
///
1008+
/// If the list is empty, do not allow any opaques to be defined. This is used to catch type mismatch
1009+
/// errors when handling opaque types, and also should be used when we would
1010+
/// otherwise reveal opaques (such as [`Reveal::All`] reveal mode).
1011+
Bind(&'tcx ty::List<LocalDefId>),
10081012
/// In contexts where we don't currently know what opaques are allowed to be
10091013
/// defined, such as (old solver) canonical queries, we will simply allow
10101014
/// opaques to be defined, but "bubble" them up in the canonical response or
@@ -1013,8 +1017,10 @@ pub enum DefiningAnchor {
10131017
/// We do not eagerly replace opaque types in `replace_opaque_types_with_inference_vars`,
10141018
/// which may affect what predicates pass and fail in the old trait solver.
10151019
Bubble,
1016-
/// Do not allow any opaques to be defined. This is used to catch type mismatch
1017-
/// errors when handling opaque types, and also should be used when we would
1018-
/// otherwise reveal opaques (such as [`Reveal::All`] reveal mode).
1019-
Error,
1020+
}
1021+
1022+
impl<'tcx> DefiningAnchor<'tcx> {
1023+
pub fn bind(tcx: TyCtxt<'tcx>, item: LocalDefId) -> Self {
1024+
Self::Bind(tcx.opaque_types_defined_by(item))
1025+
}
10201026
}

compiler/rustc_middle/src/traits/solve.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl MaybeCause {
114114
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
115115
pub struct QueryInput<'tcx, T> {
116116
pub goal: Goal<'tcx, T>,
117-
pub anchor: DefiningAnchor,
117+
pub anchor: DefiningAnchor<'tcx>,
118118
pub predefined_opaques_in_body: PredefinedOpaques<'tcx>,
119119
}
120120

compiler/rustc_middle/src/ty/codec.rs

+10
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::traits;
1717
use crate::ty::GenericArgsRef;
1818
use crate::ty::{self, AdtDef, Ty};
1919
use rustc_data_structures::fx::FxHashMap;
20+
use rustc_hir::def_id::LocalDefId;
2021
use rustc_middle::ty::TyCtxt;
2122
use rustc_serialize::{Decodable, Encodable};
2223
use rustc_span::Span;
@@ -431,6 +432,15 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<Fi
431432
}
432433
}
433434

435+
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<LocalDefId> {
436+
fn decode(decoder: &mut D) -> &'tcx Self {
437+
let len = decoder.read_usize();
438+
decoder.interner().mk_local_def_ids_from_iter(
439+
(0..len).map::<LocalDefId, _>(|_| Decodable::decode(decoder)),
440+
)
441+
}
442+
}
443+
434444
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
435445
for ty::List<(VariantIdx, FieldIdx)>
436446
{

compiler/rustc_middle/src/ty/context.rs

+8
Original file line numberDiff line numberDiff line change
@@ -2014,6 +2014,14 @@ impl<'tcx> TyCtxt<'tcx> {
20142014
self.intern_local_def_ids(clauses)
20152015
}
20162016

2017+
pub fn mk_local_def_ids_from_iter<I, T>(self, iter: I) -> T::Output
2018+
where
2019+
I: Iterator<Item = T>,
2020+
T: CollectAndApply<LocalDefId, &'tcx List<LocalDefId>>,
2021+
{
2022+
T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
2023+
}
2024+
20172025
pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
20182026
where
20192027
I: Iterator<Item = T>,

compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_middle::traits::solve::{
1616
CanonicalInput, CanonicalResponse, Certainty, IsNormalizesToHack, PredefinedOpaques,
1717
PredefinedOpaquesData, QueryResult,
1818
};
19-
use rustc_middle::traits::{specialization_graph, DefiningAnchor};
19+
use rustc_middle::traits::specialization_graph;
2020
use rustc_middle::ty::{
2121
self, InferCtxtLike, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
2222
TypeVisitable, TypeVisitableExt, TypeVisitor,
@@ -258,10 +258,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
258258
// instead of taking them. This would cause an ICE here, since we have
259259
// assertions against dropping an `InferCtxt` without taking opaques.
260260
// FIXME: Once we remove support for the old impl we can remove this.
261-
if input.anchor != DefiningAnchor::Error {
262-
// This seems ok, but fragile.
263-
let _ = infcx.take_opaque_types();
264-
}
261+
let _ = infcx.take_opaque_types();
265262

266263
result
267264
}

compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

+6-13
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use rustc_hir::{GenericParam, Item, Node};
3232
use rustc_infer::infer::error_reporting::TypeErrCtxt;
3333
use rustc_infer::infer::{InferOk, TypeTrace};
3434
use rustc_middle::traits::select::OverflowError;
35-
use rustc_middle::traits::{DefiningAnchor, SignatureMismatchData};
35+
use rustc_middle::traits::SignatureMismatchData;
3636
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
3737
use rustc_middle::ty::error::{ExpectedFound, TypeError};
3838
use rustc_middle::ty::fold::{BottomUpFolder, TypeFolder, TypeSuperFoldable};
@@ -3390,19 +3390,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
33903390
obligation.cause.span,
33913391
format!("cannot check whether the hidden type of {name} satisfies auto traits"),
33923392
);
3393+
3394+
err.note(
3395+
"fetching the hidden types of an opaque inside of the defining scope is not supported. \
3396+
You can try moving the opaque type and the item that actually registers a hidden type into a new submodule",
3397+
);
33933398
err.span_note(self.tcx.def_span(def_id), "opaque type is declared here");
3394-
match self.defining_use_anchor {
3395-
DefiningAnchor::Bubble | DefiningAnchor::Error => {}
3396-
DefiningAnchor::Bind(bind) => {
3397-
err.span_note(
3398-
self.tcx.def_ident_span(bind).unwrap_or_else(|| self.tcx.def_span(bind)),
3399-
"this item depends on auto traits of the hidden type, \
3400-
but may also be registering the hidden type. \
3401-
This is not supported right now. \
3402-
You can try moving the opaque type and the item that actually registers a hidden type into a new submodule".to_string(),
3403-
);
3404-
}
3405-
};
34063399

34073400
self.note_obligation_cause(&mut err, &obligation);
34083401
self.point_at_returns_when_relevant(&mut err, &obligation);

0 commit comments

Comments
 (0)