Skip to content

Commit eb378d2

Browse files
authored
Rollup merge of #99862 - WaffleLapkin:type_mismatch_fix, r=compiler-errors
Improve type mismatch w/ function signatures This PR makes use of `note: expected/found` (instead of labeling types in labels) in type mismatch with function signatures. Pros: it's easier to compare the signatures, cons: the error is a little more verbose now. This is especially nice when - The signatures differ in a small subset of parameters (same parameters are elided) - The difference is in details, for example `isize` vs `usize` (there is a better chance that the types align) Also this PR fixes the inconsistency in variable names in the edited code (`expected` and `found`). A zulip thread from which this pr started: [[link]](https://rust-lang.zulipchat.com/#narrow/stream/147480-t-compiler.2Fwg-diagnostics/topic/Type.20error.20regression.3F.2E.2E.2E/near/289756602). An example diagnostic: <table> <tr> <th>this pr</th> <th>nightly</th> </tr> <tr> <td> ```text error[E0631]: type mismatch in function arguments --> ./t.rs:4:12 | 4 | expect(&f); | ------ ^^ expected due to this | | | required by a bound introduced by this call ... 10 | fn f(_: isize, _: u8, _: Vec<u32>) {} | ---------------------------------- found signature defined here | = note: expected function signature `fn(usize, _, Vec<u64>) -> _` found function signature `fn(isize, _, Vec<u32>) -> _` note: required because of the requirements on the impl of `Trait` for `fn(isize, u8, Vec<u32>) {f}` --> ./t.rs:8:9 | 8 | impl<F> Trait for F where F: Fn(usize, u8, Vec<u64>) -> u8 {} | ^^^^^ ^ = note: required for the cast from `fn(isize, u8, Vec<u32>) {f}` to the object type `dyn Trait` ``` </td> <td> ```text error[E0631]: type mismatch in function arguments --> ./t.rs:4:12 | 4 | expect(&f); | ------ ^^ expected signature of `fn(usize, u8, Vec<u64>) -> _` | | | required by a bound introduced by this call ... 10 | fn f(_: isize, _: u8, _: Vec<u32>) {} | ---------------------------------- found signature of `fn(isize, u8, Vec<u32>) -> _` | note: required because of the requirements on the impl of `Trait` for `fn(isize, u8, Vec<u32>) {f}` --> ./t.rs:8:9 | 8 | impl<F> Trait for F where F: Fn(usize, u8, Vec<u64>) -> u8 {} | ^^^^^ ^ = note: required for the cast to the object type `dyn Trait` ``` </td> </tr> </table> <details><summary>code</summary> <p> ```rust fn main() { fn expect(_: &dyn Trait) {} expect(&f); } trait Trait {} impl<F> Trait for F where F: Fn(usize, u8, Vec<u64>) -> u8 {} fn f(_: isize, _: u8, _: Vec<u32>) {} ``` </p> </details> r? `@compiler-errors`
2 parents c668820 + 7da578b commit eb378d2

13 files changed

+139
-76
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+20-13
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use rustc_hir::def_id::DefId;
2020
use rustc_hir::intravisit::Visitor;
2121
use rustc_hir::lang_items::LangItem;
2222
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
23+
use rustc_infer::infer::TyCtxtInferExt;
2324
use rustc_middle::hir::map;
2425
use rustc_middle::ty::{
2526
self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
@@ -253,8 +254,8 @@ pub trait InferCtxtExt<'tcx> {
253254
&self,
254255
span: Span,
255256
found_span: Option<Span>,
256-
expected_ref: ty::PolyTraitRef<'tcx>,
257257
found: ty::PolyTraitRef<'tcx>,
258+
expected: ty::PolyTraitRef<'tcx>,
258259
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>;
259260

260261
fn suggest_fully_qualified_path(
@@ -1536,13 +1537,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
15361537
&self,
15371538
span: Span,
15381539
found_span: Option<Span>,
1539-
expected_ref: ty::PolyTraitRef<'tcx>,
15401540
found: ty::PolyTraitRef<'tcx>,
1541+
expected: ty::PolyTraitRef<'tcx>,
15411542
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
1542-
pub(crate) fn build_fn_sig_string<'tcx>(
1543+
pub(crate) fn build_fn_sig_ty<'tcx>(
15431544
tcx: TyCtxt<'tcx>,
15441545
trait_ref: ty::PolyTraitRef<'tcx>,
1545-
) -> String {
1546+
) -> Ty<'tcx> {
15461547
let inputs = trait_ref.skip_binder().substs.type_at(1);
15471548
let sig = match inputs.kind() {
15481549
ty::Tuple(inputs)
@@ -1564,10 +1565,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
15641565
abi::Abi::Rust,
15651566
),
15661567
};
1567-
trait_ref.rebind(sig).to_string()
1568+
1569+
tcx.mk_fn_ptr(trait_ref.rebind(sig))
15681570
}
15691571

1570-
let argument_kind = match expected_ref.skip_binder().self_ty().kind() {
1572+
let argument_kind = match expected.skip_binder().self_ty().kind() {
15711573
ty::Closure(..) => "closure",
15721574
ty::Generator(..) => "generator",
15731575
_ => "function",
@@ -1576,17 +1578,22 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
15761578
self.tcx.sess,
15771579
span,
15781580
E0631,
1579-
"type mismatch in {} arguments",
1580-
argument_kind
1581+
"type mismatch in {argument_kind} arguments",
15811582
);
15821583

1583-
let found_str = format!("expected signature of `{}`", build_fn_sig_string(self.tcx, found));
1584-
err.span_label(span, found_str);
1584+
err.span_label(span, "expected due to this");
15851585

15861586
let found_span = found_span.unwrap_or(span);
1587-
let expected_str =
1588-
format!("found signature of `{}`", build_fn_sig_string(self.tcx, expected_ref));
1589-
err.span_label(found_span, expected_str);
1587+
err.span_label(found_span, "found signature defined here");
1588+
1589+
let expected = build_fn_sig_ty(self.tcx, expected);
1590+
let found = build_fn_sig_ty(self.tcx, found);
1591+
1592+
let (expected_str, found_str) =
1593+
self.tcx.infer_ctxt().enter(|infcx| infcx.cmp(expected, found));
1594+
1595+
let signature_kind = format!("{argument_kind} signature");
1596+
err.note_expected_found(&signature_kind, expected_str, &signature_kind, found_str);
15901597

15911598
err
15921599
}

src/test/ui/anonymous-higher-ranked-lifetime.stderr

+44-22
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ error[E0631]: type mismatch in closure arguments
22
--> $DIR/anonymous-higher-ranked-lifetime.rs:2:5
33
|
44
LL | f1(|_: (), _: ()| {});
5-
| ^^ -------------- found signature of `fn((), ()) -> _`
5+
| ^^ -------------- found signature defined here
66
| |
7-
| expected signature of `for<'r, 's> fn(&'r (), &'s ()) -> _`
7+
| expected due to this
88
|
9+
= note: expected closure signature `for<'r, 's> fn(&'r (), &'s ()) -> _`
10+
found closure signature `fn((), ()) -> _`
911
note: required by a bound in `f1`
1012
--> $DIR/anonymous-higher-ranked-lifetime.rs:16:25
1113
|
@@ -16,10 +18,12 @@ error[E0631]: type mismatch in closure arguments
1618
--> $DIR/anonymous-higher-ranked-lifetime.rs:3:5
1719
|
1820
LL | f2(|_: (), _: ()| {});
19-
| ^^ -------------- found signature of `fn((), ()) -> _`
21+
| ^^ -------------- found signature defined here
2022
| |
21-
| expected signature of `for<'a, 'r> fn(&'a (), &'r ()) -> _`
23+
| expected due to this
2224
|
25+
= note: expected closure signature `for<'a, 'r> fn(&'a (), &'r ()) -> _`
26+
found closure signature `fn((), ()) -> _`
2327
note: required by a bound in `f2`
2428
--> $DIR/anonymous-higher-ranked-lifetime.rs:17:25
2529
|
@@ -30,10 +34,12 @@ error[E0631]: type mismatch in closure arguments
3034
--> $DIR/anonymous-higher-ranked-lifetime.rs:4:5
3135
|
3236
LL | f3(|_: (), _: ()| {});
33-
| ^^ -------------- found signature of `fn((), ()) -> _`
37+
| ^^ -------------- found signature defined here
3438
| |
35-
| expected signature of `for<'r> fn(&(), &'r ()) -> _`
39+
| expected due to this
3640
|
41+
= note: expected closure signature `for<'r> fn(&(), &'r ()) -> _`
42+
found closure signature `fn((), ()) -> _`
3743
note: required by a bound in `f3`
3844
--> $DIR/anonymous-higher-ranked-lifetime.rs:18:29
3945
|
@@ -44,10 +50,12 @@ error[E0631]: type mismatch in closure arguments
4450
--> $DIR/anonymous-higher-ranked-lifetime.rs:5:5
4551
|
4652
LL | f4(|_: (), _: ()| {});
47-
| ^^ -------------- found signature of `fn((), ()) -> _`
53+
| ^^ -------------- found signature defined here
4854
| |
49-
| expected signature of `for<'s, 'r> fn(&'s (), &'r ()) -> _`
55+
| expected due to this
5056
|
57+
= note: expected closure signature `for<'r, 's> fn(&'s (), &'r ()) -> _`
58+
found closure signature `fn((), ()) -> _`
5159
note: required by a bound in `f4`
5260
--> $DIR/anonymous-higher-ranked-lifetime.rs:19:25
5361
|
@@ -58,10 +66,12 @@ error[E0631]: type mismatch in closure arguments
5866
--> $DIR/anonymous-higher-ranked-lifetime.rs:6:5
5967
|
6068
LL | f5(|_: (), _: ()| {});
61-
| ^^ -------------- found signature of `fn((), ()) -> _`
69+
| ^^ -------------- found signature defined here
6270
| |
63-
| expected signature of `for<'r> fn(&'r (), &'r ()) -> _`
71+
| expected due to this
6472
|
73+
= note: expected closure signature `for<'r> fn(&'r (), &'r ()) -> _`
74+
found closure signature `fn((), ()) -> _`
6575
note: required by a bound in `f5`
6676
--> $DIR/anonymous-higher-ranked-lifetime.rs:20:25
6777
|
@@ -72,10 +82,12 @@ error[E0631]: type mismatch in closure arguments
7282
--> $DIR/anonymous-higher-ranked-lifetime.rs:7:5
7383
|
7484
LL | g1(|_: (), _: ()| {});
75-
| ^^ -------------- found signature of `fn((), ()) -> _`
85+
| ^^ -------------- found signature defined here
7686
| |
77-
| expected signature of `for<'r> fn(&'r (), Box<(dyn for<'s> Fn(&'s ()) + 'static)>) -> _`
87+
| expected due to this
7888
|
89+
= note: expected closure signature `for<'r> fn(&'r (), Box<(dyn for<'r> Fn(&'r ()) + 'static)>) -> _`
90+
found closure signature `fn((), ()) -> _`
7991
note: required by a bound in `g1`
8092
--> $DIR/anonymous-higher-ranked-lifetime.rs:23:25
8193
|
@@ -86,10 +98,12 @@ error[E0631]: type mismatch in closure arguments
8698
--> $DIR/anonymous-higher-ranked-lifetime.rs:8:5
8799
|
88100
LL | g2(|_: (), _: ()| {});
89-
| ^^ -------------- found signature of `fn((), ()) -> _`
101+
| ^^ -------------- found signature defined here
90102
| |
91-
| expected signature of `for<'r> fn(&'r (), for<'s> fn(&'s ())) -> _`
103+
| expected due to this
92104
|
105+
= note: expected closure signature `for<'r> fn(&'r (), for<'r> fn(&'r ())) -> _`
106+
found closure signature `fn((), ()) -> _`
93107
note: required by a bound in `g2`
94108
--> $DIR/anonymous-higher-ranked-lifetime.rs:24:25
95109
|
@@ -100,10 +114,12 @@ error[E0631]: type mismatch in closure arguments
100114
--> $DIR/anonymous-higher-ranked-lifetime.rs:9:5
101115
|
102116
LL | g3(|_: (), _: ()| {});
103-
| ^^ -------------- found signature of `fn((), ()) -> _`
117+
| ^^ -------------- found signature defined here
104118
| |
105-
| expected signature of `for<'s> fn(&'s (), Box<(dyn for<'r> Fn(&'r ()) + 'static)>) -> _`
119+
| expected due to this
106120
|
121+
= note: expected closure signature `for<'s> fn(&'s (), Box<(dyn for<'r> Fn(&'r ()) + 'static)>) -> _`
122+
found closure signature `fn((), ()) -> _`
107123
note: required by a bound in `g3`
108124
--> $DIR/anonymous-higher-ranked-lifetime.rs:25:25
109125
|
@@ -114,10 +130,12 @@ error[E0631]: type mismatch in closure arguments
114130
--> $DIR/anonymous-higher-ranked-lifetime.rs:10:5
115131
|
116132
LL | g4(|_: (), _: ()| {});
117-
| ^^ -------------- found signature of `fn((), ()) -> _`
133+
| ^^ -------------- found signature defined here
118134
| |
119-
| expected signature of `for<'s> fn(&'s (), for<'r> fn(&'r ())) -> _`
135+
| expected due to this
120136
|
137+
= note: expected closure signature `for<'s> fn(&'s (), for<'r> fn(&'r ())) -> _`
138+
found closure signature `fn((), ()) -> _`
121139
note: required by a bound in `g4`
122140
--> $DIR/anonymous-higher-ranked-lifetime.rs:26:25
123141
|
@@ -128,10 +146,12 @@ error[E0631]: type mismatch in closure arguments
128146
--> $DIR/anonymous-higher-ranked-lifetime.rs:11:5
129147
|
130148
LL | h1(|_: (), _: (), _: (), _: ()| {});
131-
| ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
149+
| ^^ ---------------------------- found signature defined here
132150
| |
133-
| expected signature of `for<'r, 's> fn(&'r (), Box<(dyn for<'t0> Fn(&'t0 ()) + 'static)>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _`
151+
| expected due to this
134152
|
153+
= note: expected closure signature `for<'r, 's> fn(&'r (), Box<(dyn for<'r> Fn(&'r ()) + 'static)>, &'s (), for<'r, 's> fn(&'r (), &'s ())) -> _`
154+
found closure signature `fn((), (), (), ()) -> _`
135155
note: required by a bound in `h1`
136156
--> $DIR/anonymous-higher-ranked-lifetime.rs:29:25
137157
|
@@ -142,10 +162,12 @@ error[E0631]: type mismatch in closure arguments
142162
--> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
143163
|
144164
LL | h2(|_: (), _: (), _: (), _: ()| {});
145-
| ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
165+
| ^^ ---------------------------- found signature defined here
146166
| |
147-
| expected signature of `for<'r, 't0> fn(&'r (), Box<(dyn for<'s> Fn(&'s ()) + 'static)>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _`
167+
| expected due to this
148168
|
169+
= note: expected closure signature `for<'t0, 'r> fn(&'r (), Box<(dyn for<'r> Fn(&'r ()) + 'static)>, &'t0 (), for<'r, 's> fn(&'r (), &'s ())) -> _`
170+
found closure signature `fn((), (), (), ()) -> _`
149171
note: required by a bound in `h2`
150172
--> $DIR/anonymous-higher-ranked-lifetime.rs:30:25
151173
|

src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ error[E0631]: type mismatch in closure arguments
22
--> $DIR/expect-infer-var-appearing-twice.rs:14:5
33
|
44
LL | with_closure(|x: u32, y: i32| {
5-
| ^^^^^^^^^^^^ ---------------- found signature of `fn(u32, i32) -> _`
5+
| ^^^^^^^^^^^^ ---------------- found signature defined here
66
| |
7-
| expected signature of `fn(_, _) -> _`
7+
| expected due to this
88
|
9+
= note: expected closure signature `fn(_, _) -> _`
10+
found closure signature `fn(u32, i32) -> _`
911
note: required by a bound in `with_closure`
1012
--> $DIR/expect-infer-var-appearing-twice.rs:2:14
1113
|

src/test/ui/generator/issue-88653.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ use std::ops::Generator;
77

88
fn foo(bar: bool) -> impl Generator<(bool,)> {
99
//~^ ERROR: type mismatch in generator arguments [E0631]
10-
//~| NOTE: expected signature of `fn((bool,)) -> _`
10+
//~| NOTE: expected due to this
11+
//~| NOTE: expected generator signature `fn((bool,)) -> _`
12+
//~| NOTE: in this expansion of desugaring of `impl Trait`
1113
//~| NOTE: in this expansion of desugaring of `impl Trait`
1214
|bar| {
13-
//~^ NOTE: found signature of `fn(bool) -> _`
15+
//~^ NOTE: found signature defined here
1416
if bar {
1517
yield bar;
1618
}

src/test/ui/generator/issue-88653.stderr

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ error[E0631]: type mismatch in generator arguments
22
--> $DIR/issue-88653.rs:8:22
33
|
44
LL | fn foo(bar: bool) -> impl Generator<(bool,)> {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^ expected signature of `fn((bool,)) -> _`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^ expected due to this
66
...
77
LL | |bar| {
8-
| ----- found signature of `fn(bool) -> _`
8+
| ----- found signature defined here
9+
|
10+
= note: expected generator signature `fn((bool,)) -> _`
11+
found generator signature `fn(bool) -> _`
912

1013
error: aborting due to previous error
1114

src/test/ui/generic-associated-types/bugs/issue-88382.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ error[E0631]: type mismatch in function arguments
22
--> $DIR/issue-88382.rs:28:40
33
|
44
LL | do_something(SomeImplementation(), test);
5-
| ------------ ^^^^ expected signature of `for<'r> fn(&'r mut std::iter::Empty<usize>) -> _`
5+
| ------------ ^^^^ expected due to this
66
| |
77
| required by a bound introduced by this call
88
...
99
LL | fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {}
10-
| ------------------------------------------------- found signature of `for<'r, 'a> fn(&'r mut <_ as Iterable>::Iterator<'a>) -> _`
10+
| ------------------------------------------------- found signature defined here
1111
|
12+
= note: expected function signature `for<'r> fn(&'r mut std::iter::Empty<usize>) -> _`
13+
found function signature `for<'a, 'r> fn(&'r mut <_ as Iterable>::Iterator<'a>) -> _`
1214
note: required by a bound in `do_something`
1315
--> $DIR/issue-88382.rs:22:48
1416
|

src/test/ui/intrinsics/const-eval-select-bad.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,15 @@ error[E0631]: type mismatch in function arguments
6767
--> $DIR/const-eval-select-bad.rs:34:32
6868
|
6969
LL | const fn foo(n: i32) -> i32 {
70-
| --------------------------- found signature of `fn(i32) -> _`
70+
| --------------------------- found signature defined here
7171
...
7272
LL | const_eval_select((true,), foo, baz);
73-
| ----------------- ^^^ expected signature of `fn(bool) -> _`
73+
| ----------------- ^^^ expected due to this
7474
| |
7575
| required by a bound introduced by this call
7676
|
77+
= note: expected function signature `fn(bool) -> _`
78+
found function signature `fn(i32) -> _`
7779
note: required by a bound in `const_eval_select`
7880
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
7981
|

src/test/ui/mismatched_types/E0631.stderr

+16-8
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ error[E0631]: type mismatch in closure arguments
22
--> $DIR/E0631.rs:7:5
33
|
44
LL | foo(|_: isize| {});
5-
| ^^^ ---------- found signature of `fn(isize) -> _`
5+
| ^^^ ---------- found signature defined here
66
| |
7-
| expected signature of `fn(usize) -> _`
7+
| expected due to this
88
|
9+
= note: expected closure signature `fn(usize) -> _`
10+
found closure signature `fn(isize) -> _`
911
note: required by a bound in `foo`
1012
--> $DIR/E0631.rs:3:11
1113
|
@@ -16,10 +18,12 @@ error[E0631]: type mismatch in closure arguments
1618
--> $DIR/E0631.rs:8:5
1719
|
1820
LL | bar(|_: isize| {});
19-
| ^^^ ---------- found signature of `fn(isize) -> _`
21+
| ^^^ ---------- found signature defined here
2022
| |
21-
| expected signature of `fn(usize) -> _`
23+
| expected due to this
2224
|
25+
= note: expected closure signature `fn(usize) -> _`
26+
found closure signature `fn(isize) -> _`
2327
note: required by a bound in `bar`
2428
--> $DIR/E0631.rs:4:11
2529
|
@@ -30,13 +34,15 @@ error[E0631]: type mismatch in function arguments
3034
--> $DIR/E0631.rs:9:9
3135
|
3236
LL | fn f(_: u64) {}
33-
| ------------ found signature of `fn(u64) -> _`
37+
| ------------ found signature defined here
3438
...
3539
LL | foo(f);
36-
| --- ^ expected signature of `fn(usize) -> _`
40+
| --- ^ expected due to this
3741
| |
3842
| required by a bound introduced by this call
3943
|
44+
= note: expected function signature `fn(usize) -> _`
45+
found function signature `fn(u64) -> _`
4046
note: required by a bound in `foo`
4147
--> $DIR/E0631.rs:3:11
4248
|
@@ -47,13 +53,15 @@ error[E0631]: type mismatch in function arguments
4753
--> $DIR/E0631.rs:10:9
4854
|
4955
LL | fn f(_: u64) {}
50-
| ------------ found signature of `fn(u64) -> _`
56+
| ------------ found signature defined here
5157
...
5258
LL | bar(f);
53-
| --- ^ expected signature of `fn(usize) -> _`
59+
| --- ^ expected due to this
5460
| |
5561
| required by a bound introduced by this call
5662
|
63+
= note: expected function signature `fn(usize) -> _`
64+
found function signature `fn(u64) -> _`
5765
note: required by a bound in `bar`
5866
--> $DIR/E0631.rs:4:11
5967
|

0 commit comments

Comments
 (0)