Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b0696a5

Browse files
committedMar 1, 2024
Auto merge of #121462 - compiler-errors:eq-and-sub, r=lcnr
Combine `Sub` and `Equate` Combine `Sub` and `Equate` into a new relation called `TypeRelating` (that name sounds familiar...) Tracks the difference between `Sub` and `Equate` via `ambient_variance: ty::Variance` much like the `NllTypeRelating` relation, but implemented slightly jankier because it's a more general purpose relation. r? lcnr
2 parents 6cbf092 + 5072b65 commit b0696a5

File tree

28 files changed

+509
-840
lines changed

28 files changed

+509
-840
lines changed
 

‎compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1066,7 +1066,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
10661066
&cause,
10671067
param_env,
10681068
hidden_ty.ty,
1069-
true,
10701069
&mut obligations,
10711070
)?;
10721071

‎compiler/rustc_borrowck/src/type_check/relate_tys.rs

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
120120
fn relate_opaques(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
121121
let infcx = self.type_checker.infcx;
122122
debug_assert!(!infcx.next_trait_solver());
123-
let (a, b) = if self.a_is_expected() { (a, b) } else { (b, a) };
124123
// `handle_opaque_type` cannot handle subtyping, so to support subtyping
125124
// we instead eagerly generalize here. This is a bit of a mess but will go
126125
// away once we're using the new solver.
@@ -161,8 +160,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
161160
),
162161
};
163162
let cause = ObligationCause::dummy_with_span(self.span());
164-
let obligations =
165-
infcx.handle_opaque_type(a, b, true, &cause, self.param_env())?.obligations;
163+
let obligations = infcx.handle_opaque_type(a, b, &cause, self.param_env())?.obligations;
166164
self.register_obligations(obligations);
167165
Ok(())
168166
}
@@ -331,10 +329,6 @@ impl<'bccx, 'tcx> TypeRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> {
331329
"nll::subtype"
332330
}
333331

334-
fn a_is_expected(&self) -> bool {
335-
true
336-
}
337-
338332
#[instrument(skip(self, info), level = "trace", ret)]
339333
fn relate_with_variance<T: Relate<'tcx>>(
340334
&mut self,
@@ -349,12 +343,15 @@ impl<'bccx, 'tcx> TypeRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> {
349343

350344
debug!(?self.ambient_variance);
351345
// In a bivariant context this always succeeds.
352-
let r =
353-
if self.ambient_variance == ty::Variance::Bivariant { a } else { self.relate(a, b)? };
346+
let r = if self.ambient_variance == ty::Variance::Bivariant {
347+
Ok(a)
348+
} else {
349+
self.relate(a, b)
350+
};
354351

355352
self.ambient_variance = old_ambient_variance;
356353

357-
Ok(r)
354+
r
358355
}
359356

360357
#[instrument(skip(self), level = "debug")]
@@ -579,10 +576,6 @@ impl<'bccx, 'tcx> ObligationEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx
579576
);
580577
}
581578

582-
fn alias_relate_direction(&self) -> ty::AliasRelationDirection {
583-
unreachable!("manually overridden to handle ty::Variance::Contravariant ambient variance")
584-
}
585-
586579
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
587580
self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
588581
ty::Variance::Covariant => ty::PredicateKind::AliasRelate(

‎compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,6 +1493,21 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
14931493
return;
14941494
}
14951495

1496+
let (expected, found) = if label_expression_as_expected {
1497+
// In the case where this is a "forced unit", like
1498+
// `break`, we want to call the `()` "expected"
1499+
// since it is implied by the syntax.
1500+
// (Note: not all force-units work this way.)"
1501+
(expression_ty, self.merged_ty())
1502+
} else {
1503+
// Otherwise, the "expected" type for error
1504+
// reporting is the current unification type,
1505+
// which is basically the LUB of the expressions
1506+
// we've seen so far (combined with the expected
1507+
// type)
1508+
(self.merged_ty(), expression_ty)
1509+
};
1510+
14961511
// Handle the actual type unification etc.
14971512
let result = if let Some(expression) = expression {
14981513
if self.pushed == 0 {
@@ -1540,12 +1555,11 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
15401555
// Another example is `break` with no argument expression.
15411556
assert!(expression_ty.is_unit(), "if let hack without unit type");
15421557
fcx.at(cause, fcx.param_env)
1543-
// needed for tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
1544-
.eq_exp(
1558+
.eq(
1559+
// needed for tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
15451560
DefineOpaqueTypes::Yes,
1546-
label_expression_as_expected,
1547-
expression_ty,
1548-
self.merged_ty(),
1561+
expected,
1562+
found,
15491563
)
15501564
.map(|infer_ok| {
15511565
fcx.register_infer_ok_obligations(infer_ok);
@@ -1579,20 +1593,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
15791593
fcx.set_tainted_by_errors(
15801594
fcx.dcx().span_delayed_bug(cause.span, "coercion error but no error emitted"),
15811595
);
1582-
let (expected, found) = if label_expression_as_expected {
1583-
// In the case where this is a "forced unit", like
1584-
// `break`, we want to call the `()` "expected"
1585-
// since it is implied by the syntax.
1586-
// (Note: not all force-units work this way.)"
1587-
(expression_ty, self.merged_ty())
1588-
} else {
1589-
// Otherwise, the "expected" type for error
1590-
// reporting is the current unification type,
1591-
// which is basically the LUB of the expressions
1592-
// we've seen so far (combined with the expected
1593-
// type)
1594-
(self.merged_ty(), expression_ty)
1595-
};
15961596
let (expected, found) = fcx.resolve_vars_if_possible((expected, found));
15971597

15981598
let mut err;

‎compiler/rustc_infer/src/infer/at.rs

Lines changed: 29 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ pub struct At<'a, 'tcx> {
4949

5050
pub struct Trace<'a, 'tcx> {
5151
at: At<'a, 'tcx>,
52-
a_is_expected: bool,
5352
trace: TypeTrace<'tcx>,
5453
}
5554

@@ -105,23 +104,6 @@ pub trait ToTrace<'tcx>: Relate<'tcx> + Copy {
105104
}
106105

107106
impl<'a, 'tcx> At<'a, 'tcx> {
108-
/// Makes `a <: b`, where `a` may or may not be expected.
109-
///
110-
/// See [`At::trace_exp`] and [`Trace::sub`] for a version of
111-
/// this method that only requires `T: Relate<'tcx>`
112-
pub fn sub_exp<T>(
113-
self,
114-
define_opaque_types: DefineOpaqueTypes,
115-
a_is_expected: bool,
116-
a: T,
117-
b: T,
118-
) -> InferResult<'tcx, ()>
119-
where
120-
T: ToTrace<'tcx>,
121-
{
122-
self.trace_exp(a_is_expected, a, b).sub(define_opaque_types, a, b)
123-
}
124-
125107
/// Makes `actual <: expected`. For example, if type-checking a
126108
/// call like `foo(x)`, where `foo: fn(i32)`, you might have
127109
/// `sup(i32, x)`, since the "expected" type is the type that
@@ -138,7 +120,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
138120
where
139121
T: ToTrace<'tcx>,
140122
{
141-
self.sub_exp(define_opaque_types, false, actual, expected)
123+
self.trace(expected, actual).sup(define_opaque_types, expected, actual)
142124
}
143125

144126
/// Makes `expected <: actual`.
@@ -154,24 +136,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
154136
where
155137
T: ToTrace<'tcx>,
156138
{
157-
self.sub_exp(define_opaque_types, true, expected, actual)
158-
}
159-
160-
/// Makes `expected <: actual`.
161-
///
162-
/// See [`At::trace_exp`] and [`Trace::eq`] for a version of
163-
/// this method that only requires `T: Relate<'tcx>`
164-
pub fn eq_exp<T>(
165-
self,
166-
define_opaque_types: DefineOpaqueTypes,
167-
a_is_expected: bool,
168-
a: T,
169-
b: T,
170-
) -> InferResult<'tcx, ()>
171-
where
172-
T: ToTrace<'tcx>,
173-
{
174-
self.trace_exp(a_is_expected, a, b).eq(define_opaque_types, a, b)
139+
self.trace(expected, actual).sub(define_opaque_types, expected, actual)
175140
}
176141

177142
/// Makes `expected <: actual`.
@@ -260,48 +225,50 @@ impl<'a, 'tcx> At<'a, 'tcx> {
260225
where
261226
T: ToTrace<'tcx>,
262227
{
263-
self.trace_exp(true, expected, actual)
228+
let trace = ToTrace::to_trace(self.cause, true, expected, actual);
229+
Trace { at: self, trace }
264230
}
231+
}
265232

266-
/// Like `trace`, but the expected value is determined by the
267-
/// boolean argument (if true, then the first argument `a` is the
268-
/// "expected" value).
269-
pub fn trace_exp<T>(self, a_is_expected: bool, a: T, b: T) -> Trace<'a, 'tcx>
233+
impl<'a, 'tcx> Trace<'a, 'tcx> {
234+
/// Makes `a <: b`.
235+
#[instrument(skip(self), level = "debug")]
236+
pub fn sub<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()>
270237
where
271-
T: ToTrace<'tcx>,
238+
T: Relate<'tcx>,
272239
{
273-
let trace = ToTrace::to_trace(self.cause, a_is_expected, a, b);
274-
Trace { at: self, trace, a_is_expected }
240+
let Trace { at, trace } = self;
241+
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
242+
fields
243+
.sub()
244+
.relate(a, b)
245+
.map(move |_| InferOk { value: (), obligations: fields.obligations })
275246
}
276-
}
277247

278-
impl<'a, 'tcx> Trace<'a, 'tcx> {
279-
/// Makes `a <: b` where `a` may or may not be expected (if
280-
/// `a_is_expected` is true, then `a` is expected).
248+
/// Makes `a :> b`.
281249
#[instrument(skip(self), level = "debug")]
282-
pub fn sub<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()>
250+
pub fn sup<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()>
283251
where
284252
T: Relate<'tcx>,
285253
{
286-
let Trace { at, trace, a_is_expected } = self;
254+
let Trace { at, trace } = self;
287255
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
288256
fields
289-
.sub(a_is_expected)
257+
.sup()
290258
.relate(a, b)
291259
.map(move |_| InferOk { value: (), obligations: fields.obligations })
292260
}
293261

294-
/// Makes `a == b`; the expectation is set by the call to
295-
/// `trace()`.
262+
/// Makes `a == b`.
296263
#[instrument(skip(self), level = "debug")]
297264
pub fn eq<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()>
298265
where
299266
T: Relate<'tcx>,
300267
{
301-
let Trace { at, trace, a_is_expected } = self;
268+
let Trace { at, trace } = self;
302269
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
303270
fields
304-
.equate(StructurallyRelateAliases::No, a_is_expected)
271+
.equate(StructurallyRelateAliases::No)
305272
.relate(a, b)
306273
.map(move |_| InferOk { value: (), obligations: fields.obligations })
307274
}
@@ -313,11 +280,11 @@ impl<'a, 'tcx> Trace<'a, 'tcx> {
313280
where
314281
T: Relate<'tcx>,
315282
{
316-
let Trace { at, trace, a_is_expected } = self;
283+
let Trace { at, trace } = self;
317284
debug_assert!(at.infcx.next_trait_solver());
318285
let mut fields = at.infcx.combine_fields(trace, at.param_env, DefineOpaqueTypes::No);
319286
fields
320-
.equate(StructurallyRelateAliases::Yes, a_is_expected)
287+
.equate(StructurallyRelateAliases::Yes)
321288
.relate(a, b)
322289
.map(move |_| InferOk { value: (), obligations: fields.obligations })
323290
}
@@ -327,10 +294,10 @@ impl<'a, 'tcx> Trace<'a, 'tcx> {
327294
where
328295
T: Relate<'tcx>,
329296
{
330-
let Trace { at, trace, a_is_expected } = self;
297+
let Trace { at, trace } = self;
331298
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
332299
fields
333-
.lub(a_is_expected)
300+
.lub()
334301
.relate(a, b)
335302
.map(move |t| InferOk { value: t, obligations: fields.obligations })
336303
}
@@ -340,10 +307,10 @@ impl<'a, 'tcx> Trace<'a, 'tcx> {
340307
where
341308
T: Relate<'tcx>,
342309
{
343-
let Trace { at, trace, a_is_expected } = self;
310+
let Trace { at, trace } = self;
344311
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
345312
fields
346-
.glb(a_is_expected)
313+
.glb()
347314
.relate(a, b)
348315
.map(move |t| InferOk { value: t, obligations: fields.obligations })
349316
}

‎compiler/rustc_infer/src/infer/error_reporting/mod.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2654,10 +2654,6 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
26542654
"SameTypeModuloInfer"
26552655
}
26562656

2657-
fn a_is_expected(&self) -> bool {
2658-
true
2659-
}
2660-
26612657
fn relate_with_variance<T: relate::Relate<'tcx>>(
26622658
&mut self,
26632659
_variance: ty::Variance,

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -836,7 +836,6 @@ impl<'tcx> InferCtxt<'tcx> {
836836
CombineFields {
837837
infcx: self,
838838
trace,
839-
cause: None,
840839
param_env,
841840
obligations: PredicateObligations::new(),
842841
define_opaque_types,
@@ -1033,7 +1032,11 @@ impl<'tcx> InferCtxt<'tcx> {
10331032
}
10341033

10351034
self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| {
1036-
Ok(self.at(cause, param_env).sub_exp(DefineOpaqueTypes::No, a_is_expected, a, b))
1035+
if a_is_expected {
1036+
Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::No, a, b))
1037+
} else {
1038+
Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::No, b, a))
1039+
}
10371040
})
10381041
}
10391042

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

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,7 @@ impl<'tcx> InferCtxt<'tcx> {
7878
span,
7979
});
8080
obligations.extend(
81-
self.handle_opaque_type(ty, ty_var, true, &cause, param_env)
82-
.unwrap()
83-
.obligations,
81+
self.handle_opaque_type(ty, ty_var, &cause, param_env).unwrap().obligations,
8482
);
8583
ty_var
8684
}
@@ -94,15 +92,13 @@ impl<'tcx> InferCtxt<'tcx> {
9492
&self,
9593
a: Ty<'tcx>,
9694
b: Ty<'tcx>,
97-
a_is_expected: bool,
9895
cause: &ObligationCause<'tcx>,
9996
param_env: ty::ParamEnv<'tcx>,
10097
) -> InferResult<'tcx, ()> {
10198
if a.references_error() || b.references_error() {
10299
return Ok(InferOk { value: (), obligations: vec![] });
103100
}
104-
let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
105-
let process = |a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected| match *a.kind() {
101+
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
106102
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => {
107103
let def_id = def_id.expect_local();
108104
match self.defining_use_anchor {
@@ -169,14 +165,13 @@ impl<'tcx> InferCtxt<'tcx> {
169165
cause.clone(),
170166
param_env,
171167
b,
172-
a_is_expected,
173168
))
174169
}
175170
_ => None,
176171
};
177-
if let Some(res) = process(a, b, true) {
172+
if let Some(res) = process(a, b) {
178173
res
179-
} else if let Some(res) = process(b, a, false) {
174+
} else if let Some(res) = process(b, a) {
180175
res
181176
} else {
182177
let (a, b) = self.resolve_vars_if_possible((a, b));
@@ -520,18 +515,10 @@ impl<'tcx> InferCtxt<'tcx> {
520515
cause: ObligationCause<'tcx>,
521516
param_env: ty::ParamEnv<'tcx>,
522517
hidden_ty: Ty<'tcx>,
523-
a_is_expected: bool,
524518
) -> InferResult<'tcx, ()> {
525519
let mut obligations = Vec::new();
526520

527-
self.insert_hidden_type(
528-
opaque_type_key,
529-
&cause,
530-
param_env,
531-
hidden_ty,
532-
a_is_expected,
533-
&mut obligations,
534-
)?;
521+
self.insert_hidden_type(opaque_type_key, &cause, param_env, hidden_ty, &mut obligations)?;
535522

536523
self.add_item_bounds_for_hidden_type(
537524
opaque_type_key.def_id.to_def_id(),
@@ -558,7 +545,6 @@ impl<'tcx> InferCtxt<'tcx> {
558545
cause: &ObligationCause<'tcx>,
559546
param_env: ty::ParamEnv<'tcx>,
560547
hidden_ty: Ty<'tcx>,
561-
a_is_expected: bool,
562548
obligations: &mut Vec<PredicateObligation<'tcx>>,
563549
) -> Result<(), TypeError<'tcx>> {
564550
// Ideally, we'd get the span where *this specific `ty` came
@@ -586,7 +572,7 @@ impl<'tcx> InferCtxt<'tcx> {
586572
if let Some(prev) = prev {
587573
obligations.extend(
588574
self.at(cause, param_env)
589-
.eq_exp(DefineOpaqueTypes::Yes, a_is_expected, prev, hidden_ty)?
575+
.eq(DefineOpaqueTypes::Yes, prev, hidden_ty)?
590576
.obligations,
591577
);
592578
}

‎compiler/rustc_infer/src/infer/outlives/test_type_match.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,6 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstHigherRankedOutlives<'tcx> {
144144
self.tcx
145145
}
146146

147-
fn a_is_expected(&self) -> bool {
148-
true
149-
} // irrelevant
150-
151147
#[instrument(level = "trace", skip(self))]
152148
fn relate_with_variance<T: Relate<'tcx>>(
153149
&mut self,

‎compiler/rustc_infer/src/infer/relate/combine.rs

Lines changed: 29 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
//! There are four type combiners: [Equate], [Sub], [Lub], and [Glb].
1+
//! There are four type combiners: [TypeRelating], [Lub], and [Glb],
2+
//! and `NllTypeRelating` in rustc_borrowck, which is only used for NLL.
3+
//!
24
//! Each implements the trait [TypeRelation] and contains methods for
35
//! combining two instances of various things and yielding a new instance.
46
//! These combiner methods always yield a `Result<T>`. To relate two
@@ -15,17 +17,10 @@
1517
//!
1618
//! On success, the LUB/GLB operations return the appropriate bound. The
1719
//! return value of `Equate` or `Sub` shouldn't really be used.
18-
//!
19-
//! ## Contravariance
20-
//!
21-
//! We explicitly track which argument is expected using
22-
//! [TypeRelation::a_is_expected], so when dealing with contravariance
23-
//! this should be correctly updated.
2420
25-
use super::equate::Equate;
2621
use super::glb::Glb;
2722
use super::lub::Lub;
28-
use super::sub::Sub;
23+
use super::type_relating::TypeRelating;
2924
use super::StructurallyRelateAliases;
3025
use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
3126
use crate::traits::{Obligation, PredicateObligations};
@@ -41,7 +36,6 @@ use rustc_span::Span;
4136
pub struct CombineFields<'infcx, 'tcx> {
4237
pub infcx: &'infcx InferCtxt<'tcx>,
4338
pub trace: TypeTrace<'tcx>,
44-
pub cause: Option<ty::relate::Cause>,
4539
pub param_env: ty::ParamEnv<'tcx>,
4640
pub obligations: PredicateObligations<'tcx>,
4741
pub define_opaque_types: DefineOpaqueTypes,
@@ -57,7 +51,6 @@ impl<'tcx> InferCtxt<'tcx> {
5751
where
5852
R: ObligationEmittingRelation<'tcx>,
5953
{
60-
let a_is_expected = relation.a_is_expected();
6154
debug_assert!(!a.has_escaping_bound_vars());
6255
debug_assert!(!b.has_escaping_bound_vars());
6356

@@ -68,20 +61,20 @@ impl<'tcx> InferCtxt<'tcx> {
6861
.borrow_mut()
6962
.int_unification_table()
7063
.unify_var_var(a_id, b_id)
71-
.map_err(|e| int_unification_error(a_is_expected, e))?;
64+
.map_err(|e| int_unification_error(true, e))?;
7265
Ok(a)
7366
}
7467
(&ty::Infer(ty::IntVar(v_id)), &ty::Int(v)) => {
75-
self.unify_integral_variable(a_is_expected, v_id, IntType(v))
68+
self.unify_integral_variable(true, v_id, IntType(v))
7669
}
7770
(&ty::Int(v), &ty::Infer(ty::IntVar(v_id))) => {
78-
self.unify_integral_variable(!a_is_expected, v_id, IntType(v))
71+
self.unify_integral_variable(false, v_id, IntType(v))
7972
}
8073
(&ty::Infer(ty::IntVar(v_id)), &ty::Uint(v)) => {
81-
self.unify_integral_variable(a_is_expected, v_id, UintType(v))
74+
self.unify_integral_variable(true, v_id, UintType(v))
8275
}
8376
(&ty::Uint(v), &ty::Infer(ty::IntVar(v_id))) => {
84-
self.unify_integral_variable(!a_is_expected, v_id, UintType(v))
77+
self.unify_integral_variable(false, v_id, UintType(v))
8578
}
8679

8780
// Relate floating-point variables to other types
@@ -90,14 +83,14 @@ impl<'tcx> InferCtxt<'tcx> {
9083
.borrow_mut()
9184
.float_unification_table()
9285
.unify_var_var(a_id, b_id)
93-
.map_err(|e| float_unification_error(a_is_expected, e))?;
86+
.map_err(|e| float_unification_error(true, e))?;
9487
Ok(a)
9588
}
9689
(&ty::Infer(ty::FloatVar(v_id)), &ty::Float(v)) => {
97-
self.unify_float_variable(a_is_expected, v_id, v)
90+
self.unify_float_variable(true, v_id, v)
9891
}
9992
(&ty::Float(v), &ty::Infer(ty::FloatVar(v_id))) => {
100-
self.unify_float_variable(!a_is_expected, v_id, v)
93+
self.unify_float_variable(false, v_id, v)
10194
}
10295

10396
// We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm.
@@ -130,7 +123,7 @@ impl<'tcx> InferCtxt<'tcx> {
130123

131124
// All other cases of inference are errors
132125
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
133-
Err(TypeError::Sorts(ty::relate::expected_found(relation, a, b)))
126+
Err(TypeError::Sorts(ty::relate::expected_found(a, b)))
134127
}
135128

136129
// During coherence, opaque types should be treated as *possibly*
@@ -228,12 +221,12 @@ impl<'tcx> InferCtxt<'tcx> {
228221
}
229222

230223
(ty::ConstKind::Infer(InferConst::Var(vid)), _) => {
231-
self.instantiate_const_var(relation, relation.a_is_expected(), vid, b)?;
224+
self.instantiate_const_var(relation, true, vid, b)?;
232225
Ok(b)
233226
}
234227

235228
(_, ty::ConstKind::Infer(InferConst::Var(vid))) => {
236-
self.instantiate_const_var(relation, !relation.a_is_expected(), vid, a)?;
229+
self.instantiate_const_var(relation, false, vid, a)?;
237230
Ok(a)
238231
}
239232

@@ -250,8 +243,6 @@ impl<'tcx> InferCtxt<'tcx> {
250243
{
251244
match relation.structurally_relate_aliases() {
252245
StructurallyRelateAliases::No => {
253-
let (a, b) = if relation.a_is_expected() { (a, b) } else { (b, a) };
254-
255246
relation.register_predicates([if self.next_trait_solver() {
256247
ty::PredicateKind::AliasRelate(
257248
a.into(),
@@ -321,21 +312,24 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
321312
pub fn equate<'a>(
322313
&'a mut self,
323314
structurally_relate_aliases: StructurallyRelateAliases,
324-
a_is_expected: bool,
325-
) -> Equate<'a, 'infcx, 'tcx> {
326-
Equate::new(self, structurally_relate_aliases, a_is_expected)
315+
) -> TypeRelating<'a, 'infcx, 'tcx> {
316+
TypeRelating::new(self, structurally_relate_aliases, ty::Invariant)
327317
}
328318

329-
pub fn sub<'a>(&'a mut self, a_is_expected: bool) -> Sub<'a, 'infcx, 'tcx> {
330-
Sub::new(self, a_is_expected)
319+
pub fn sub<'a>(&'a mut self) -> TypeRelating<'a, 'infcx, 'tcx> {
320+
TypeRelating::new(self, StructurallyRelateAliases::No, ty::Covariant)
331321
}
332322

333-
pub fn lub<'a>(&'a mut self, a_is_expected: bool) -> Lub<'a, 'infcx, 'tcx> {
334-
Lub::new(self, a_is_expected)
323+
pub fn sup<'a>(&'a mut self) -> TypeRelating<'a, 'infcx, 'tcx> {
324+
TypeRelating::new(self, StructurallyRelateAliases::No, ty::Contravariant)
335325
}
336326

337-
pub fn glb<'a>(&'a mut self, a_is_expected: bool) -> Glb<'a, 'infcx, 'tcx> {
338-
Glb::new(self, a_is_expected)
327+
pub fn lub<'a>(&'a mut self) -> Lub<'a, 'infcx, 'tcx> {
328+
Lub::new(self)
329+
}
330+
331+
pub fn glb<'a>(&'a mut self) -> Glb<'a, 'infcx, 'tcx> {
332+
Glb::new(self)
339333
}
340334

341335
pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
@@ -367,19 +361,8 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> {
367361
/// be used if control over the obligation causes is required.
368362
fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ToPredicate<'tcx>>);
369363

370-
/// Register an obligation that both types must be related to each other according to
371-
/// the [`ty::AliasRelationDirection`] given by [`ObligationEmittingRelation::alias_relate_direction`]
372-
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
373-
self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasRelate(
374-
a.into(),
375-
b.into(),
376-
self.alias_relate_direction(),
377-
))]);
378-
}
379-
380-
/// Relation direction emitted for `AliasRelate` predicates, corresponding to the direction
381-
/// of the relation.
382-
fn alias_relate_direction(&self) -> ty::AliasRelationDirection;
364+
/// Register `AliasRelate` obligation(s) that both types must be related to each other.
365+
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>);
383366
}
384367

385368
fn int_unification_error<'tcx>(

‎compiler/rustc_infer/src/infer/relate/equate.rs

Lines changed: 0 additions & 228 deletions
This file was deleted.

‎compiler/rustc_infer/src/infer/relate/generalize.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ impl<'tcx> InferCtxt<'tcx> {
130130
// instantiate_ty_var(?b, A) # expected and variance flipped
131131
// A rel A'
132132
// ```
133-
if target_is_expected == relation.a_is_expected() {
133+
if target_is_expected {
134134
relation.relate(generalized_ty, source_ty)?;
135135
} else {
136136
debug!("flip relation");
@@ -204,9 +204,9 @@ impl<'tcx> InferCtxt<'tcx> {
204204
.const_unification_table()
205205
.union_value(target_vid, ConstVariableValue::Known { value: generalized_ct });
206206

207-
// HACK: make sure that we `a_is_expected` continues to be
208-
// correct when relating the generalized type with the source.
209-
if target_is_expected == relation.a_is_expected() {
207+
// Make sure that the order is correct when relating the
208+
// generalized const and the source.
209+
if target_is_expected {
210210
relation.relate_with_variance(
211211
ty::Variance::Invariant,
212212
ty::VarianceDiagInfo::default(),
@@ -398,10 +398,6 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
398398
"Generalizer"
399399
}
400400

401-
fn a_is_expected(&self) -> bool {
402-
true
403-
}
404-
405401
fn relate_item_args(
406402
&mut self,
407403
item_def_id: DefId,
@@ -440,9 +436,9 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
440436
debug!(?self.ambient_variance, "new ambient variance");
441437
// Recursive calls to `relate` can overflow the stack. For example a deeper version of
442438
// `ui/associated-consts/issue-93775.rs`.
443-
let r = ensure_sufficient_stack(|| self.relate(a, b))?;
439+
let r = ensure_sufficient_stack(|| self.relate(a, b));
444440
self.ambient_variance = old_ambient_variance;
445-
Ok(r)
441+
r
446442
}
447443

448444
#[instrument(level = "debug", skip(self, t2), ret)]

‎compiler/rustc_infer/src/infer/relate/glb.rs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,11 @@ use crate::traits::{ObligationCause, PredicateObligations};
1313
/// "Greatest lower bound" (common subtype)
1414
pub struct Glb<'combine, 'infcx, 'tcx> {
1515
fields: &'combine mut CombineFields<'infcx, 'tcx>,
16-
a_is_expected: bool,
1716
}
1817

1918
impl<'combine, 'infcx, 'tcx> Glb<'combine, 'infcx, 'tcx> {
20-
pub fn new(
21-
fields: &'combine mut CombineFields<'infcx, 'tcx>,
22-
a_is_expected: bool,
23-
) -> Glb<'combine, 'infcx, 'tcx> {
24-
Glb { fields, a_is_expected }
19+
pub fn new(fields: &'combine mut CombineFields<'infcx, 'tcx>) -> Glb<'combine, 'infcx, 'tcx> {
20+
Glb { fields }
2521
}
2622
}
2723

@@ -34,10 +30,6 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
3430
self.fields.tcx()
3531
}
3632

37-
fn a_is_expected(&self) -> bool {
38-
self.a_is_expected
39-
}
40-
4133
fn relate_with_variance<T: Relate<'tcx>>(
4234
&mut self,
4335
variance: ty::Variance,
@@ -46,13 +38,11 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
4638
b: T,
4739
) -> RelateResult<'tcx, T> {
4840
match variance {
49-
ty::Invariant => {
50-
self.fields.equate(StructurallyRelateAliases::No, self.a_is_expected).relate(a, b)
51-
}
41+
ty::Invariant => self.fields.equate(StructurallyRelateAliases::No).relate(a, b),
5242
ty::Covariant => self.relate(a, b),
5343
// FIXME(#41044) -- not correct, need test
5444
ty::Bivariant => Ok(a),
55-
ty::Contravariant => self.fields.lub(self.a_is_expected).relate(a, b),
45+
ty::Contravariant => self.fields.lub().relate(a, b),
5646
}
5747
}
5848

@@ -126,7 +116,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx,
126116
}
127117

128118
fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
129-
let mut sub = self.fields.sub(self.a_is_expected);
119+
let mut sub = self.fields.sub();
130120
sub.relate(v, a)?;
131121
sub.relate(v, b)?;
132122
Ok(())
@@ -158,8 +148,12 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> {
158148
self.fields.register_obligations(obligations);
159149
}
160150

161-
fn alias_relate_direction(&self) -> ty::AliasRelationDirection {
162-
// FIXME(deferred_projection_equality): This isn't right, I think?
163-
ty::AliasRelationDirection::Equate
151+
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
152+
self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasRelate(
153+
a.into(),
154+
b.into(),
155+
// FIXME(deferred_projection_equality): This isn't right, I think?
156+
ty::AliasRelationDirection::Equate,
157+
))]);
164158
}
165159
}

‎compiler/rustc_infer/src/infer/relate/higher_ranked.rs

Lines changed: 3 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,11 @@
11
//! Helper routines for higher-ranked things. See the `doc` module at
22
//! the end of the file for details.
33
4-
use super::combine::CombineFields;
54
use crate::infer::CombinedSnapshot;
6-
use crate::infer::{HigherRankedType, InferCtxt};
5+
use crate::infer::InferCtxt;
76
use rustc_middle::ty::fold::FnMutDelegate;
8-
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
9-
use rustc_middle::ty::{self, Binder, Ty, TyCtxt, TypeFoldable};
10-
11-
impl<'a, 'tcx> CombineFields<'a, 'tcx> {
12-
/// Checks whether `for<..> sub <: for<..> sup` holds.
13-
///
14-
/// For this to hold, **all** instantiations of the super type
15-
/// have to be a super type of **at least one** instantiation of
16-
/// the subtype.
17-
///
18-
/// This is implemented by first entering a new universe.
19-
/// We then replace all bound variables in `sup` with placeholders,
20-
/// and all bound variables in `sub` with inference vars.
21-
/// We can then just relate the two resulting types as normal.
22-
///
23-
/// Note: this is a subtle algorithm. For a full explanation, please see
24-
/// the [rustc dev guide][rd]
25-
///
26-
/// [rd]: https://rustc-dev-guide.rust-lang.org/borrow_check/region_inference/placeholders_and_universes.html
27-
#[instrument(skip(self), level = "debug")]
28-
pub fn higher_ranked_sub<T>(
29-
&mut self,
30-
sub: Binder<'tcx, T>,
31-
sup: Binder<'tcx, T>,
32-
sub_is_expected: bool,
33-
) -> RelateResult<'tcx, ()>
34-
where
35-
T: Relate<'tcx>,
36-
{
37-
let span = self.trace.cause.span;
38-
// First, we instantiate each bound region in the supertype with a
39-
// fresh placeholder region. Note that this automatically creates
40-
// a new universe if needed.
41-
self.infcx.enter_forall(sup, |sup_prime| {
42-
// Next, we instantiate each bound region in the subtype
43-
// with a fresh region variable. These region variables --
44-
// but no other preexisting region variables -- can name
45-
// the placeholders.
46-
let sub_prime =
47-
self.infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, sub);
48-
debug!("a_prime={:?}", sub_prime);
49-
debug!("b_prime={:?}", sup_prime);
50-
51-
// Compare types now that bound regions have been replaced.
52-
let result = self.sub(sub_is_expected).relate(sub_prime, sup_prime);
53-
if result.is_ok() {
54-
debug!("OK result={result:?}");
55-
}
56-
// NOTE: returning the result here would be dangerous as it contains
57-
// placeholders which **must not** be named afterwards.
58-
result.map(|_| ())
59-
})
60-
}
61-
}
7+
use rustc_middle::ty::relate::RelateResult;
8+
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
629

6310
impl<'tcx> InferCtxt<'tcx> {
6411
/// Replaces all bound variables (lifetimes, types, and constants) bound by

‎compiler/rustc_infer/src/infer/relate/lattice.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,7 @@ where
116116
&& !this.infcx().next_trait_solver() =>
117117
{
118118
this.register_obligations(
119-
infcx
120-
.handle_opaque_type(a, b, this.a_is_expected(), this.cause(), this.param_env())?
121-
.obligations,
119+
infcx.handle_opaque_type(a, b, this.cause(), this.param_env())?.obligations,
122120
);
123121
Ok(a)
124122
}

‎compiler/rustc_infer/src/infer/relate/lub.rs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,11 @@ use rustc_span::Span;
1313
/// "Least upper bound" (common supertype)
1414
pub struct Lub<'combine, 'infcx, 'tcx> {
1515
fields: &'combine mut CombineFields<'infcx, 'tcx>,
16-
a_is_expected: bool,
1716
}
1817

1918
impl<'combine, 'infcx, 'tcx> Lub<'combine, 'infcx, 'tcx> {
20-
pub fn new(
21-
fields: &'combine mut CombineFields<'infcx, 'tcx>,
22-
a_is_expected: bool,
23-
) -> Lub<'combine, 'infcx, 'tcx> {
24-
Lub { fields, a_is_expected }
19+
pub fn new(fields: &'combine mut CombineFields<'infcx, 'tcx>) -> Lub<'combine, 'infcx, 'tcx> {
20+
Lub { fields }
2521
}
2622
}
2723

@@ -34,10 +30,6 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
3430
self.fields.tcx()
3531
}
3632

37-
fn a_is_expected(&self) -> bool {
38-
self.a_is_expected
39-
}
40-
4133
fn relate_with_variance<T: Relate<'tcx>>(
4234
&mut self,
4335
variance: ty::Variance,
@@ -46,13 +38,11 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
4638
b: T,
4739
) -> RelateResult<'tcx, T> {
4840
match variance {
49-
ty::Invariant => {
50-
self.fields.equate(StructurallyRelateAliases::No, self.a_is_expected).relate(a, b)
51-
}
41+
ty::Invariant => self.fields.equate(StructurallyRelateAliases::No).relate(a, b),
5242
ty::Covariant => self.relate(a, b),
5343
// FIXME(#41044) -- not correct, need test
5444
ty::Bivariant => Ok(a),
55-
ty::Contravariant => self.fields.glb(self.a_is_expected).relate(a, b),
45+
ty::Contravariant => self.fields.glb().relate(a, b),
5646
}
5747
}
5848

@@ -126,7 +116,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx,
126116
}
127117

128118
fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
129-
let mut sub = self.fields.sub(self.a_is_expected);
119+
let mut sub = self.fields.sub();
130120
sub.relate(a, v)?;
131121
sub.relate(b, v)?;
132122
Ok(())
@@ -158,8 +148,12 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> {
158148
self.fields.register_obligations(obligations)
159149
}
160150

161-
fn alias_relate_direction(&self) -> ty::AliasRelationDirection {
162-
// FIXME(deferred_projection_equality): This isn't right, I think?
163-
ty::AliasRelationDirection::Equate
151+
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
152+
self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasRelate(
153+
a.into(),
154+
b.into(),
155+
// FIXME(deferred_projection_equality): This isn't right, I think?
156+
ty::AliasRelationDirection::Equate,
157+
))]);
164158
}
165159
}

‎compiler/rustc_infer/src/infer/relate/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@
22
//! (except for some relations used for diagnostics and heuristics in the compiler).
33
44
pub(super) mod combine;
5-
mod equate;
65
mod generalize;
76
mod glb;
87
mod higher_ranked;
98
mod lattice;
109
mod lub;
11-
mod sub;
10+
mod type_relating;
1211

1312
/// Whether aliases should be related structurally or not. Used
1413
/// to adjust the behavior of generalization and combine.

‎compiler/rustc_infer/src/infer/relate/sub.rs

Lines changed: 0 additions & 229 deletions
This file was deleted.
Lines changed: 326 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,326 @@
1+
use super::combine::CombineFields;
2+
use crate::infer::BoundRegionConversionTime::HigherRankedType;
3+
use crate::infer::{
4+
DefineOpaqueTypes, ObligationEmittingRelation, StructurallyRelateAliases, SubregionOrigin,
5+
};
6+
use crate::traits::{Obligation, PredicateObligations};
7+
8+
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
9+
use rustc_middle::ty::TyVar;
10+
use rustc_middle::ty::{self, Ty, TyCtxt};
11+
use rustc_span::Span;
12+
13+
/// Enforce that `a` is equal to or a subtype of `b`.
14+
pub struct TypeRelating<'combine, 'a, 'tcx> {
15+
fields: &'combine mut CombineFields<'a, 'tcx>,
16+
structurally_relate_aliases: StructurallyRelateAliases,
17+
ambient_variance: ty::Variance,
18+
}
19+
20+
impl<'combine, 'infcx, 'tcx> TypeRelating<'combine, 'infcx, 'tcx> {
21+
pub fn new(
22+
f: &'combine mut CombineFields<'infcx, 'tcx>,
23+
structurally_relate_aliases: StructurallyRelateAliases,
24+
ambient_variance: ty::Variance,
25+
) -> TypeRelating<'combine, 'infcx, 'tcx> {
26+
TypeRelating { fields: f, structurally_relate_aliases, ambient_variance }
27+
}
28+
}
29+
30+
impl<'tcx> TypeRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
31+
fn tag(&self) -> &'static str {
32+
"TypeRelating"
33+
}
34+
35+
fn tcx(&self) -> TyCtxt<'tcx> {
36+
self.fields.infcx.tcx
37+
}
38+
39+
fn relate_with_variance<T: Relate<'tcx>>(
40+
&mut self,
41+
variance: ty::Variance,
42+
_info: ty::VarianceDiagInfo<'tcx>,
43+
a: T,
44+
b: T,
45+
) -> RelateResult<'tcx, T> {
46+
let old_ambient_variance = self.ambient_variance;
47+
self.ambient_variance = self.ambient_variance.xform(variance);
48+
debug!(?self.ambient_variance, "new ambient variance");
49+
50+
let r = if self.ambient_variance == ty::Bivariant { Ok(a) } else { self.relate(a, b) };
51+
52+
self.ambient_variance = old_ambient_variance;
53+
r
54+
}
55+
56+
#[instrument(skip(self), level = "debug")]
57+
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
58+
if a == b {
59+
return Ok(a);
60+
}
61+
62+
let infcx = self.fields.infcx;
63+
let a = infcx.inner.borrow_mut().type_variables().replace_if_possible(a);
64+
let b = infcx.inner.borrow_mut().type_variables().replace_if_possible(b);
65+
66+
match (a.kind(), b.kind()) {
67+
(&ty::Infer(TyVar(a_id)), &ty::Infer(TyVar(b_id))) => {
68+
match self.ambient_variance {
69+
ty::Covariant => {
70+
// can't make progress on `A <: B` if both A and B are
71+
// type variables, so record an obligation.
72+
self.fields.obligations.push(Obligation::new(
73+
self.tcx(),
74+
self.fields.trace.cause.clone(),
75+
self.fields.param_env,
76+
ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
77+
a_is_expected: true,
78+
a,
79+
b,
80+
})),
81+
));
82+
}
83+
ty::Contravariant => {
84+
// can't make progress on `B <: A` if both A and B are
85+
// type variables, so record an obligation.
86+
self.fields.obligations.push(Obligation::new(
87+
self.tcx(),
88+
self.fields.trace.cause.clone(),
89+
self.fields.param_env,
90+
ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
91+
a_is_expected: false,
92+
a: b,
93+
b: a,
94+
})),
95+
));
96+
}
97+
ty::Invariant => {
98+
infcx.inner.borrow_mut().type_variables().equate(a_id, b_id);
99+
}
100+
ty::Bivariant => {
101+
unreachable!("Expected bivariance to be handled in relate_with_variance")
102+
}
103+
}
104+
}
105+
106+
(&ty::Infer(TyVar(a_vid)), _) => {
107+
infcx.instantiate_ty_var(self, true, a_vid, self.ambient_variance, b)?;
108+
}
109+
(_, &ty::Infer(TyVar(b_vid))) => {
110+
infcx.instantiate_ty_var(
111+
self,
112+
false,
113+
b_vid,
114+
self.ambient_variance.xform(ty::Contravariant),
115+
a,
116+
)?;
117+
}
118+
119+
(&ty::Error(e), _) | (_, &ty::Error(e)) => {
120+
infcx.set_tainted_by_errors(e);
121+
return Ok(Ty::new_error(self.tcx(), e));
122+
}
123+
124+
(
125+
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
126+
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
127+
) if a_def_id == b_def_id => {
128+
infcx.super_combine_tys(self, a, b)?;
129+
}
130+
131+
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
132+
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
133+
if self.fields.define_opaque_types == DefineOpaqueTypes::Yes
134+
&& def_id.is_local()
135+
&& !infcx.next_trait_solver() =>
136+
{
137+
self.fields.obligations.extend(
138+
infcx
139+
.handle_opaque_type(a, b, &self.fields.trace.cause, self.param_env())?
140+
.obligations,
141+
);
142+
}
143+
144+
_ => {
145+
infcx.super_combine_tys(self, a, b)?;
146+
}
147+
}
148+
149+
Ok(a)
150+
}
151+
152+
fn regions(
153+
&mut self,
154+
a: ty::Region<'tcx>,
155+
b: ty::Region<'tcx>,
156+
) -> RelateResult<'tcx, ty::Region<'tcx>> {
157+
debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
158+
let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
159+
160+
match self.ambient_variance {
161+
// Subtype(&'a u8, &'b u8) => Outlives('a: 'b) => SubRegion('b, 'a)
162+
ty::Covariant => {
163+
self.fields
164+
.infcx
165+
.inner
166+
.borrow_mut()
167+
.unwrap_region_constraints()
168+
.make_subregion(origin, b, a);
169+
}
170+
// Suptype(&'a u8, &'b u8) => Outlives('b: 'a) => SubRegion('a, 'b)
171+
ty::Contravariant => {
172+
self.fields
173+
.infcx
174+
.inner
175+
.borrow_mut()
176+
.unwrap_region_constraints()
177+
.make_subregion(origin, a, b);
178+
}
179+
ty::Invariant => {
180+
self.fields
181+
.infcx
182+
.inner
183+
.borrow_mut()
184+
.unwrap_region_constraints()
185+
.make_eqregion(origin, a, b);
186+
}
187+
ty::Bivariant => {
188+
unreachable!("Expected bivariance to be handled in relate_with_variance")
189+
}
190+
}
191+
192+
Ok(a)
193+
}
194+
195+
fn consts(
196+
&mut self,
197+
a: ty::Const<'tcx>,
198+
b: ty::Const<'tcx>,
199+
) -> RelateResult<'tcx, ty::Const<'tcx>> {
200+
self.fields.infcx.super_combine_consts(self, a, b)
201+
}
202+
203+
fn binders<T>(
204+
&mut self,
205+
a: ty::Binder<'tcx, T>,
206+
b: ty::Binder<'tcx, T>,
207+
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
208+
where
209+
T: Relate<'tcx>,
210+
{
211+
if a == b {
212+
// Do nothing
213+
} else if let Some(a) = a.no_bound_vars()
214+
&& let Some(b) = b.no_bound_vars()
215+
{
216+
self.relate(a, b)?;
217+
} else {
218+
let span = self.fields.trace.cause.span;
219+
let infcx = self.fields.infcx;
220+
221+
match self.ambient_variance {
222+
// Checks whether `for<..> sub <: for<..> sup` holds.
223+
//
224+
// For this to hold, **all** instantiations of the super type
225+
// have to be a super type of **at least one** instantiation of
226+
// the subtype.
227+
//
228+
// This is implemented by first entering a new universe.
229+
// We then replace all bound variables in `sup` with placeholders,
230+
// and all bound variables in `sub` with inference vars.
231+
// We can then just relate the two resulting types as normal.
232+
//
233+
// Note: this is a subtle algorithm. For a full explanation, please see
234+
// the [rustc dev guide][rd]
235+
//
236+
// [rd]: https://rustc-dev-guide.rust-lang.org/borrow_check/region_inference/placeholders_and_universes.html
237+
ty::Covariant => {
238+
infcx.enter_forall(b, |b| {
239+
let a = infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, a);
240+
self.relate(a, b)
241+
})?;
242+
}
243+
ty::Contravariant => {
244+
infcx.enter_forall(a, |a| {
245+
let b = infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, b);
246+
self.relate(a, b)
247+
})?;
248+
}
249+
250+
// When **equating** binders, we check that there is a 1-to-1
251+
// correspondence between the bound vars in both types.
252+
//
253+
// We do so by separately instantiating one of the binders with
254+
// placeholders and the other with inference variables and then
255+
// equating the instantiated types.
256+
//
257+
// We want `for<..> A == for<..> B` -- therefore we want
258+
// `exists<..> A == for<..> B` and `exists<..> B == for<..> A`.
259+
// Check if `exists<..> A == for<..> B`
260+
ty::Invariant => {
261+
infcx.enter_forall(b, |b| {
262+
let a = infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, a);
263+
self.relate(a, b)
264+
})?;
265+
266+
// Check if `exists<..> B == for<..> A`.
267+
infcx.enter_forall(a, |a| {
268+
let b = infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, b);
269+
self.relate(a, b)
270+
})?;
271+
}
272+
ty::Bivariant => {
273+
unreachable!("Expected bivariance to be handled in relate_with_variance")
274+
}
275+
}
276+
}
277+
278+
Ok(a)
279+
}
280+
}
281+
282+
impl<'tcx> ObligationEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
283+
fn span(&self) -> Span {
284+
self.fields.trace.span()
285+
}
286+
287+
fn param_env(&self) -> ty::ParamEnv<'tcx> {
288+
self.fields.param_env
289+
}
290+
291+
fn structurally_relate_aliases(&self) -> StructurallyRelateAliases {
292+
self.structurally_relate_aliases
293+
}
294+
295+
fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>) {
296+
self.fields.register_predicates(obligations);
297+
}
298+
299+
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
300+
self.fields.register_obligations(obligations);
301+
}
302+
303+
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
304+
self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
305+
ty::Variance::Covariant => ty::PredicateKind::AliasRelate(
306+
a.into(),
307+
b.into(),
308+
ty::AliasRelationDirection::Subtype,
309+
),
310+
// a :> b is b <: a
311+
ty::Variance::Contravariant => ty::PredicateKind::AliasRelate(
312+
b.into(),
313+
a.into(),
314+
ty::AliasRelationDirection::Subtype,
315+
),
316+
ty::Variance::Invariant => ty::PredicateKind::AliasRelate(
317+
a.into(),
318+
b.into(),
319+
ty::AliasRelationDirection::Equate,
320+
),
321+
ty::Variance::Bivariant => {
322+
unreachable!("Expected bivariance to be handled in relate_with_variance")
323+
}
324+
})]);
325+
}
326+
}

‎compiler/rustc_middle/src/ty/_match.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> {
3737
self.tcx
3838
}
3939

40-
fn a_is_expected(&self) -> bool {
41-
true
42-
} // irrelevant
43-
4440
fn relate_with_variance<T: Relate<'tcx>>(
4541
&mut self,
4642
_: ty::Variance,
@@ -75,7 +71,7 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> {
7571
) => Ok(a),
7672

7773
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
78-
Err(TypeError::Sorts(relate::expected_found(self, a, b)))
74+
Err(TypeError::Sorts(relate::expected_found(a, b)))
7975
}
8076

8177
(&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(Ty::new_error(self.tcx(), guar)),
@@ -100,7 +96,7 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> {
10096
}
10197

10298
(ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => {
103-
return Err(TypeError::ConstMismatch(relate::expected_found(self, a, b)));
99+
return Err(TypeError::ConstMismatch(relate::expected_found(a, b)));
104100
}
105101

106102
_ => {}

‎compiler/rustc_middle/src/ty/relate.rs

Lines changed: 31 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,12 @@ use std::iter;
1515

1616
pub type RelateResult<'tcx, T> = Result<T, TypeError<'tcx>>;
1717

18-
#[derive(Clone, Debug)]
19-
pub enum Cause {
20-
ExistentialRegionBound, // relating an existential region bound
21-
}
22-
2318
pub trait TypeRelation<'tcx>: Sized {
2419
fn tcx(&self) -> TyCtxt<'tcx>;
2520

2621
/// Returns a static string we can use for printouts.
2722
fn tag(&self) -> &'static str;
2823

29-
/// Returns `true` if the value `a` is the "expected" type in the
30-
/// relation. Just affects error messages.
31-
fn a_is_expected(&self) -> bool;
32-
33-
fn with_cause<F, R>(&mut self, _cause: Cause, f: F) -> R
34-
where
35-
F: FnOnce(&mut Self) -> R,
36-
{
37-
f(self)
38-
}
39-
4024
/// Generic relation routine suitable for most anything.
4125
fn relate<T: Relate<'tcx>>(&mut self, a: T, b: T) -> RelateResult<'tcx, T> {
4226
Relate::relate(self, a, b)
@@ -178,11 +162,7 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
178162
let tcx = relation.tcx();
179163

180164
if a.c_variadic != b.c_variadic {
181-
return Err(TypeError::VariadicMismatch(expected_found(
182-
relation,
183-
a.c_variadic,
184-
b.c_variadic,
185-
)));
165+
return Err(TypeError::VariadicMismatch(expected_found(a.c_variadic, b.c_variadic)));
186166
}
187167
let unsafety = relation.relate(a.unsafety, b.unsafety)?;
188168
let abi = relation.relate(a.abi, b.abi)?;
@@ -227,39 +207,31 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
227207

228208
impl<'tcx> Relate<'tcx> for ty::BoundConstness {
229209
fn relate<R: TypeRelation<'tcx>>(
230-
relation: &mut R,
210+
_relation: &mut R,
231211
a: ty::BoundConstness,
232212
b: ty::BoundConstness,
233213
) -> RelateResult<'tcx, ty::BoundConstness> {
234-
if a != b {
235-
Err(TypeError::ConstnessMismatch(expected_found(relation, a, b)))
236-
} else {
237-
Ok(a)
238-
}
214+
if a != b { Err(TypeError::ConstnessMismatch(expected_found(a, b))) } else { Ok(a) }
239215
}
240216
}
241217

242218
impl<'tcx> Relate<'tcx> for hir::Unsafety {
243219
fn relate<R: TypeRelation<'tcx>>(
244-
relation: &mut R,
220+
_relation: &mut R,
245221
a: hir::Unsafety,
246222
b: hir::Unsafety,
247223
) -> RelateResult<'tcx, hir::Unsafety> {
248-
if a != b {
249-
Err(TypeError::UnsafetyMismatch(expected_found(relation, a, b)))
250-
} else {
251-
Ok(a)
252-
}
224+
if a != b { Err(TypeError::UnsafetyMismatch(expected_found(a, b))) } else { Ok(a) }
253225
}
254226
}
255227

256228
impl<'tcx> Relate<'tcx> for abi::Abi {
257229
fn relate<R: TypeRelation<'tcx>>(
258-
relation: &mut R,
230+
_relation: &mut R,
259231
a: abi::Abi,
260232
b: abi::Abi,
261233
) -> RelateResult<'tcx, abi::Abi> {
262-
if a == b { Ok(a) } else { Err(TypeError::AbiMismatch(expected_found(relation, a, b))) }
234+
if a == b { Ok(a) } else { Err(TypeError::AbiMismatch(expected_found(a, b))) }
263235
}
264236
}
265237

@@ -270,7 +242,7 @@ impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> {
270242
b: ty::AliasTy<'tcx>,
271243
) -> RelateResult<'tcx, ty::AliasTy<'tcx>> {
272244
if a.def_id != b.def_id {
273-
Err(TypeError::ProjectionMismatched(expected_found(relation, a.def_id, b.def_id)))
245+
Err(TypeError::ProjectionMismatched(expected_found(a.def_id, b.def_id)))
274246
} else {
275247
let args = match relation.tcx().def_kind(a.def_id) {
276248
DefKind::OpaqueTy => relate_args_with_variances(
@@ -298,7 +270,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
298270
b: ty::ExistentialProjection<'tcx>,
299271
) -> RelateResult<'tcx, ty::ExistentialProjection<'tcx>> {
300272
if a.def_id != b.def_id {
301-
Err(TypeError::ProjectionMismatched(expected_found(relation, a.def_id, b.def_id)))
273+
Err(TypeError::ProjectionMismatched(expected_found(a.def_id, b.def_id)))
302274
} else {
303275
let term = relation.relate_with_variance(
304276
ty::Invariant,
@@ -325,7 +297,7 @@ impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
325297
) -> RelateResult<'tcx, ty::TraitRef<'tcx>> {
326298
// Different traits cannot be related.
327299
if a.def_id != b.def_id {
328-
Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
300+
Err(TypeError::Traits(expected_found(a.def_id, b.def_id)))
329301
} else {
330302
let args = relate_args_invariantly(relation, a.args, b.args)?;
331303
Ok(ty::TraitRef::new(relation.tcx(), a.def_id, args))
@@ -341,7 +313,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
341313
) -> RelateResult<'tcx, ty::ExistentialTraitRef<'tcx>> {
342314
// Different traits cannot be related.
343315
if a.def_id != b.def_id {
344-
Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
316+
Err(TypeError::Traits(expected_found(a.def_id, b.def_id)))
345317
} else {
346318
let args = relate_args_invariantly(relation, a.args, b.args)?;
347319
Ok(ty::ExistentialTraitRef { def_id: a.def_id, args })
@@ -452,10 +424,12 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
452424
(&ty::Dynamic(a_obj, a_region, a_repr), &ty::Dynamic(b_obj, b_region, b_repr))
453425
if a_repr == b_repr =>
454426
{
455-
let region_bound = relation.with_cause(Cause::ExistentialRegionBound, |relation| {
456-
relation.relate(a_region, b_region)
457-
})?;
458-
Ok(Ty::new_dynamic(tcx, relation.relate(a_obj, b_obj)?, region_bound, a_repr))
427+
Ok(Ty::new_dynamic(
428+
tcx,
429+
relation.relate(a_obj, b_obj)?,
430+
relation.relate(a_region, b_region)?,
431+
a_repr,
432+
))
459433
}
460434

461435
(&ty::Coroutine(a_id, a_args), &ty::Coroutine(b_id, b_args)) if a_id == b_id => {
@@ -515,9 +489,9 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
515489
let sz_b = sz_b.try_to_target_usize(tcx);
516490

517491
match (sz_a, sz_b) {
518-
(Some(sz_a_val), Some(sz_b_val)) if sz_a_val != sz_b_val => Err(
519-
TypeError::FixedArraySize(expected_found(relation, sz_a_val, sz_b_val)),
520-
),
492+
(Some(sz_a_val), Some(sz_b_val)) if sz_a_val != sz_b_val => {
493+
Err(TypeError::FixedArraySize(expected_found(sz_a_val, sz_b_val)))
494+
}
521495
_ => Err(err),
522496
}
523497
}
@@ -536,9 +510,9 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
536510
iter::zip(as_, bs).map(|(a, b)| relation.relate(a, b)),
537511
)?)
538512
} else if !(as_.is_empty() || bs.is_empty()) {
539-
Err(TypeError::TupleSize(expected_found(relation, as_.len(), bs.len())))
513+
Err(TypeError::TupleSize(expected_found(as_.len(), bs.len())))
540514
} else {
541-
Err(TypeError::Sorts(expected_found(relation, a, b)))
515+
Err(TypeError::Sorts(expected_found(a, b)))
542516
}
543517
}
544518

@@ -559,7 +533,7 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
559533
Ok(Ty::new_alias(tcx, a_kind, alias_ty))
560534
}
561535

562-
_ => Err(TypeError::Sorts(expected_found(relation, a, b))),
536+
_ => Err(TypeError::Sorts(expected_found(a, b))),
563537
}
564538
}
565539

@@ -657,13 +631,13 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>(
657631
let related_args = tcx.mk_const_list(&related_args);
658632
Expr::FunctionCall(func, related_args)
659633
}
660-
_ => return Err(TypeError::ConstMismatch(expected_found(r, a, b))),
634+
_ => return Err(TypeError::ConstMismatch(expected_found(a, b))),
661635
};
662636
return Ok(ty::Const::new_expr(tcx, expr, a.ty()));
663637
}
664638
_ => false,
665639
};
666-
if is_match { Ok(a) } else { Err(TypeError::ConstMismatch(expected_found(relation, a, b))) }
640+
if is_match { Ok(a) } else { Err(TypeError::ConstMismatch(expected_found(a, b))) }
667641
}
668642

669643
impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
@@ -685,7 +659,7 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
685659
b_v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
686660
b_v.dedup();
687661
if a_v.len() != b_v.len() {
688-
return Err(TypeError::ExistentialMismatch(expected_found(relation, a, b)));
662+
return Err(TypeError::ExistentialMismatch(expected_found(a, b)));
689663
}
690664

691665
let v = iter::zip(a_v, b_v).map(|(ep_a, ep_b)| {
@@ -697,7 +671,7 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
697671
relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(),
698672
))),
699673
(AutoTrait(a), AutoTrait(b)) if a == b => Ok(ep_a.rebind(AutoTrait(a))),
700-
_ => Err(TypeError::ExistentialMismatch(expected_found(relation, a, b))),
674+
_ => Err(TypeError::ExistentialMismatch(expected_found(a, b))),
701675
}
702676
});
703677
tcx.mk_poly_existential_predicates_from_iter(v)
@@ -797,15 +771,11 @@ impl<'tcx> Relate<'tcx> for GenericArg<'tcx> {
797771

798772
impl<'tcx> Relate<'tcx> for ty::ImplPolarity {
799773
fn relate<R: TypeRelation<'tcx>>(
800-
relation: &mut R,
774+
_relation: &mut R,
801775
a: ty::ImplPolarity,
802776
b: ty::ImplPolarity,
803777
) -> RelateResult<'tcx, ty::ImplPolarity> {
804-
if a != b {
805-
Err(TypeError::PolarityMismatch(expected_found(relation, a, b)))
806-
} else {
807-
Ok(a)
808-
}
778+
if a != b { Err(TypeError::PolarityMismatch(expected_found(a, b))) } else { Ok(a) }
809779
}
810780
}
811781

@@ -839,9 +809,6 @@ impl<'tcx> Relate<'tcx> for Term<'tcx> {
839809
///////////////////////////////////////////////////////////////////////////
840810
// Error handling
841811

842-
pub fn expected_found<'tcx, R, T>(relation: &mut R, a: T, b: T) -> ExpectedFound<T>
843-
where
844-
R: TypeRelation<'tcx>,
845-
{
846-
ExpectedFound::new(relation.a_is_expected(), a, b)
812+
pub fn expected_found<T>(a: T, b: T) -> ExpectedFound<T> {
813+
ExpectedFound::new(true, a, b)
847814
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
904904
&ObligationCause::dummy(),
905905
param_env,
906906
hidden_ty,
907-
true,
908907
&mut obligations,
909908
)?;
910909
self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));

‎compiler/rustc_trait_selection/src/traits/engine.rs

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -116,24 +116,6 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
116116
self.infcx.at(cause, param_env).deeply_normalize(value, &mut **self.engine.borrow_mut())
117117
}
118118

119-
/// Makes `expected <: actual`.
120-
pub fn eq_exp<T>(
121-
&self,
122-
cause: &ObligationCause<'tcx>,
123-
param_env: ty::ParamEnv<'tcx>,
124-
a_is_expected: bool,
125-
a: T,
126-
b: T,
127-
) -> Result<(), TypeError<'tcx>>
128-
where
129-
T: ToTrace<'tcx>,
130-
{
131-
self.infcx
132-
.at(cause, param_env)
133-
.eq_exp(DefineOpaqueTypes::Yes, a_is_expected, a, b)
134-
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
135-
}
136-
137119
pub fn eq<T: ToTrace<'tcx>>(
138120
&self,
139121
cause: &ObligationCause<'tcx>,

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,20 +1528,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
15281528
| ObligationCauseCode::Coercion { .. }
15291529
);
15301530

1531+
let (expected, actual) = if is_normalized_term_expected {
1532+
(normalized_term, data.term)
1533+
} else {
1534+
(data.term, normalized_term)
1535+
};
1536+
15311537
// constrain inference variables a bit more to nested obligations from normalize so
15321538
// we can have more helpful errors.
15331539
//
15341540
// we intentionally drop errors from normalization here,
15351541
// since the normalization is just done to improve the error message.
15361542
let _ = ocx.select_where_possible();
15371543

1538-
if let Err(new_err) = ocx.eq_exp(
1539-
&obligation.cause,
1540-
obligation.param_env,
1541-
is_normalized_term_expected,
1542-
normalized_term,
1543-
data.term,
1544-
) {
1544+
if let Err(new_err) =
1545+
ocx.eq(&obligation.cause, obligation.param_env, expected, actual)
1546+
{
15451547
(Some((data, is_normalized_term_expected, normalized_term, data.term)), new_err)
15461548
} else {
15471549
(None, error.err)

‎tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ fn main() {
1313
}
1414

1515
fn weird0() -> impl Sized + !Sized {}
16-
//~^ ERROR type mismatch resolving `() == impl !Sized + Sized`
16+
//~^ ERROR type mismatch resolving `impl !Sized + Sized == ()`
1717
fn weird1() -> impl !Sized + Sized {}
18-
//~^ ERROR type mismatch resolving `() == impl !Sized + Sized`
18+
//~^ ERROR type mismatch resolving `impl !Sized + Sized == ()`
1919
fn weird2() -> impl !Sized {}
20-
//~^ ERROR type mismatch resolving `() == impl !Sized`
20+
//~^ ERROR type mismatch resolving `impl !Sized == ()`

‎tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
error[E0271]: type mismatch resolving `() == impl !Sized + Sized`
1+
error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
22
--> $DIR/opaque-type-unsatisfied-bound.rs:15:16
33
|
44
LL | fn weird0() -> impl Sized + !Sized {}
55
| ^^^^^^^^^^^^^^^^^^^ types differ
66

7-
error[E0271]: type mismatch resolving `() == impl !Sized + Sized`
7+
error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
88
--> $DIR/opaque-type-unsatisfied-bound.rs:17:16
99
|
1010
LL | fn weird1() -> impl !Sized + Sized {}
1111
| ^^^^^^^^^^^^^^^^^^^ types differ
1212

13-
error[E0271]: type mismatch resolving `() == impl !Sized`
13+
error[E0271]: type mismatch resolving `impl !Sized == ()`
1414
--> $DIR/opaque-type-unsatisfied-bound.rs:19:16
1515
|
1616
LL | fn weird2() -> impl !Sized {}

‎tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
#![feature(negative_bounds, unboxed_closures)]
44

55
fn produce() -> impl !Fn<(u32,)> {}
6-
//~^ ERROR type mismatch resolving `() == impl !Fn<(u32,)>`
6+
//~^ ERROR type mismatch resolving `impl !Fn<(u32,)> == ()`
77

88
fn main() {}

‎tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0271]: type mismatch resolving `() == impl !Fn<(u32,)>`
1+
error[E0271]: type mismatch resolving `impl !Fn<(u32,)> == ()`
22
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
33
|
44
LL | fn produce() -> impl !Fn<(u32,)> {}

‎tests/ui/type-alias-impl-trait/itiat-allow-nested-closures.bad.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ LL | let _: i32 = closure();
88
| --- ^^^^^^^^^ expected `i32`, found opaque type
99
| |
1010
| expected due to this
11+
|
12+
= note: expected type `i32`
13+
found opaque type `<() as Foo>::Assoc`
1114

1215
error[E0308]: mismatched types
1316
--> $DIR/itiat-allow-nested-closures.rs:22:9

0 commit comments

Comments
 (0)
Please sign in to comment.