Skip to content

Commit 8bb5450

Browse files
committed
Fix incorrect diagnostics for expected type in E0271 with an associated type
1 parent c553e8e commit 8bb5450

11 files changed

+64
-51
lines changed

src/librustc/traits/error_reporting.rs

+18-5
Original file line numberDiff line numberDiff line change
@@ -226,13 +226,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
226226
0,
227227
&mut obligations
228228
);
229+
230+
debug!("report_projection_error obligation.cause={:?} obligation.param_env={:?}",
231+
obligation.cause, obligation.param_env);
232+
233+
debug!("report_projection_error normalized_ty={:?} data.ty={:?}",
234+
normalized_ty, data.ty);
235+
236+
let is_normalized_ty_expected = match &obligation.cause.code {
237+
ObligationCauseCode::ItemObligation(_) |
238+
ObligationCauseCode::BindingObligation(_, _) |
239+
ObligationCauseCode::ObjectCastObligation(_) => false,
240+
_ => true,
241+
};
242+
229243
if let Err(error) = self.at(&obligation.cause, obligation.param_env)
230-
.eq(normalized_ty, data.ty)
244+
.eq_exp(is_normalized_ty_expected, normalized_ty, data.ty)
231245
{
232-
values = Some(infer::ValuePairs::Types(ExpectedFound {
233-
expected: normalized_ty,
234-
found: data.ty,
235-
}));
246+
values = Some(infer::ValuePairs::Types(
247+
ExpectedFound::new(is_normalized_ty_expected, normalized_ty, data.ty)));
248+
236249
err_buf = error;
237250
err = &err_buf;
238251
}

src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ LL | fn blue_car<C:Car<Color=Blue>>(c: C) {
55
| -------- ---------- required by this bound in `blue_car`
66
...
77
LL | fn b() { blue_car(ModelT); }
8-
| ^^^^^^^^ expected struct `Black`, found struct `Blue`
8+
| ^^^^^^^^ expected struct `Blue`, found struct `Black`
99
|
10-
= note: expected type `Black`
11-
found type `Blue`
10+
= note: expected type `Blue`
11+
found type `Black`
1212

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

2525
error: aborting due to 2 previous errors
2626

src/test/ui/associated-types/associated-types-eq-3.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ pub fn main() {
3737
let a = 42;
3838
foo1(a);
3939
//~^ ERROR type mismatch resolving
40-
//~| expected usize, found struct `Bar`
40+
//~| expected struct `Bar`, found usize
4141
baz(&a);
4242
//~^ ERROR type mismatch resolving
43-
//~| expected usize, found struct `Bar`
43+
//~| expected struct `Bar`, found usize
4444
}

src/test/ui/associated-types/associated-types-eq-3.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,19 @@ LL | fn foo1<I: Foo<A=Bar>>(x: I) {
1616
| ---- ----- required by this bound in `foo1`
1717
...
1818
LL | foo1(a);
19-
| ^^^^ expected usize, found struct `Bar`
19+
| ^^^^ expected struct `Bar`, found usize
2020
|
21-
= note: expected type `usize`
22-
found type `Bar`
21+
= note: expected type `Bar`
22+
found type `usize`
2323

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

3434
error: aborting due to 3 previous errors

src/test/ui/associated-types/associated-types-eq-hr.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ LL | where T : for<'x> TheTrait<&'x isize, A = &'x isize>
77
| ------------- required by this bound in `foo`
88
...
99
LL | foo::<UintStruct>();
10-
| ^^^^^^^^^^^^^^^^^ expected usize, found isize
10+
| ^^^^^^^^^^^^^^^^^ expected isize, found usize
1111
|
12-
= note: expected type `&usize`
13-
found type `&isize`
12+
= note: expected type `&isize`
13+
found type `&usize`
1414

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

2929
error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
3030
--> $DIR/associated-types-eq-hr.rs:91:17

src/test/ui/associated-types/associated-types-issue-20346.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ LL | fn is_iterator_of<A, I: Iterator<Item=A>>(_: &I) {}
55
| -------------- ------ required by this bound in `is_iterator_of`
66
...
77
LL | is_iterator_of::<Option<T>, _>(&adapter);
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found enum `std::option::Option`
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `std::option::Option`, found type parameter
99
|
10-
= note: expected type `T`
11-
found type `std::option::Option<T>`
10+
= note: expected type `std::option::Option<T>`
11+
found type `T`
1212
= help: type parameters must be constrained to match other types
1313
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
1414

src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr

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

1515
error[E0271]: type mismatch resolving `<T as Foo>::X == u32`
1616
--> $DIR/associated-types-multiple-types-one-trait.rs:18:5
1717
|
1818
LL | want_x(t);
19-
| ^^^^^^ expected associated type, found u32
19+
| ^^^^^^ expected u32, found associated type
2020
...
2121
LL | fn want_x<T:Foo<X=u32>>(t: &T) { }
2222
| ------ ----- required by this bound in `want_x`
2323
|
24-
= note: expected type `<T as Foo>::X`
25-
found type `u32`
26-
= note: consider constraining the associated type `<T as Foo>::X` to `u32` or calling a method that returns `<T as Foo>::X`
24+
= note: expected type `u32`
25+
found type `<T as Foo>::X`
26+
= note: consider constraining the associated type `<T as Foo>::X` to `u32`
2727
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
2828

2929
error: aborting due to 2 previous errors

src/test/ui/associated-types/associated-types-overridden-binding-2.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ error[E0271]: type mismatch resolving `<std::vec::IntoIter<u32> as std::iter::It
22
--> $DIR/associated-types-overridden-binding-2.rs:6:43
33
|
44
LL | let _: &dyn I32Iterator<Item = u32> = &vec![42].into_iter();
5-
| ^^^^^^^^^^^^^^^^^^^^^ expected u32, found i32
5+
| ^^^^^^^^^^^^^^^^^^^^^ expected i32, found u32
66
|
7-
= note: expected type `u32`
8-
found type `i32`
7+
= note: expected type `i32`
8+
found type `u32`
99
= note: required for the cast to the object type `dyn std::iter::Iterator<Item = u32, Item = i32>`
1010

1111
error: aborting due to previous error

src/test/ui/async-await/async-block-control-flow-static-semantics.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ error[E0271]: type mismatch resolving `<impl std::future::Future as std::future:
3333
--> $DIR/async-block-control-flow-static-semantics.rs:18:39
3434
|
3535
LL | let _: &dyn Future<Output = ()> = &block;
36-
| ^^^^^^ expected u8, found ()
36+
| ^^^^^^ expected (), found u8
3737
|
38-
= note: expected type `u8`
39-
found type `()`
38+
= note: expected type `()`
39+
found type `u8`
4040
= note: required for the cast to the object type `dyn std::future::Future<Output = ()>`
4141

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

6868
error[E0308]: mismatched types

src/test/ui/error-codes/E0271.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ LL | fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
55
| --- ------------------ required by this bound in `foo`
66
...
77
LL | foo(3_i8);
8-
| ^^^ expected reference, found u32
8+
| ^^^ expected u32, found reference
99
|
10-
= note: expected type `&'static str`
11-
found type `u32`
10+
= note: expected type `u32`
11+
found type `&'static str`
1212

1313
error: aborting due to previous error
1414

src/test/ui/issues/issue-24204.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ LL | trait Trait: Sized {
55
| ------------------ required by `Trait`
66
...
77
LL | fn test<T: Trait<B=i32>>(b: i32) -> T where T::A: MultiDispatch<i32> { T::new(b) }
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found type parameter
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found associated type
99
|
10-
= note: expected type `<<T as Trait>::A as MultiDispatch<i32>>::O`
11-
found type `T`
10+
= note: expected type `T`
11+
found type `<<T as Trait>::A as MultiDispatch<i32>>::O`
1212
= note: you might be missing a type parameter or trait bound
1313

1414
error: aborting due to previous error

0 commit comments

Comments
 (0)