Get rid of some sub_exp and eq_exp

This commit is contained in:
Michael Goulet 2024-02-26 19:52:52 +00:00
parent 801dd1d061
commit 61daee66a8
12 changed files with 48 additions and 60 deletions

View file

@ -1066,7 +1066,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
&cause, &cause,
param_env, param_env,
hidden_ty.ty, hidden_ty.ty,
true,
&mut obligations, &mut obligations,
)?; )?;

View file

@ -1493,6 +1493,21 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
return; return;
} }
let (expected, found) = if label_expression_as_expected {
// In the case where this is a "forced unit", like
// `break`, we want to call the `()` "expected"
// since it is implied by the syntax.
// (Note: not all force-units work this way.)"
(expression_ty, self.merged_ty())
} else {
// Otherwise, the "expected" type for error
// reporting is the current unification type,
// which is basically the LUB of the expressions
// we've seen so far (combined with the expected
// type)
(self.merged_ty(), expression_ty)
};
// Handle the actual type unification etc. // Handle the actual type unification etc.
let result = if let Some(expression) = expression { let result = if let Some(expression) = expression {
if self.pushed == 0 { if self.pushed == 0 {
@ -1540,12 +1555,11 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
// Another example is `break` with no argument expression. // Another example is `break` with no argument expression.
assert!(expression_ty.is_unit(), "if let hack without unit type"); assert!(expression_ty.is_unit(), "if let hack without unit type");
fcx.at(cause, fcx.param_env) fcx.at(cause, fcx.param_env)
.eq(
// needed for tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs // needed for tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
.eq_exp(
DefineOpaqueTypes::Yes, DefineOpaqueTypes::Yes,
label_expression_as_expected, expected,
expression_ty, found,
self.merged_ty(),
) )
.map(|infer_ok| { .map(|infer_ok| {
fcx.register_infer_ok_obligations(infer_ok); fcx.register_infer_ok_obligations(infer_ok);
@ -1579,20 +1593,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
fcx.set_tainted_by_errors( fcx.set_tainted_by_errors(
fcx.dcx().span_delayed_bug(cause.span, "coercion error but no error emitted"), fcx.dcx().span_delayed_bug(cause.span, "coercion error but no error emitted"),
); );
let (expected, found) = if label_expression_as_expected {
// In the case where this is a "forced unit", like
// `break`, we want to call the `()` "expected"
// since it is implied by the syntax.
// (Note: not all force-units work this way.)"
(expression_ty, self.merged_ty())
} else {
// Otherwise, the "expected" type for error
// reporting is the current unification type,
// which is basically the LUB of the expressions
// we've seen so far (combined with the expected
// type)
(self.merged_ty(), expression_ty)
};
let (expected, found) = fcx.resolve_vars_if_possible((expected, found)); let (expected, found) = fcx.resolve_vars_if_possible((expected, found));
let mut err; let mut err;

View file

@ -1032,7 +1032,11 @@ impl<'tcx> InferCtxt<'tcx> {
} }
self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| { self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| {
Ok(self.at(cause, param_env).sub_exp(DefineOpaqueTypes::No, a_is_expected, a, b)) if a_is_expected {
Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::No, a, b))
} else {
Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::No, b, a))
}
}) })
} }

View file

@ -102,7 +102,7 @@ impl<'tcx> InferCtxt<'tcx> {
return Ok(InferOk { value: (), obligations: vec![] }); return Ok(InferOk { value: (), obligations: vec![] });
} }
let (a, b) = if a_is_expected { (a, b) } else { (b, a) }; let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
let process = |a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected| match *a.kind() { let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => { ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => {
let def_id = def_id.expect_local(); let def_id = def_id.expect_local();
match self.defining_use_anchor { match self.defining_use_anchor {
@ -169,14 +169,13 @@ impl<'tcx> InferCtxt<'tcx> {
cause.clone(), cause.clone(),
param_env, param_env,
b, b,
a_is_expected,
)) ))
} }
_ => None, _ => None,
}; };
if let Some(res) = process(a, b, true) { if let Some(res) = process(a, b) {
res res
} else if let Some(res) = process(b, a, false) { } else if let Some(res) = process(b, a) {
res res
} else { } else {
let (a, b) = self.resolve_vars_if_possible((a, b)); let (a, b) = self.resolve_vars_if_possible((a, b));
@ -520,7 +519,6 @@ impl<'tcx> InferCtxt<'tcx> {
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
hidden_ty: Ty<'tcx>, hidden_ty: Ty<'tcx>,
a_is_expected: bool,
) -> InferResult<'tcx, ()> { ) -> InferResult<'tcx, ()> {
let mut obligations = Vec::new(); let mut obligations = Vec::new();
@ -529,7 +527,6 @@ impl<'tcx> InferCtxt<'tcx> {
&cause, &cause,
param_env, param_env,
hidden_ty, hidden_ty,
a_is_expected,
&mut obligations, &mut obligations,
)?; )?;
@ -558,7 +555,6 @@ impl<'tcx> InferCtxt<'tcx> {
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
hidden_ty: Ty<'tcx>, hidden_ty: Ty<'tcx>,
a_is_expected: bool,
obligations: &mut Vec<PredicateObligation<'tcx>>, obligations: &mut Vec<PredicateObligation<'tcx>>,
) -> Result<(), TypeError<'tcx>> { ) -> Result<(), TypeError<'tcx>> {
// Ideally, we'd get the span where *this specific `ty` came // Ideally, we'd get the span where *this specific `ty` came
@ -586,7 +582,7 @@ impl<'tcx> InferCtxt<'tcx> {
if let Some(prev) = prev { if let Some(prev) = prev {
obligations.extend( obligations.extend(
self.at(cause, param_env) self.at(cause, param_env)
.eq_exp(DefineOpaqueTypes::Yes, a_is_expected, prev, hidden_ty)? .eq(DefineOpaqueTypes::Yes, prev, hidden_ty)?
.obligations, .obligations,
); );
} }

View file

@ -904,7 +904,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
&ObligationCause::dummy(), &ObligationCause::dummy(),
param_env, param_env,
hidden_ty, hidden_ty,
true,
&mut obligations, &mut obligations,
)?; )?;
self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into())); self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));

View file

@ -116,24 +116,6 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
self.infcx.at(cause, param_env).deeply_normalize(value, &mut **self.engine.borrow_mut()) self.infcx.at(cause, param_env).deeply_normalize(value, &mut **self.engine.borrow_mut())
} }
/// Makes `expected <: actual`.
pub fn eq_exp<T>(
&self,
cause: &ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
a_is_expected: bool,
a: T,
b: T,
) -> Result<(), TypeError<'tcx>>
where
T: ToTrace<'tcx>,
{
self.infcx
.at(cause, param_env)
.eq_exp(DefineOpaqueTypes::Yes, a_is_expected, a, b)
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
}
pub fn eq<T: ToTrace<'tcx>>( pub fn eq<T: ToTrace<'tcx>>(
&self, &self,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,

View file

@ -1528,6 +1528,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
| ObligationCauseCode::Coercion { .. } | ObligationCauseCode::Coercion { .. }
); );
let (expected, actual) = if is_normalized_term_expected {
(normalized_term, data.term)
} else {
(data.term, normalized_term)
};
// constrain inference variables a bit more to nested obligations from normalize so // constrain inference variables a bit more to nested obligations from normalize so
// we can have more helpful errors. // we can have more helpful errors.
// //
@ -1535,12 +1541,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// since the normalization is just done to improve the error message. // since the normalization is just done to improve the error message.
let _ = ocx.select_where_possible(); let _ = ocx.select_where_possible();
if let Err(new_err) = ocx.eq_exp( if let Err(new_err) = ocx.eq(
&obligation.cause, &obligation.cause,
obligation.param_env, obligation.param_env,
is_normalized_term_expected, expected,
normalized_term, actual,
data.term,
) { ) {
(Some((data, is_normalized_term_expected, normalized_term, data.term)), new_err) (Some((data, is_normalized_term_expected, normalized_term, data.term)), new_err)
} else { } else {

View file

@ -13,8 +13,8 @@ fn main() {
} }
fn weird0() -> impl Sized + !Sized {} fn weird0() -> impl Sized + !Sized {}
//~^ ERROR type mismatch resolving `() == impl !Sized + Sized` //~^ ERROR type mismatch resolving `impl !Sized + Sized == ()`
fn weird1() -> impl !Sized + Sized {} fn weird1() -> impl !Sized + Sized {}
//~^ ERROR type mismatch resolving `() == impl !Sized + Sized` //~^ ERROR type mismatch resolving `impl !Sized + Sized == ()`
fn weird2() -> impl !Sized {} fn weird2() -> impl !Sized {}
//~^ ERROR type mismatch resolving `() == impl !Sized` //~^ ERROR type mismatch resolving `impl !Sized == ()`

View file

@ -1,16 +1,16 @@
error[E0271]: type mismatch resolving `() == impl !Sized + Sized` error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
--> $DIR/opaque-type-unsatisfied-bound.rs:15:16 --> $DIR/opaque-type-unsatisfied-bound.rs:15:16
| |
LL | fn weird0() -> impl Sized + !Sized {} LL | fn weird0() -> impl Sized + !Sized {}
| ^^^^^^^^^^^^^^^^^^^ types differ | ^^^^^^^^^^^^^^^^^^^ types differ
error[E0271]: type mismatch resolving `() == impl !Sized + Sized` error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
--> $DIR/opaque-type-unsatisfied-bound.rs:17:16 --> $DIR/opaque-type-unsatisfied-bound.rs:17:16
| |
LL | fn weird1() -> impl !Sized + Sized {} LL | fn weird1() -> impl !Sized + Sized {}
| ^^^^^^^^^^^^^^^^^^^ types differ | ^^^^^^^^^^^^^^^^^^^ types differ
error[E0271]: type mismatch resolving `() == impl !Sized` error[E0271]: type mismatch resolving `impl !Sized == ()`
--> $DIR/opaque-type-unsatisfied-bound.rs:19:16 --> $DIR/opaque-type-unsatisfied-bound.rs:19:16
| |
LL | fn weird2() -> impl !Sized {} LL | fn weird2() -> impl !Sized {}

View file

@ -3,6 +3,6 @@
#![feature(negative_bounds, unboxed_closures)] #![feature(negative_bounds, unboxed_closures)]
fn produce() -> impl !Fn<(u32,)> {} fn produce() -> impl !Fn<(u32,)> {}
//~^ ERROR type mismatch resolving `() == impl !Fn<(u32,)>` //~^ ERROR type mismatch resolving `impl !Fn<(u32,)> == ()`
fn main() {} fn main() {}

View file

@ -1,4 +1,4 @@
error[E0271]: type mismatch resolving `() == impl !Fn<(u32,)>` error[E0271]: type mismatch resolving `impl !Fn<(u32,)> == ()`
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17 --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
| |
LL | fn produce() -> impl !Fn<(u32,)> {} LL | fn produce() -> impl !Fn<(u32,)> {}

View file

@ -8,6 +8,9 @@ LL | let _: i32 = closure();
| --- ^^^^^^^^^ expected `i32`, found opaque type | --- ^^^^^^^^^ expected `i32`, found opaque type
| | | |
| expected due to this | expected due to this
|
= note: expected type `i32`
found opaque type `<() as Foo>::Assoc`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/itiat-allow-nested-closures.rs:22:9 --> $DIR/itiat-allow-nested-closures.rs:22:9