Rollup merge of #131795 - compiler-errors:expectation, r=Nadrieril

Stop inverting expectation in normalization errors

We have some funky special case logic to invert the expectation and actual type for normalization errors depending on their cause code. IMO most of the error messages get better, except for `try {}` blocks' type expectations. I think that these need to be special cased in some other way, rather than via this hack.

Fixes #131763
This commit is contained in:
Matthias Krüger 2024-10-19 22:00:57 +02:00 committed by GitHub
commit 559f8ce726
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 48 additions and 82 deletions

View file

@ -1277,19 +1277,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let normalized_term =
ocx.normalize(&obligation.cause, obligation.param_env, unnormalized_term);
let is_normalized_term_expected = !matches!(
obligation.cause.code().peel_derives(),
ObligationCauseCode::WhereClause(..)
| ObligationCauseCode::WhereClauseInExpr(..)
| 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
// we can have more helpful errors.
//
@ -1298,12 +1285,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let _ = ocx.select_where_possible();
if let Err(new_err) =
ocx.eq(&obligation.cause, obligation.param_env, expected, actual)
ocx.eq(&obligation.cause, obligation.param_env, data.term, normalized_term)
{
(
Some((
data.projection_term,
is_normalized_term_expected,
false,
self.resolve_vars_if_possible(normalized_term),
data.term,
)),
@ -1444,12 +1431,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
&mut diag,
&obligation.cause,
secondary_span,
values.map(|(_, is_normalized_ty_expected, normalized_ty, expected_ty)| {
infer::ValuePairs::Terms(ExpectedFound::new(
is_normalized_ty_expected,
normalized_ty,
expected_ty,
))
values.map(|(_, _, normalized_ty, expected_ty)| {
infer::ValuePairs::Terms(ExpectedFound::new(true, expected_ty, normalized_ty))
}),
err,
false,

View file

@ -2,18 +2,16 @@ error[E0271]: type mismatch resolving `<impl Bar as Foo>::Item == i32`
--> $DIR/impl-trait-return-missing-constraint.rs:25:13
|
LL | fn bar() -> impl Bar {
| -------- the expected opaque type
| -------- the found opaque type
...
LL | fn baz() -> impl Bar<Item = i32> {
| ^^^^^^^^^^^^^^^^^^^^ expected associated type, found `i32`
| ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found associated type
LL |
LL | bar()
| ----- return type was inferred to be `impl Bar` here
|
= note: expected associated type `<impl Bar as Foo>::Item`
found type `i32`
= help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i32` or calling a method that returns `<impl Bar as Foo>::Item`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
= note: expected type `i32`
found associated type `<impl Bar as Foo>::Item`
help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i32`
|
LL | fn bar() -> impl Bar<Item = i32> {

View file

@ -22,10 +22,10 @@ error[E0271]: type mismatch resolving `<{coroutine@$DIR/type-mismatch-signature-
--> $DIR/type-mismatch-signature-deduction.rs:5:13
|
LL | fn foo() -> impl Coroutine<Return = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Result<{integer}, _>`, found `i32`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `Result<{integer}, _>`
|
= note: expected enum `Result<{integer}, _>`
found type `i32`
= note: expected type `i32`
found enum `Result<{integer}, _>`
error: aborting due to 2 previous errors

View file

@ -29,10 +29,7 @@ error[E0271]: type mismatch resolving `<SelectInt as Expression>::SqlType == Tex
--> $DIR/as_expression.rs:57:5
|
LL | SelectInt.check("bar");
| ^^^^^^^^^^^^^^^^^^^^^^ expected `Integer`, found `Text`
|
= note: expected struct `Integer`
found struct `Text`
| ^^^^^^^^^^^^^^^^^^^^^^ expected `Text`, found `Integer`
error: aborting due to 3 previous errors

View file

@ -7,13 +7,13 @@ LL |
LL | Foo(())
| ------- return type was inferred to be `Foo<()>` here
|
note: expected this to be `()`
note: expected this to be `<T as impl_trait::Trait>::Assoc`
--> $DIR/bound-normalization-fail.rs:14:19
|
LL | type Output = T;
| ^
= note: expected unit type `()`
found associated type `<T as impl_trait::Trait>::Assoc`
= note: expected associated type `<T as impl_trait::Trait>::Assoc`
found unit type `()`
help: consider constraining the associated type `<T as impl_trait::Trait>::Assoc` to `()`
|
LL | fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {
@ -28,13 +28,13 @@ LL |
LL | Foo(())
| ------- return type was inferred to be `Foo<()>` here
|
note: expected this to be `()`
note: expected this to be `<T as lifetimes::Trait<'a>>::Assoc`
--> $DIR/bound-normalization-fail.rs:14:19
|
LL | type Output = T;
| ^
= note: expected unit type `()`
found associated type `<T as lifetimes::Trait<'a>>::Assoc`
= note: expected associated type `<T as lifetimes::Trait<'a>>::Assoc`
found unit type `()`
help: consider constraining the associated type `<T as lifetimes::Trait<'a>>::Assoc` to `()`
|
LL | fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {

View file

@ -2,7 +2,7 @@ error[E0271]: type mismatch resolving `<&i32 as Deref>::Target == String`
--> $DIR/default-body-type-err.rs:4:22
|
LL | fn lol(&self) -> impl Deref<Target = String> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `String`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `String`, found `i32`
LL |
LL | &1i32
| ----- return type was inferred to be `&i32` here

View file

@ -16,7 +16,7 @@ error[E0271]: expected `{async block@$DIR/issue-78722-2.rs:13:13: 13:18}` to be
--> $DIR/issue-78722-2.rs:11:30
|
LL | fn concrete_use() -> F {
| ^ expected `()`, found `u8`
| ^ expected `u8`, found `()`
error: aborting due to 2 previous errors

View file

@ -12,7 +12,7 @@ error[E0271]: expected `{async block@$DIR/issue-78722.rs:10:13: 10:18}` to be a
--> $DIR/issue-78722.rs:8:30
|
LL | fn concrete_use() -> F {
| ^ expected `()`, found `u8`
| ^ expected `u8`, found `()`
error: aborting due to 2 previous errors

View file

@ -4,7 +4,7 @@ error[E0271]: type mismatch resolving `<() as Super>::Assoc == ()`
LL | fn test() -> impl Test {
| ^^^^^^^^^ type mismatch resolving `<() as Super>::Assoc == ()`
|
note: expected this to be `u8`
note: expected this to be `()`
--> $DIR/projection-mismatch-in-impl-where-clause.rs:6:18
|
LL | type Assoc = u8;

View file

@ -20,10 +20,10 @@ error[E0271]: expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but
--> $DIR/issue-33941.rs:6:14
|
LL | for _ in HashMap::new().iter().cloned() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(&_, &_)`, found `&_`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&_`, found `(&_, &_)`
|
= note: expected tuple `(&_, &_)`
found reference `&_`
= note: expected reference `&_`
found tuple `(&_, &_)`
= note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `Iterator`
= note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `IntoIterator`

View file

@ -2,10 +2,10 @@ error[E0271]: type mismatch resolving `<Rc<Apple> as Deref>::Target == Rc<Apple>
--> $DIR/issue-67039-unsound-pin-partialeq.rs:25:29
|
LL | let _ = Pin::new(Apple) == Rc::pin(Apple);
| ^^ expected `Apple`, found `Rc<Apple>`
| ^^ expected `Rc<Apple>`, found `Apple`
|
= note: expected struct `Apple`
found struct `Rc<Apple>`
= note: expected struct `Rc<Apple>`
found struct `Apple`
= note: required for `Pin<Apple>` to implement `PartialEq<Pin<Rc<Apple>>>`
error: aborting due to 1 previous error

View file

@ -2,7 +2,7 @@ error[E0271]: expected `foo` to be a fn item that returns `i32`, but it returns
--> $DIR/issue-106991.rs:5:13
|
LL | fn bar() -> impl Iterator<Item = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `i32`
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `()`
|
= note: required for `Map<std::slice::IterMut<'_, Vec<u8>>, for<'a> fn(&'a mut Vec<u8>) {foo}>` to implement `Iterator`

View file

@ -8,14 +8,14 @@ error[E0271]: expected `Box<dyn Iterator>` to be an iterator that yields `u32`,
--> $DIR/trait-hidden-method.rs:3:32
|
LL | pub fn i_can_has_iterator() -> impl Iterator<Item = u32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `u32`
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u32`, found associated type
...
LL | Box::new(1..=10) as Box<dyn Iterator>
| ------------------------------------- return type was inferred to be `Box<dyn Iterator>` here
|
= note: expected associated type `<dyn Iterator as Iterator>::Item`
found type `u32`
= help: consider constraining the associated type `<dyn Iterator as Iterator>::Item` to `u32` or calling a method that returns `<dyn Iterator as Iterator>::Item`
= note: expected type `u32`
found associated type `<dyn Iterator as Iterator>::Item`
= help: consider constraining the associated type `<dyn Iterator as Iterator>::Item` to `u32`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
error: aborting due to 2 previous errors

View file

@ -2,12 +2,10 @@ error[E0271]: expected `{async block@$DIR/async.rs:12:17: 12:22}` to be a future
--> $DIR/async.rs:12:17
|
LL | needs_async(async {});
| ----------- ^^^^^^^^ expected `()`, found `i32`
| ----------- ^^^^^^^^ expected `i32`, found `()`
| |
| required by a bound introduced by this call
|
= note: expected unit type `()`
found type `i32`
note: required by a bound in `needs_async`
--> $DIR/async.rs:8:31
|

View file

@ -2,19 +2,14 @@ error[E0271]: type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::
--> $DIR/more-object-bound.rs:12:5
|
LL | fn transmute<A, B>(x: A) -> B {
| - -
| | |
| | expected type parameter
| | found type parameter
| - - expected type parameter
| |
| found type parameter
| expected type parameter
LL | foo::<A, B, dyn Trait<A = A, B = B>>(x)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `A`, found type parameter `B`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found type parameter `A`
|
= note: expected type parameter `A`
found type parameter `B`
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
= note: expected type parameter `B`
found type parameter `A`
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
= note: required because it appears within the type `dyn Trait<A = A, B = B>`

View file

@ -15,13 +15,13 @@ error[E0271]: type mismatch resolving `<Result<i32, i32> as Try>::Output == &str
--> $DIR/try-block-bad-type.rs:12:9
|
LL | ""
| ^^ expected `i32`, found `&str`
| ^^ expected `&str`, found `i32`
error[E0271]: type mismatch resolving `<Result<i32, i32> as Try>::Output == ()`
--> $DIR/try-block-bad-type.rs:15:39
|
LL | let res: Result<i32, i32> = try { };
| ^ expected `i32`, found `()`
| ^ expected `()`, found `i32`
error[E0277]: a `try` block must return `Result` or `Option` (or another type that implements `Try`)
--> $DIR/try-block-bad-type.rs:17:25

View file

@ -2,18 +2,13 @@ error[E0271]: type mismatch resolving `<Option<f32> as Try>::Output == {integer}
--> $DIR/try-block-type-error.rs:10:9
|
LL | 42
| ^^ expected `f32`, found integer
|
help: use a float literal
|
LL | 42.0
| ++
| ^^ expected integer, found `f32`
error[E0271]: type mismatch resolving `<Option<i32> as Try>::Output == ()`
--> $DIR/try-block-type-error.rs:16:5
|
LL | };
| ^ expected `i32`, found `()`
| ^ expected `()`, found `i32`
error: aborting due to 2 previous errors

View file

@ -2,18 +2,18 @@ error[E0271]: type mismatch resolving `<() as Proj>::Assoc == i32`
--> $DIR/hidden_type_mismatch.rs:43:9
|
LL | pub type Sep = impl Sized + std::fmt::Display;
| ------------------------------ the expected opaque type
| ------------------------------ the found opaque type
...
LL | Bar { inner: 1i32, _marker: () }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<() as Proj>::Assoc == i32`
|
note: expected this to be `Sep`
note: expected this to be `i32`
--> $DIR/hidden_type_mismatch.rs:20:22
|
LL | type Assoc = sus::Sep;
| ^^^^^^^^
= note: expected opaque type `Sep`
found type `i32`
= note: expected type `i32`
found opaque type `Sep`
note: required for `Bar<()>` to implement `Copy`
--> $DIR/hidden_type_mismatch.rs:32:39
|

View file

@ -2,7 +2,7 @@ error[E0271]: type mismatch resolving `<{coroutine@$DIR/issue-94429.rs:18:9: 18:
--> $DIR/issue-94429.rs:15:26
|
LL | fn run(&mut self) -> Self::Coro {
| ^^^^^^^^^^ expected integer, found `()`
| ^^^^^^^^^^ expected `()`, found integer
error: aborting due to 1 previous error