Skip to content

Commit b0696a5

Browse files
committed
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

-1
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

+7-14
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

+19-19
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

+29-62
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

-4
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

+5-2
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

0 commit comments

Comments
 (0)