Skip to content

Commit

Permalink
Rollup merge of #65977 - ohadravid:fix-incorrect-diagnostics-with-an-…
Browse files Browse the repository at this point in the history
…associated-type, r=estebank

Fix incorrect diagnostics for expected type in E0271 with an associated type

With code like the following code:

```rust
#[derive(Debug)]
struct Data {}

fn do_stuff<'a>(iterator: impl Iterator<Item = &'a Data>) {
    for item in iterator {
        println!("{:?}", item)
    }
}

fn main() {
    let v = vec![Data {}];

    do_stuff(v.into_iter());
}
```

the diagnostic (in nightly & stable) wrongly complains about the expected type:

```
error[E0271]: type mismatch resolving `<std::vec::IntoIter<Data> as std::iter::Iterator>::Item == &Data`
  --> src/main.rs:15:5
   |
5  | fn do_stuff<'a>(iterator: impl Iterator<Item = &'a Data>) {
   |    --------                             --------------- required by this bound in `do_stuff`
...
15 |     do_stuff(v.into_iter());
   |     ^^^^^^^^ expected struct `Data`, found &Data
   |
   = note: expected type `Data`
              found type `&Data`
```

This PR fixes this issue by flipping the expected/actual values where appropriate, so it looks like this:

```
error[E0271]: type mismatch resolving `<std::vec::IntoIter<Data> as std::iter::Iterator>::Item == &Data`
  --> main.rs:15:5
   |
5  | fn do_stuff<'a>(iterator: impl Iterator<Item = &'a Data>) {
   |    --------                             --------------- required by this bound in `do_stuff`
...
15 |     do_stuff(v.into_iter());
   |     ^^^^^^^^ expected &Data, found struct `Data`
   |
   = note: expected type `&Data`
              found type `Data`
```

This improves the output of a lot of existing tests (check out `associated-types-binding-to-type-defined-in-supertrait`!).

The only change which I wasn't too sure about is in the test `associated-types-overridden-binding-2`, but I think it's an improvement and the underlying problem is with handling of `trait_alias`.

Fix #57226, fix #64760, fix #58092.
  • Loading branch information
tmandry authored Nov 1, 2019
2 parents 05de0d7 + 8bb5450 commit 959a563
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 51 deletions.
23 changes: 18 additions & 5 deletions src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
0,
&mut obligations
);

debug!("report_projection_error obligation.cause={:?} obligation.param_env={:?}",
obligation.cause, obligation.param_env);

debug!("report_projection_error normalized_ty={:?} data.ty={:?}",
normalized_ty, data.ty);

let is_normalized_ty_expected = match &obligation.cause.code {
ObligationCauseCode::ItemObligation(_) |
ObligationCauseCode::BindingObligation(_, _) |
ObligationCauseCode::ObjectCastObligation(_) => false,
_ => true,
};

if let Err(error) = self.at(&obligation.cause, obligation.param_env)
.eq(normalized_ty, data.ty)
.eq_exp(is_normalized_ty_expected, normalized_ty, data.ty)
{
values = Some(infer::ValuePairs::Types(ExpectedFound {
expected: normalized_ty,
found: data.ty,
}));
values = Some(infer::ValuePairs::Types(
ExpectedFound::new(is_normalized_ty_expected, normalized_ty, data.ty)));

err_buf = error;
err = &err_buf;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ LL | fn blue_car<C:Car<Color=Blue>>(c: C) {
| -------- ---------- required by this bound in `blue_car`
...
LL | fn b() { blue_car(ModelT); }
| ^^^^^^^^ expected struct `Black`, found struct `Blue`
| ^^^^^^^^ expected struct `Blue`, found struct `Black`
|
= note: expected type `Black`
found type `Blue`
= note: expected type `Blue`
found type `Black`

error[E0271]: type mismatch resolving `<ModelU as Vehicle>::Color == Black`
--> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:32:10
Expand All @@ -17,10 +17,10 @@ LL | fn black_car<C:Car<Color=Black>>(c: C) {
| --------- ----------- required by this bound in `black_car`
...
LL | fn c() { black_car(ModelU); }
| ^^^^^^^^^ expected struct `Blue`, found struct `Black`
| ^^^^^^^^^ expected struct `Black`, found struct `Blue`
|
= note: expected type `Blue`
found type `Black`
= note: expected type `Black`
found type `Blue`

error: aborting due to 2 previous errors

Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/associated-types/associated-types-eq-3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ pub fn main() {
let a = 42;
foo1(a);
//~^ ERROR type mismatch resolving
//~| expected usize, found struct `Bar`
//~| expected struct `Bar`, found usize
baz(&a);
//~^ ERROR type mismatch resolving
//~| expected usize, found struct `Bar`
//~| expected struct `Bar`, found usize
}
12 changes: 6 additions & 6 deletions src/test/ui/associated-types/associated-types-eq-3.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ LL | fn foo1<I: Foo<A=Bar>>(x: I) {
| ---- ----- required by this bound in `foo1`
...
LL | foo1(a);
| ^^^^ expected usize, found struct `Bar`
| ^^^^ expected struct `Bar`, found usize
|
= note: expected type `usize`
found type `Bar`
= note: expected type `Bar`
found type `usize`

error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
--> $DIR/associated-types-eq-3.rs:41:9
|
LL | baz(&a);
| ^^ expected usize, found struct `Bar`
| ^^ expected struct `Bar`, found usize
|
= note: expected type `usize`
found type `Bar`
= note: expected type `Bar`
found type `usize`
= note: required for the cast to the object type `dyn Foo<A = Bar>`

error: aborting due to 3 previous errors
Expand Down
12 changes: 6 additions & 6 deletions src/test/ui/associated-types/associated-types-eq-hr.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ LL | where T : for<'x> TheTrait<&'x isize, A = &'x isize>
| ------------- required by this bound in `foo`
...
LL | foo::<UintStruct>();
| ^^^^^^^^^^^^^^^^^ expected usize, found isize
| ^^^^^^^^^^^^^^^^^ expected isize, found usize
|
= note: expected type `&usize`
found type `&isize`
= note: expected type `&isize`
found type `&usize`

error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
--> $DIR/associated-types-eq-hr.rs:86:5
Expand All @@ -21,10 +21,10 @@ LL | where T : for<'x> TheTrait<&'x isize, A = &'x usize>
| ------------- required by this bound in `bar`
...
LL | bar::<IntStruct>();
| ^^^^^^^^^^^^^^^^ expected isize, found usize
| ^^^^^^^^^^^^^^^^ expected usize, found isize
|
= note: expected type `&isize`
found type `&usize`
= note: expected type `&usize`
found type `&isize`

error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
--> $DIR/associated-types-eq-hr.rs:91:17
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ LL | fn is_iterator_of<A, I: Iterator<Item=A>>(_: &I) {}
| -------------- ------ required by this bound in `is_iterator_of`
...
LL | is_iterator_of::<Option<T>, _>(&adapter);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found enum `std::option::Option`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `std::option::Option`, found type parameter
|
= note: expected type `T`
found type `std::option::Option<T>`
= note: expected type `std::option::Option<T>`
found type `T`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,28 @@ error[E0271]: type mismatch resolving `<T as Foo>::Y == i32`
--> $DIR/associated-types-multiple-types-one-trait.rs:13:5
|
LL | want_y(t);
| ^^^^^^ expected associated type, found i32
| ^^^^^^ expected i32, found associated type
...
LL | fn want_y<T:Foo<Y=i32>>(t: &T) { }
| ------ ----- required by this bound in `want_y`
|
= note: expected type `<T as Foo>::Y`
found type `i32`
= note: consider constraining the associated type `<T as Foo>::Y` to `i32` or calling a method that returns `<T as Foo>::Y`
= note: expected type `i32`
found type `<T as Foo>::Y`
= note: consider constraining the associated type `<T as Foo>::Y` to `i32`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

error[E0271]: type mismatch resolving `<T as Foo>::X == u32`
--> $DIR/associated-types-multiple-types-one-trait.rs:18:5
|
LL | want_x(t);
| ^^^^^^ expected associated type, found u32
| ^^^^^^ expected u32, found associated type
...
LL | fn want_x<T:Foo<X=u32>>(t: &T) { }
| ------ ----- required by this bound in `want_x`
|
= note: expected type `<T as Foo>::X`
found type `u32`
= note: consider constraining the associated type `<T as Foo>::X` to `u32` or calling a method that returns `<T as Foo>::X`
= note: expected type `u32`
found type `<T as Foo>::X`
= note: consider constraining the associated type `<T as Foo>::X` 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ error[E0271]: type mismatch resolving `<std::vec::IntoIter<u32> as std::iter::It
--> $DIR/associated-types-overridden-binding-2.rs:6:43
|
LL | let _: &dyn I32Iterator<Item = u32> = &vec![42].into_iter();
| ^^^^^^^^^^^^^^^^^^^^^ expected u32, found i32
| ^^^^^^^^^^^^^^^^^^^^^ expected i32, found u32
|
= note: expected type `u32`
found type `i32`
= note: expected type `i32`
found type `u32`
= note: required for the cast to the object type `dyn std::iter::Iterator<Item = u32, Item = i32>`

error: aborting due to previous error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ error[E0271]: type mismatch resolving `<impl std::future::Future as std::future:
--> $DIR/async-block-control-flow-static-semantics.rs:18:39
|
LL | let _: &dyn Future<Output = ()> = &block;
| ^^^^^^ expected u8, found ()
| ^^^^^^ expected (), found u8
|
= note: expected type `u8`
found type `()`
= note: expected type `()`
found type `u8`
= note: required for the cast to the object type `dyn std::future::Future<Output = ()>`

error[E0308]: mismatched types
Expand All @@ -59,10 +59,10 @@ error[E0271]: type mismatch resolving `<impl std::future::Future as std::future:
--> $DIR/async-block-control-flow-static-semantics.rs:27:39
|
LL | let _: &dyn Future<Output = ()> = &block;
| ^^^^^^ expected u8, found ()
| ^^^^^^ expected (), found u8
|
= note: expected type `u8`
found type `()`
= note: expected type `()`
found type `u8`
= note: required for the cast to the object type `dyn std::future::Future<Output = ()>`

error[E0308]: mismatched types
Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/error-codes/E0271.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ LL | fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
| --- ------------------ required by this bound in `foo`
...
LL | foo(3_i8);
| ^^^ expected reference, found u32
| ^^^ expected u32, found reference
|
= note: expected type `&'static str`
found type `u32`
= note: expected type `u32`
found type `&'static str`

error: aborting due to previous error

Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/issues/issue-24204.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ LL | trait Trait: Sized {
| ------------------ required by `Trait`
...
LL | fn test<T: Trait<B=i32>>(b: i32) -> T where T::A: MultiDispatch<i32> { T::new(b) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found type parameter
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found associated type
|
= note: expected type `<<T as Trait>::A as MultiDispatch<i32>>::O`
found type `T`
= note: expected type `T`
found type `<<T as Trait>::A as MultiDispatch<i32>>::O`
= note: you might be missing a type parameter or trait bound

error: aborting due to previous error
Expand Down

0 comments on commit 959a563

Please sign in to comment.