Skip to content

Commit e34498b

Browse files
committed
Auto merge of rust-lang#122077 - oli-obk:eager_opaque_checks4, r=<try>
Pass list of defineable opaque types into canonical queries based on rust-lang#121796 This eliminates `DefiningAnchor::Bubble` for good and brings the old solver closer to the new one wrt cycles and nested obligations. At that point the difference between `DefiningAnchor::Bind([])` and `DefiningAnchor::Error` was academic. We only used the difference for some sanity checks, which actually had to be worked around in places, so I just removed `DefiningAnchor` entirely and just stored the list of opaques that may be defined. fixes rust-lang#108498 * [ ] run crater
2 parents 65cd843 + cb7c75b commit e34498b

File tree

72 files changed

+469
-454
lines changed

Some content is hidden

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

72 files changed

+469
-454
lines changed

compiler/rustc_borrowck/src/consumers.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use rustc_hir::def_id::LocalDefId;
44
use rustc_index::{IndexSlice, IndexVec};
55
use rustc_infer::infer::TyCtxtInferExt;
66
use rustc_middle::mir::{Body, Promoted};
7-
use rustc_middle::traits::DefiningAnchor;
87
use rustc_middle::ty::TyCtxt;
98
use std::rc::Rc;
109

@@ -106,7 +105,7 @@ pub fn get_body_with_borrowck_facts(
106105
options: ConsumerOptions,
107106
) -> BodyWithBorrowckFacts<'_> {
108107
let (input_body, promoted) = tcx.mir_promoted(def);
109-
let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def)).build();
108+
let infcx = tcx.infer_ctxt().with_opaque_type_inference(def).build();
110109
let input_body: &Body<'_> = &input_body.borrow();
111110
let promoted: &IndexSlice<_, _> = &promoted.borrow();
112111
*super::do_mir_borrowck(&infcx, input_body, promoted, Some(options)).1.unwrap()

compiler/rustc_borrowck/src/lib.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ use rustc_infer::infer::{
3232
use rustc_middle::mir::tcx::PlaceTy;
3333
use rustc_middle::mir::*;
3434
use rustc_middle::query::Providers;
35-
use rustc_middle::traits::DefiningAnchor;
3635
use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt};
3736
use rustc_session::lint::builtin::UNUSED_MUT;
3837
use rustc_span::{Span, Symbol};
@@ -126,10 +125,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
126125
return tcx.arena.alloc(result);
127126
}
128127

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();
128+
let infcx = tcx.infer_ctxt().with_opaque_type_inference(def).build();
133129
let promoted: &IndexSlice<_, _> = &promoted.borrow();
134130
let opt_closure_req = do_mir_borrowck(&infcx, input_body, promoted, None).0;
135131
debug!("mir_borrowck done");

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use rustc_infer::infer::InferCtxt;
77
use rustc_infer::infer::TyCtxtInferExt as _;
88
use rustc_infer::traits::{Obligation, ObligationCause};
99
use rustc_macros::extension;
10-
use rustc_middle::traits::DefiningAnchor;
1110
use rustc_middle::ty::visit::TypeVisitableExt;
1211
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
1312
use rustc_middle::ty::{GenericArgKind, GenericArgs};
@@ -146,6 +145,17 @@ impl<'tcx> RegionInferenceContext<'tcx> {
146145
opaque_type_key,
147146
universal_concrete_type,
148147
);
148+
149+
// Sometimes, when the hidden type is an inference variable, it can happen that
150+
// the hidden type becomes the opaque type itself. In this case, this was an opaque
151+
// usage of the opaque type and we can ignore it. This check is mirrored in typeck's
152+
// writeback.
153+
if let ty::Alias(ty::Opaque, alias_ty) = universal_concrete_type.ty.kind()
154+
&& alias_ty.def_id == opaque_type_key.def_id.to_def_id()
155+
&& alias_ty.args == opaque_type_key.args
156+
{
157+
continue;
158+
}
149159
// Sometimes two opaque types are the same only after we remap the generic parameters
150160
// back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)`
151161
// and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we only know that
@@ -311,13 +321,13 @@ fn check_opaque_type_well_formed<'tcx>(
311321
parent_def_id = tcx.local_parent(parent_def_id);
312322
}
313323

314-
// FIXME(-Znext-solver): We probably should use `DefiningAnchor::Error`
324+
// FIXME(-Znext-solver): We probably should use `&[]` instead of
315325
// and prepopulate this `InferCtxt` with known opaque values, rather than
316-
// using the `Bind` anchor here. For now it's fine.
326+
// allowing opaque types to be defined and checking them after the fact.
317327
let infcx = tcx
318328
.infer_ctxt()
319329
.with_next_trait_solver(next_trait_solver)
320-
.with_opaque_type_inference(DefiningAnchor::Bind(parent_def_id))
330+
.with_opaque_type_inference(parent_def_id)
321331
.build();
322332
let ocx = ObligationCtxt::new(&infcx);
323333
let identity_args = GenericArgs::identity_for_item(tcx, def_id);

compiler/rustc_hir_analysis/src/check/check.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
1313
use rustc_infer::traits::{Obligation, TraitEngineExt as _};
1414
use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
1515
use rustc_middle::middle::stability::EvalResult;
16-
use rustc_middle::traits::{DefiningAnchor, ObligationCauseCode};
16+
use rustc_middle::traits::ObligationCauseCode;
1717
use rustc_middle::ty::fold::BottomUpFolder;
1818
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
1919
use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt};
@@ -345,10 +345,7 @@ fn check_opaque_meets_bounds<'tcx>(
345345
};
346346
let param_env = tcx.param_env(defining_use_anchor);
347347

348-
let infcx = tcx
349-
.infer_ctxt()
350-
.with_opaque_type_inference(DefiningAnchor::Bind(defining_use_anchor))
351-
.build();
348+
let infcx = tcx.infer_ctxt().with_opaque_type_inference(defining_use_anchor).build();
352349
let ocx = ObligationCtxt::new(&infcx);
353350

354351
let args = match *origin {
@@ -1558,7 +1555,7 @@ pub(super) fn check_coroutine_obligations(
15581555
.ignoring_regions()
15591556
// Bind opaque types to type checking root, as they should have been checked by borrowck,
15601557
// 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))
1558+
.with_opaque_type_inference(typeck.hir_owner.def_id)
15621559
.build();
15631560

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

compiler/rustc_hir_typeck/src/inherited.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use rustc_hir as hir;
55
use rustc_hir::def_id::LocalDefId;
66
use rustc_hir::HirIdMap;
77
use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
8-
use rustc_middle::traits::DefiningAnchor;
98
use rustc_middle::ty::visit::TypeVisitableExt;
109
use rustc_middle::ty::{self, Ty, TyCtxt};
1110
use rustc_span::def_id::LocalDefIdMap;
@@ -76,11 +75,7 @@ impl<'tcx> Inherited<'tcx> {
7675
pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
7776
let hir_owner = tcx.local_def_id_to_hir_id(def_id).owner;
7877

79-
let infcx = tcx
80-
.infer_ctxt()
81-
.ignoring_regions()
82-
.with_opaque_type_inference(DefiningAnchor::Bind(def_id))
83-
.build();
78+
let infcx = tcx.infer_ctxt().ignoring_regions().with_opaque_type_inference(def_id).build();
8479
let typeck_results = RefCell::new(ty::TypeckResults::new(hir_owner));
8580

8681
Inherited {

compiler/rustc_infer/src/infer/at.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ impl<'tcx> InferCtxt<'tcx> {
7575
pub fn fork_with_intercrate(&self, intercrate: bool) -> Self {
7676
Self {
7777
tcx: self.tcx,
78-
defining_use_anchor: self.defining_use_anchor,
78+
defining_opaque_types: self.defining_opaque_types,
7979
considering_regions: self.considering_regions,
8080
skip_leak_check: self.skip_leak_check,
8181
inner: self.inner.clone(),

compiler/rustc_infer/src/infer/canonical/canonicalizer.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ impl<'tcx> InferCtxt<'tcx> {
4545
let param_env = self.tcx.canonical_param_env_cache.get_or_insert(
4646
self.tcx,
4747
param_env,
48+
self.defining_opaque_types,
4849
query_state,
4950
|tcx, param_env, query_state| {
5051
// FIXME(#118965): We don't canonicalize the static lifetimes that appear in the
@@ -540,6 +541,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
540541
max_universe: ty::UniverseIndex::ROOT,
541542
variables: List::empty(),
542543
value: (),
544+
defining_opaque_types: infcx.map(|i| i.defining_opaque_types).unwrap_or_default(),
543545
};
544546
Canonicalizer::canonicalize_with_base(
545547
base,
@@ -609,7 +611,12 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
609611
.max()
610612
.unwrap_or(ty::UniverseIndex::ROOT);
611613

612-
Canonical { max_universe, variables: canonical_variables, value: (base.value, out_value) }
614+
Canonical {
615+
max_universe,
616+
variables: canonical_variables,
617+
value: (base.value, out_value),
618+
defining_opaque_types: base.defining_opaque_types,
619+
}
613620
}
614621

615622
/// Creates a canonical variable replacing `kind` from the input,

compiler/rustc_infer/src/infer/mod.rs

+23-22
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKin
3434
use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey};
3535
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
3636
use rustc_middle::mir::ConstraintCategory;
37-
use rustc_middle::traits::{select, DefiningAnchor};
37+
use rustc_middle::traits::select;
3838
use rustc_middle::ty::error::{ExpectedFound, TypeError};
3939
use rustc_middle::ty::fold::BoundVarReplacerDelegate;
4040
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
@@ -234,17 +234,8 @@ impl<'tcx> InferCtxtInner<'tcx> {
234234
pub struct InferCtxt<'tcx> {
235235
pub tcx: TyCtxt<'tcx>,
236236

237-
/// The `DefId` of the item in whose context we are performing inference or typeck.
238-
/// It is used to check whether an opaque type use is a defining use.
239-
///
240-
/// If it is `DefiningAnchor::Bubble`, we can't resolve opaque types here and need to bubble up
241-
/// the obligation. This frequently happens for
242-
/// short lived InferCtxt within queries. The opaque type obligations are forwarded
243-
/// to the outside until the end up in an `InferCtxt` for typeck or borrowck.
244-
///
245-
/// Its default value is `DefiningAnchor::Error`, this way it is easier to catch errors that
246-
/// might come up during inference or typeck.
247-
pub defining_use_anchor: DefiningAnchor,
237+
/// The `DefIds` of the opaque types that may have their hidden types constrained.
238+
pub defining_opaque_types: &'tcx ty::List<LocalDefId>,
248239

249240
/// Whether this inference context should care about region obligations in
250241
/// the root universe. Most notably, this is used during hir typeck as region
@@ -391,6 +382,10 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
391382
fn probe_ct_var(&self, vid: ConstVid) -> Option<ty::Const<'tcx>> {
392383
self.probe_const_var(vid).ok()
393384
}
385+
386+
fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> {
387+
self.defining_opaque_types
388+
}
394389
}
395390

396391
/// See the `error_reporting` module for more details.
@@ -605,7 +600,7 @@ impl fmt::Display for FixupError {
605600
/// Used to configure inference contexts before their creation.
606601
pub struct InferCtxtBuilder<'tcx> {
607602
tcx: TyCtxt<'tcx>,
608-
defining_use_anchor: DefiningAnchor,
603+
defining_opaque_types: &'tcx ty::List<LocalDefId>,
609604
considering_regions: bool,
610605
skip_leak_check: bool,
611606
/// Whether we are in coherence mode.
@@ -620,7 +615,7 @@ impl<'tcx> TyCtxt<'tcx> {
620615
fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
621616
InferCtxtBuilder {
622617
tcx: self,
623-
defining_use_anchor: DefiningAnchor::Error,
618+
defining_opaque_types: ty::List::empty(),
624619
considering_regions: true,
625620
skip_leak_check: false,
626621
intercrate: false,
@@ -636,8 +631,16 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
636631
/// It is only meant to be called in two places, for typeck
637632
/// (via `Inherited::build`) and for the inference context used
638633
/// in mir borrowck.
639-
pub fn with_opaque_type_inference(mut self, defining_use_anchor: DefiningAnchor) -> Self {
640-
self.defining_use_anchor = defining_use_anchor;
634+
pub fn with_opaque_type_inference(mut self, defining_anchor: LocalDefId) -> Self {
635+
self.defining_opaque_types = self.tcx.opaque_types_defined_by(defining_anchor);
636+
self
637+
}
638+
639+
pub fn with_defining_opaque_types(
640+
mut self,
641+
defining_opaque_types: &'tcx ty::List<LocalDefId>,
642+
) -> Self {
643+
self.defining_opaque_types = defining_opaque_types;
641644
self
642645
}
643646

@@ -669,30 +672,30 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
669672
/// the bound values in `C` to their instantiated values in `V`
670673
/// (in other words, `S(C) = V`).
671674
pub fn build_with_canonical<T>(
672-
&mut self,
675+
self,
673676
span: Span,
674677
canonical: &Canonical<'tcx, T>,
675678
) -> (InferCtxt<'tcx>, T, CanonicalVarValues<'tcx>)
676679
where
677680
T: TypeFoldable<TyCtxt<'tcx>>,
678681
{
679-
let infcx = self.build();
682+
let infcx = self.with_defining_opaque_types(canonical.defining_opaque_types).build();
680683
let (value, args) = infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical);
681684
(infcx, value, args)
682685
}
683686

684687
pub fn build(&mut self) -> InferCtxt<'tcx> {
685688
let InferCtxtBuilder {
686689
tcx,
687-
defining_use_anchor,
690+
defining_opaque_types,
688691
considering_regions,
689692
skip_leak_check,
690693
intercrate,
691694
next_trait_solver,
692695
} = *self;
693696
InferCtxt {
694697
tcx,
695-
defining_use_anchor,
698+
defining_opaque_types,
696699
considering_regions,
697700
skip_leak_check,
698701
inner: RefCell::new(InferCtxtInner::new()),
@@ -1208,13 +1211,11 @@ impl<'tcx> InferCtxt<'tcx> {
12081211

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

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

0 commit comments

Comments
 (0)