Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 1163aa7

Browse files
committed
Remove opaque type obligation and just register opaque types as they are encountered.
This also registers obligations for the hidden type immediately.
1 parent 86e1860 commit 1163aa7

File tree

60 files changed

+290
-311
lines changed

Some content is hidden

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

60 files changed

+290
-311
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2646,7 +2646,7 @@ impl NormalizeLocation for Location {
26462646
pub(super) struct InstantiateOpaqueType<'tcx> {
26472647
pub base_universe: Option<ty::UniverseIndex>,
26482648
pub region_constraints: Option<RegionConstraintData<'tcx>>,
2649-
pub obligation: PredicateObligation<'tcx>,
2649+
pub obligations: Vec<PredicateObligation<'tcx>>,
26502650
}
26512651

26522652
impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> {
@@ -2660,7 +2660,7 @@ impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> {
26602660

26612661
fn fully_perform(mut self, infcx: &InferCtxt<'_, 'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
26622662
let (mut output, region_constraints) = scrape_region_constraints(infcx, || {
2663-
Ok(InferOk { value: (), obligations: vec![self.obligation.clone()] })
2663+
Ok(InferOk { value: (), obligations: self.obligations.clone() })
26642664
})?;
26652665
self.region_constraints = Some(region_constraints);
26662666
output.error_info = Some(self);

compiler/rustc_borrowck/src/type_check/relate_tys.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRe
22
use rustc_infer::infer::NllRegionVariableOrigin;
33
use rustc_infer::traits::ObligationCause;
44
use rustc_middle::mir::ConstraintCategory;
5+
use rustc_middle::ty::error::TypeError;
56
use rustc_middle::ty::relate::TypeRelation;
67
use rustc_middle::ty::{self, Const, Ty};
78
use rustc_span::Span;
@@ -136,7 +137,12 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
136137
true
137138
}
138139

139-
fn register_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool) {
140+
fn register_opaque_type(
141+
&mut self,
142+
a: Ty<'tcx>,
143+
b: Ty<'tcx>,
144+
a_is_expected: bool,
145+
) -> Result<(), TypeError<'tcx>> {
140146
let param_env = self.param_env();
141147
let span = self.span();
142148
let def_id = self.type_checker.body.source.def_id().expect_local();
@@ -147,18 +153,17 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
147153
self.locations,
148154
self.category,
149155
InstantiateOpaqueType {
150-
obligation: self.type_checker.infcx.opaque_ty_obligation(
151-
a,
152-
b,
153-
a_is_expected,
154-
param_env,
155-
cause,
156-
),
156+
obligations: self
157+
.type_checker
158+
.infcx
159+
.handle_opaque_type(a, b, a_is_expected, &cause, param_env)?
160+
.obligations,
157161
// These fields are filled in during exectuion of the operation
158162
base_universe: None,
159163
region_constraints: None,
160164
},
161165
)
162166
.unwrap();
167+
Ok(())
163168
}
164169
}

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

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc_data_structures::captures::Captures;
2222
use rustc_index::vec::Idx;
2323
use rustc_index::vec::IndexVec;
2424
use rustc_middle::arena::ArenaAllocatable;
25+
use rustc_middle::ty::error::TypeError;
2526
use rustc_middle::ty::fold::TypeFoldable;
2627
use rustc_middle::ty::relate::TypeRelation;
2728
use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
@@ -499,7 +500,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
499500
for &(a, b) in &query_response.value.opaque_types {
500501
let a = substitute_value(self.tcx, &result_subst, a);
501502
let b = substitute_value(self.tcx, &result_subst, b);
502-
obligations.extend(self.handle_opaque_type(a, b, cause, param_env)?.obligations);
503+
obligations.extend(self.handle_opaque_type(a, b, true, cause, param_env)?.obligations);
503504
}
504505

505506
Ok(InferOk { value: result_subst, obligations })
@@ -718,13 +719,17 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
718719
true
719720
}
720721

721-
fn register_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool) {
722-
self.obligations.push(self.infcx.opaque_ty_obligation(
723-
a,
724-
b,
725-
a_is_expected,
726-
self.param_env,
727-
self.cause.clone(),
728-
));
722+
fn register_opaque_type(
723+
&mut self,
724+
a: Ty<'tcx>,
725+
b: Ty<'tcx>,
726+
a_is_expected: bool,
727+
) -> Result<(), TypeError<'tcx>> {
728+
self.obligations.extend(
729+
self.infcx
730+
.handle_opaque_type(a, b, a_is_expected, &self.cause, self.param_env)?
731+
.obligations,
732+
);
733+
Ok(())
729734
}
730735
}

compiler/rustc_infer/src/infer/equate.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,17 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
9898
(&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..))
9999
if self.fields.define_opaque_types && did.is_local() =>
100100
{
101-
self.fields.obligations.push(infcx.opaque_ty_obligation(
102-
a,
103-
b,
104-
self.a_is_expected(),
105-
self.param_env(),
106-
self.fields.trace.cause.clone(),
107-
));
101+
self.fields.obligations.extend(
102+
infcx
103+
.handle_opaque_type(
104+
a,
105+
b,
106+
self.a_is_expected(),
107+
&self.fields.trace.cause,
108+
self.param_env(),
109+
)?
110+
.obligations,
111+
);
108112
}
109113

110114
_ => {

compiler/rustc_infer/src/infer/lattice.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,11 @@ where
111111
(&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..))
112112
if this.define_opaque_types() && did.is_local() =>
113113
{
114-
this.add_obligations(vec![infcx.opaque_ty_obligation(
115-
a,
116-
b,
117-
this.a_is_expected(),
118-
this.param_env(),
119-
this.cause().clone(),
120-
)]);
114+
this.add_obligations(
115+
infcx
116+
.handle_opaque_type(a, b, this.a_is_expected(), this.cause(), this.param_env())?
117+
.obligations,
118+
);
121119
Ok(a)
122120
}
123121

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,12 @@ pub trait TypeRelatingDelegate<'tcx> {
9191
);
9292

9393
fn const_equate(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>);
94-
fn register_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool);
94+
fn register_opaque_type(
95+
&mut self,
96+
a: Ty<'tcx>,
97+
b: Ty<'tcx>,
98+
a_is_expected: bool,
99+
) -> Result<(), TypeError<'tcx>>;
95100

96101
/// Creates a new universe index. Used when instantiating placeholders.
97102
fn create_next_universe(&mut self) -> ty::UniverseIndex;
@@ -590,7 +595,7 @@ where
590595
(_, &ty::Opaque(..)) => (generalize(a, true)?, b),
591596
_ => unreachable!(),
592597
};
593-
self.delegate.register_opaque_type(a, b, true);
598+
self.delegate.register_opaque_type(a, b, true)?;
594599
trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
595600
Ok(a)
596601
}

compiler/rustc_infer/src/infer/opaque_types.rs

Lines changed: 39 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::infer::{InferCtxt, InferOk};
2-
use crate::traits::{self, PredicateObligation};
2+
use crate::traits;
33
use hir::def_id::{DefId, LocalDefId};
44
use hir::OpaqueTyOrigin;
55
use rustc_data_structures::sync::Lrc;
@@ -42,25 +42,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
4242
&self,
4343
a: Ty<'tcx>,
4444
b: Ty<'tcx>,
45+
a_is_expected: bool,
4546
cause: &ObligationCause<'tcx>,
4647
param_env: ty::ParamEnv<'tcx>,
4748
) -> InferResult<'tcx, ()> {
4849
if a.references_error() || b.references_error() {
4950
return Ok(InferOk { value: (), obligations: vec![] });
5051
}
51-
if self.defining_use_anchor.is_some() {
52-
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
53-
ty::Opaque(def_id, substs) => {
54-
if let ty::Opaque(did2, _) = *b.kind() {
55-
// We could accept this, but there are various ways to handle this situation, and we don't
56-
// want to make a decision on it right now. Likely this case is so super rare anyway, that
57-
// no one encounters it in practice.
58-
// It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
59-
// where it is of no concern, so we only check for TAITs.
60-
if let Some(OpaqueTyOrigin::TyAlias) =
61-
self.opaque_type_origin(did2, cause.span)
62-
{
63-
self.tcx
52+
let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
53+
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
54+
ty::Opaque(def_id, substs) => {
55+
if let ty::Opaque(did2, _) = *b.kind() {
56+
// We could accept this, but there are various ways to handle this situation, and we don't
57+
// want to make a decision on it right now. Likely this case is so super rare anyway, that
58+
// no one encounters it in practice.
59+
// It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
60+
// where it is of no concern, so we only check for TAITs.
61+
if let Some(OpaqueTyOrigin::TyAlias) = self.opaque_type_origin(did2, cause.span)
62+
{
63+
self.tcx
6464
.sess
6565
.struct_span_err(
6666
cause.span,
@@ -76,13 +76,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
7676
"opaque type being used as hidden type",
7777
)
7878
.emit();
79-
}
8079
}
81-
Some(self.register_hidden_type(
82-
OpaqueTypeKey { def_id, substs },
83-
cause.clone(),
84-
param_env,
85-
b,
80+
}
81+
Some(self.register_hidden_type(
82+
OpaqueTypeKey { def_id, substs },
83+
cause.clone(),
84+
param_env,
85+
b,
86+
if self.defining_use_anchor.is_some() {
8687
// Check that this is `impl Trait` type is
8788
// declared by `parent_def_id` -- i.e., one whose
8889
// value we are inferring. At present, this is
@@ -117,47 +118,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
117118
// let x = || foo(); // returns the Opaque assoc with `foo`
118119
// }
119120
// ```
120-
self.opaque_type_origin(def_id, cause.span)?,
121-
))
122-
}
123-
_ => None,
124-
};
125-
if let Some(res) = process(a, b) {
126-
res
127-
} else if let Some(res) = process(b, a) {
128-
res
129-
} else {
130-
// Rerun equality check, but this time error out due to
131-
// different types.
132-
match self.at(cause, param_env).define_opaque_types(false).eq(a, b) {
133-
Ok(_) => span_bug!(
134-
cause.span,
135-
"opaque types are never equal to anything but themselves: {:#?}",
136-
(a.kind(), b.kind())
137-
),
138-
Err(e) => Err(e),
139-
}
121+
self.opaque_type_origin(def_id, cause.span)?
122+
} else {
123+
self.opaque_ty_origin_unchecked(def_id, cause.span)
124+
},
125+
))
140126
}
127+
_ => None,
128+
};
129+
if let Some(res) = process(a, b) {
130+
res
131+
} else if let Some(res) = process(b, a) {
132+
res
141133
} else {
142-
let (opaque_type, hidden_ty) = match (a.kind(), b.kind()) {
143-
(ty::Opaque(..), _) => (a, b),
144-
(_, ty::Opaque(..)) => (b, a),
145-
types => span_bug!(
134+
// Rerun equality check, but this time error out due to
135+
// different types.
136+
match self.at(cause, param_env).define_opaque_types(false).eq(a, b) {
137+
Ok(_) => span_bug!(
146138
cause.span,
147-
"opaque type obligations only work for opaque types: {:#?}",
148-
types
139+
"opaque types are never equal to anything but themselves: {:#?}",
140+
(a.kind(), b.kind())
149141
),
150-
};
151-
let key = opaque_type.expect_opaque_type();
152-
let origin = self.opaque_ty_origin_unchecked(key.def_id, cause.span);
153-
let prev = self.inner.borrow_mut().opaque_types().register(
154-
key,
155-
OpaqueHiddenType { ty: hidden_ty, span: cause.span },
156-
origin,
157-
);
158-
match prev {
159-
Some(prev) => self.at(cause, param_env).eq(prev, hidden_ty),
160-
None => Ok(InferOk { value: (), obligations: vec![] }),
142+
Err(e) => Err(e),
161143
}
162144
}
163145
}
@@ -363,22 +345,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
363345
});
364346
}
365347

366-
pub fn opaque_ty_obligation(
367-
&self,
368-
a: Ty<'tcx>,
369-
b: Ty<'tcx>,
370-
a_is_expected: bool,
371-
param_env: ty::ParamEnv<'tcx>,
372-
cause: ObligationCause<'tcx>,
373-
) -> PredicateObligation<'tcx> {
374-
let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
375-
PredicateObligation::new(
376-
cause,
377-
param_env,
378-
self.tcx.mk_predicate(ty::Binder::dummy(ty::PredicateKind::OpaqueType(a, b))),
379-
)
380-
}
381-
382348
#[instrument(skip(self), level = "trace")]
383349
pub fn opaque_type_origin(&self, opaque_def_id: DefId, span: Span) -> Option<OpaqueTyOrigin> {
384350
let def_id = opaque_def_id.as_local()?;

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ pub fn explicit_outlives_bounds<'tcx>(
2828
| ty::PredicateKind::TypeOutlives(..)
2929
| ty::PredicateKind::ConstEvaluatable(..)
3030
| ty::PredicateKind::ConstEquate(..)
31-
| ty::PredicateKind::OpaqueType(..)
3231
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
3332
ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
3433
Some(OutlivesBound::RegionSubRegion(r_b, r_a))

compiler/rustc_infer/src/infer/sub.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,11 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
146146
(_, &ty::Opaque(..)) => (generalize(a, false)?, b),
147147
_ => unreachable!(),
148148
};
149-
self.fields.obligations.push(infcx.opaque_ty_obligation(
150-
a,
151-
b,
152-
true,
153-
self.param_env(),
154-
self.fields.trace.cause.clone(),
155-
));
149+
self.fields.obligations.extend(
150+
infcx
151+
.handle_opaque_type(a, b, true, &self.fields.trace.cause, self.param_env())?
152+
.obligations,
153+
);
156154
Ok(a)
157155
}
158156

compiler/rustc_infer/src/traits/util.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,6 @@ impl<'tcx> Elaborator<'tcx> {
167167
// Currently, we do not elaborate WF predicates,
168168
// although we easily could.
169169
}
170-
ty::PredicateKind::OpaqueType(..) => {
171-
todo!("{:#?}", obligation)
172-
}
173170
ty::PredicateKind::ObjectSafe(..) => {
174171
// Currently, we do not elaborate object-safe
175172
// predicates.

0 commit comments

Comments
 (0)