Skip to content

Commit

Permalink
Rollup merge of #118730 - jyn514:cmp_refs, r=estebank,compiler-errors
Browse files Browse the repository at this point in the history
recurse into refs when comparing tys for diagnostics

before:
![image](https://github.com/rust-lang/rust/assets/23638587/bf6abd62-c7f3-4c09-a47e-31b6e129de19)

after:
![image](https://github.com/rust-lang/rust/assets/23638587/b704d728-ddba-4204-aebe-c07dcbbcb55c)

this diff from the test suite is also quite nice imo:
```diff
`@@` -4,8 +4,8 `@@` error[E0308]: mismatched types
 LL |     debug_assert_eq!(iter.next(), Some(value));
    |                                   ^^^^^^^^^^^ expected `Option<<I as Iterator>::Item>`, found `Option<&<I as Iterator>::Item>`
    |
-   = note: expected enum `Option<<I as Iterator>::Item>`
-              found enum `Option<&<I as Iterator>::Item>`
+   = note: expected enum `Option<_>`
+              found enum `Option<&_>`
```
  • Loading branch information
matthiaskrgr committed Dec 8, 2023
2 parents d2de292 + eb53721 commit 943fa33
Show file tree
Hide file tree
Showing 58 changed files with 224 additions and 214 deletions.
94 changes: 52 additions & 42 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1181,37 +1181,54 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
debug!("cmp(t1={}, t1.kind={:?}, t2={}, t2.kind={:?})", t1, t1.kind(), t2, t2.kind());

// helper functions
fn equals<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
match (a.kind(), b.kind()) {
(a, b) if *a == *b => true,
(&ty::Int(_), &ty::Infer(ty::InferTy::IntVar(_)))
| (
&ty::Infer(ty::InferTy::IntVar(_)),
&ty::Int(_) | &ty::Infer(ty::InferTy::IntVar(_)),
)
| (&ty::Float(_), &ty::Infer(ty::InferTy::FloatVar(_)))
| (
&ty::Infer(ty::InferTy::FloatVar(_)),
&ty::Float(_) | &ty::Infer(ty::InferTy::FloatVar(_)),
) => true,
_ => false,
let recurse = |t1, t2, values: &mut (DiagnosticStyledString, DiagnosticStyledString)| {
let (x1, x2) = self.cmp(t1, t2);
(values.0).0.extend(x1.0);
(values.1).0.extend(x2.0);
};

fn fmt_region<'tcx>(region: ty::Region<'tcx>) -> String {
let mut r = region.to_string();
if r == "'_" {
r.clear();
} else {
r.push(' ');
}
format!("&{r}")
}

fn push_ty_ref<'tcx>(
fn push_ref<'tcx>(
region: ty::Region<'tcx>,
ty: Ty<'tcx>,
mutbl: hir::Mutability,
s: &mut DiagnosticStyledString,
) {
let mut r = region.to_string();
if r == "'_" {
r.clear();
s.push_highlighted(fmt_region(region));
s.push_highlighted(mutbl.prefix_str());
}

fn cmp_ty_refs<'tcx>(
r1: ty::Region<'tcx>,
mut1: hir::Mutability,
r2: ty::Region<'tcx>,
mut2: hir::Mutability,
ss: &mut (DiagnosticStyledString, DiagnosticStyledString),
) {
let (r1, r2) = (fmt_region(r1), fmt_region(r2));
if r1 != r2 {
ss.0.push_highlighted(r1);
ss.1.push_highlighted(r2);
} else {
r.push(' ');
ss.0.push_normal(r1);
ss.1.push_normal(r2);
}

if mut1 != mut2 {
ss.0.push_highlighted(mut1.prefix_str());
ss.1.push_highlighted(mut2.prefix_str());
} else {
ss.0.push_normal(mut1.prefix_str());
ss.1.push_normal(mut2.prefix_str());
}
s.push_highlighted(format!("&{}{}", r, mutbl.prefix_str()));
s.push_normal(ty.to_string());
}

// process starts here
Expand Down Expand Up @@ -1310,9 +1327,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
values.0.push_normal("_");
values.1.push_normal("_");
} else {
let (x1, x2) = self.cmp(ta1, ta2);
(values.0).0.extend(x1.0);
(values.1).0.extend(x2.0);
recurse(ta1, ta2, &mut values);
}
self.push_comma(&mut values.0, &mut values.1, len, i);
}
Expand Down Expand Up @@ -1418,27 +1433,24 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
}

// When finding T != &T, highlight only the borrow
(&ty::Ref(r1, ref_ty1, mutbl1), _) if equals(ref_ty1, t2) => {
// When finding `&T != &T`, compare the references, then recurse into pointee type
(&ty::Ref(r1, ref_ty1, mutbl1), &ty::Ref(r2, ref_ty2, mutbl2)) => {
let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
push_ty_ref(r1, ref_ty1, mutbl1, &mut values.0);
values.1.push_normal(t2.to_string());
cmp_ty_refs(r1, mutbl1, r2, mutbl2, &mut values);
recurse(ref_ty1, ref_ty2, &mut values);
values
}
(_, &ty::Ref(r2, ref_ty2, mutbl2)) if equals(t1, ref_ty2) => {
// When finding T != &T, highlight the borrow
(&ty::Ref(r1, ref_ty1, mutbl1), _) => {
let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
values.0.push_normal(t1.to_string());
push_ty_ref(r2, ref_ty2, mutbl2, &mut values.1);
push_ref(r1, mutbl1, &mut values.0);
recurse(ref_ty1, t2, &mut values);
values
}

// When encountering &T != &mut T, highlight only the borrow
(&ty::Ref(r1, ref_ty1, mutbl1), &ty::Ref(r2, ref_ty2, mutbl2))
if equals(ref_ty1, ref_ty2) =>
{
(_, &ty::Ref(r2, ref_ty2, mutbl2)) => {
let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
push_ty_ref(r1, ref_ty1, mutbl1, &mut values.0);
push_ty_ref(r2, ref_ty2, mutbl2, &mut values.1);
push_ref(r2, mutbl2, &mut values.1);
recurse(t1, ref_ty2, &mut values);
values
}

Expand All @@ -1448,9 +1460,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
(DiagnosticStyledString::normal("("), DiagnosticStyledString::normal("("));
let len = args1.len();
for (i, (left, right)) in args1.iter().zip(args2).enumerate() {
let (x1, x2) = self.cmp(left, right);
(values.0).0.extend(x1.0);
(values.1).0.extend(x2.0);
recurse(left, right, &mut values);
self.push_comma(&mut values.0, &mut values.1, len, i);
}
if len == 1 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ error[E0308]: const not compatible with trait
LL | const NAME: &'a str = "unit";
| ^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected reference `&'static str`
found reference `&'a str`
= note: expected reference `&'static _`
found reference `&'a _`
note: the lifetime `'a` as defined here...
--> $DIR/associated-const-impl-wrong-lifetime.rs:6:6
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ error[E0308]: mismatched types
LL | debug_assert_eq!(iter.next(), Some(value));
| ^^^^^^^^^^^ expected `Option<<I as Iterator>::Item>`, found `Option<&<I as Iterator>::Item>`
|
= note: expected enum `Option<<I as Iterator>::Item>`
found enum `Option<&<I as Iterator>::Item>`
= note: expected enum `Option<_>`
found enum `Option<&_>`

error: aborting due to 1 previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ note: type in trait
|
LL | fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected signature `fn(&i32) -> Pin<Box<dyn Future<Output = i32>>>`
found signature `fn(&i32) -> impl Future<Output = i32>`
= note: expected signature `fn(&_) -> Pin<Box<dyn Future<Output = i32>>>`
found signature `fn(&_) -> impl Future<Output = i32>`

error: aborting due to 1 previous error

Expand Down
8 changes: 4 additions & 4 deletions tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ error[E0308]: method not compatible with trait
LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected signature `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'_>)`
found signature `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'_>)`
= note: expected signature `fn(&'a _, Inv<'c>, Inv<'c>, Inv<'_>)`
found signature `fn(&'a _, Inv<'_>, Inv<'c>, Inv<'_>)`
note: the lifetime `'c` as defined here...
--> $DIR/regions-bound-missing-bound-in-impl.rs:27:24
|
Expand All @@ -41,8 +41,8 @@ error[E0308]: method not compatible with trait
LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected signature `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'_>)`
found signature `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'_>)`
= note: expected signature `fn(&'a _, Inv<'c>, Inv<'c>, Inv<'_>)`
found signature `fn(&'a _, Inv<'_>, Inv<'c>, Inv<'_>)`
note: the lifetime `'c` as defined here...
--> $DIR/regions-bound-missing-bound-in-impl.rs:27:24
|
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/box/issue-82446.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ error[E0308]: mismatched types
LL | val
| ^^^ expected `Box<dyn MyTrait>`, found `&Box<dyn MyTrait>`
|
= note: expected struct `Box<(dyn MyTrait + 'static)>`
found reference `&Box<(dyn MyTrait + 'static)>`
= note: expected struct `Box<_>`
found reference `&Box<_>`

error: aborting due to 1 previous error

Expand Down
12 changes: 6 additions & 6 deletions tests/ui/closure-expected-type/expect-fn-supply-fn.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,26 @@ error[E0308]: mismatched types
LL | with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
| ^ one type is more general than the other
|
= note: expected fn pointer `fn(&u32)`
found fn pointer `for<'a> fn(&'a u32)`
= note: expected fn pointer `fn(&_)`
found fn pointer `for<'a> fn(&'a _)`

error[E0308]: mismatched types
--> $DIR/expect-fn-supply-fn.rs:39:50
|
LL | with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
| ^ one type is more general than the other
|
= note: expected fn pointer `for<'a> fn(&'a u32)`
found fn pointer `fn(&u32)`
= note: expected fn pointer `for<'a> fn(&'a _)`
found fn pointer `fn(&_)`

error[E0308]: mismatched types
--> $DIR/expect-fn-supply-fn.rs:48:50
|
LL | with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
| ^ one type is more general than the other
|
= note: expected fn pointer `for<'a> fn(&'a u32)`
found fn pointer `fn(&u32)`
= note: expected fn pointer `for<'a> fn(&'a _)`
found fn pointer `fn(&_)`

error: aborting due to 5 previous errors

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/closures/multiple-fn-bounds.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ LL | foo(move |x| v);
| |
| expected due to this
|
= note: expected closure signature `fn(char) -> _`
found closure signature `for<'a> fn(&'a char) -> _`
= note: expected closure signature `fn(_) -> _`
found closure signature `for<'a> fn(&'a _) -> _`
note: closure inferred to have a different signature due to this bound
--> $DIR/multiple-fn-bounds.rs:1:11
|
Expand Down
12 changes: 6 additions & 6 deletions tests/ui/fn/fn-pointer-mismatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,20 @@ fn main() {
// suggest removing reference
let c: fn(u32) -> u32 = &foo;
//~^ ERROR mismatched types
//~| expected fn pointer `fn(u32) -> u32`
//~| found reference `&fn(u32) -> u32 {foo}`
//~| expected fn pointer `fn(_) -> _`
//~| found reference `&fn(_) -> _ {foo}`

// suggest using reference
let d: &fn(u32) -> u32 = foo;
//~^ ERROR mismatched types
//~| expected reference `&fn(u32) -> u32`
//~| found fn item `fn(u32) -> u32 {foo}`
//~| expected reference `&fn(_) -> _`
//~| found fn item `fn(_) -> _ {foo}`

// suggest casting with reference
let e: &fn(u32) -> u32 = &foo;
//~^ ERROR mismatched types
//~| expected reference `&fn(u32) -> u32`
//~| found reference `&fn(u32) -> u32 {foo}`
//~| expected reference `&fn(_) -> _`
//~| found reference `&fn(_) -> _ {foo}`

// OK
let mut z: fn(u32) -> u32 = foo as fn(u32) -> u32;
Expand Down
16 changes: 8 additions & 8 deletions tests/ui/fn/fn-pointer-mismatch.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ LL | let g = if n % 2 == 0 { &foo } else { &bar };
| |
| expected because of this
|
= note: expected reference `&fn(u32) -> u32 {foo}`
found reference `&fn(u32) -> u32 {bar}`
= note: expected reference `&fn(_) -> _ {foo}`
found reference `&fn(_) -> _ {bar}`
= note: different fn items have unique types, even if their signatures are the same
= help: consider casting both fn items to fn pointers using `as fn(u32) -> u32`

Expand Down Expand Up @@ -47,8 +47,8 @@ LL | let c: fn(u32) -> u32 = &foo;
| |
| expected due to this
|
= note: expected fn pointer `fn(u32) -> u32`
found reference `&fn(u32) -> u32 {foo}`
= note: expected fn pointer `fn(_) -> _`
found reference `&fn(_) -> _ {foo}`
help: consider removing the reference
|
LL | let c: fn(u32) -> u32 = foo;
Expand All @@ -62,8 +62,8 @@ LL | let d: &fn(u32) -> u32 = foo;
| |
| expected due to this
|
= note: expected reference `&fn(u32) -> u32`
found fn item `fn(u32) -> u32 {foo}`
= note: expected reference `&fn(_) -> _`
found fn item `fn(_) -> _ {foo}`
help: consider using a reference
|
LL | let d: &fn(u32) -> u32 = &foo;
Expand All @@ -77,8 +77,8 @@ LL | let e: &fn(u32) -> u32 = &foo;
| |
| expected due to this
|
= note: expected reference `&fn(u32) -> u32`
found reference `&fn(u32) -> u32 {foo}`
= note: expected reference `&fn(_) -> _`
found reference `&fn(_) -> _ {foo}`
= note: fn items are distinct from fn pointers
help: consider casting to a fn pointer
|
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/generic-associated-types/issue-88360.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ LL | fn copy(&self) -> Self::Gat<'_> where T: Copy {
LL | *self.test()
| ^^^^^^^^^^^^ expected `&T`, found type parameter `T`
|
= note: expected reference `&T`
found type parameter `T`
= note: expected reference `&_`
found type parameter `_`
help: consider removing deref here
|
LL - *self.test()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ LL | / check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u3
LL | | for<'a> fn(&'a u32, &'a u32) -> &'a u32) }
| |_____________________________________________- in this macro invocation
|
= note: expected enum `Option<for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32>`
found enum `Option<for<'a> fn(&'a u32, &'a u32) -> &'a u32>`
= note: expected enum `Option<for<'a, 'b> fn(&'a _, &'b _) -> &'a _>`
found enum `Option<for<'a> fn(&'a _, &'a _) -> &'a _>`
= note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 1 previous error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ LL | / check! { bound_a_vs_free_x: (for<'a> fn(&'a u32),
LL | | fn(&'x u32)) }
| |______________- in this macro invocation
|
= note: expected enum `Option<for<'a> fn(&'a u32)>`
found enum `Option<fn(&u32)>`
= note: expected enum `Option<for<'a> fn(&'a _)>`
found enum `Option<fn(&_)>`
= note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 1 previous error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ LL | let _: for<'b> fn(&'b u32) = foo();
| |
| expected due to this
|
= note: expected fn pointer `for<'b> fn(&'b u32)`
found fn pointer `fn(&u32)`
= note: expected fn pointer `for<'b> fn(&'b _)`
found fn pointer `fn(&_)`

error: aborting due to 1 previous error

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/impl-trait/in-trait/specialization-broken.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ note: type in trait
|
LL | fn bar(&self) -> impl Sized;
| ^^^^^^^^^^
= note: expected signature `fn(&U) -> impl Sized`
found signature `fn(&U) -> U`
= note: expected signature `fn(&_) -> impl Sized`
found signature `fn(&_) -> U`

error: method with return-position `impl Trait` in trait cannot be specialized
--> $DIR/specialization-broken.rs:15:5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ LL | fn eq(&self, _other: &(Foo, i32)) -> bool {
| expected `a::Bar`, found opaque type
| help: change the parameter type to match the trait: `&(a::Bar, i32)`
|
= note: expected signature `fn(&a::Bar, &(a::Bar, i32)) -> _`
found signature `fn(&a::Bar, &(a::Foo, i32)) -> _`
= note: expected signature `fn(&a::Bar, &(a::Bar, _)) -> _`
found signature `fn(&a::Bar, &(a::Foo, _)) -> _`

error: unconstrained opaque type
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:18:16
Expand All @@ -41,8 +41,8 @@ LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
| expected opaque type, found `b::Bar`
| help: change the parameter type to match the trait: `&(b::Foo, i32)`
|
= note: expected signature `fn(&b::Bar, &(b::Foo, i32)) -> _`
found signature `fn(&b::Bar, &(b::Bar, i32)) -> _`
= note: expected signature `fn(&b::Bar, &(b::Foo, _)) -> _`
found signature `fn(&b::Bar, &(b::Bar, _)) -> _`
note: this item must have the opaque type in its signature in order to be able to register hidden types
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:12
|
Expand Down

0 comments on commit 943fa33

Please sign in to comment.