Skip to content

Commit f15979d

Browse files
authored
Rollup merge of rust-lang#114256 - Urgau:fix-issue-114180, r=WaffleLapkin
Fix invalid suggestion for mismatched types in closure arguments This PR fixes the invalid suggestion for mismatched types in closure arguments. The invalid suggestion came from a wrongly created span in the parser for closure arguments that don't have a type specified. Specifically, the span in this case was the last token span, but in the case of tuples, the span represented the last parenthesis instead of the whole tuple, which is fixed by taking the more accurate span of the pattern. There is one unfortunate downside of this fix, it worsens even more the diagnostic for mismatched types in closure args without an explicit type. This happens because there is no correct span for implied inferred type. I tried also fixing this but it's a rabbit hole. Fixes rust-lang#114180
2 parents 91404bd + 8ea7e45 commit f15979d

File tree

7 files changed

+78
-30
lines changed

7 files changed

+78
-30
lines changed

compiler/rustc_hir_typeck/src/pat.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
755755
match binding_parent {
756756
// Check that there is explicit type (ie this is not a closure param with inferred type)
757757
// so we don't suggest moving something to the type that does not exist
758-
hir::Node::Param(hir::Param { ty_span, .. }) if binding.span != *ty_span => {
758+
hir::Node::Param(hir::Param { ty_span, pat, .. }) if pat.span != *ty_span => {
759759
err.multipart_suggestion_verbose(
760760
format!("to take parameter `{binding}` by reference, move `&{mutability}` to the type"),
761761
vec![

compiler/rustc_parse/src/parser/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2342,7 +2342,7 @@ impl<'a> Parser<'a> {
23422342
let ty = if this.eat(&token::Colon) {
23432343
this.parse_ty()?
23442344
} else {
2345-
this.mk_ty(this.prev_token.span, TyKind::Infer)
2345+
this.mk_ty(pat.span, TyKind::Infer)
23462346
};
23472347

23482348
Ok((

tests/ui/impl-trait/hidden-type-is-opaque-2.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
fn reify_as() -> Thunk<impl FnOnce(Continuation) -> Continuation> {
88
Thunk::new(|mut cont| {
9-
cont.reify_as(); //~ ERROR type annotations needed
9+
//~^ ERROR type annotations needed
10+
cont.reify_as();
1011
cont
1112
})
1213
}
@@ -15,7 +16,8 @@ type Tait = impl FnOnce(Continuation) -> Continuation;
1516

1617
fn reify_as_tait() -> Thunk<Tait> {
1718
Thunk::new(|mut cont| {
18-
cont.reify_as(); //~ ERROR type annotations needed
19+
//~^ ERROR type annotations needed
20+
cont.reify_as();
1921
cont
2022
})
2123
}

tests/ui/impl-trait/hidden-type-is-opaque-2.stderr

+20-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,30 @@
11
error[E0282]: type annotations needed
2-
--> $DIR/hidden-type-is-opaque-2.rs:9:9
2+
--> $DIR/hidden-type-is-opaque-2.rs:8:17
33
|
4+
LL | Thunk::new(|mut cont| {
5+
| ^^^^^^^^
6+
LL |
47
LL | cont.reify_as();
5-
| ^^^^ cannot infer type
8+
| ---- type must be known at this point
9+
|
10+
help: consider giving this closure parameter an explicit type
11+
|
12+
LL | Thunk::new(|mut cont: /* Type */| {
13+
| ++++++++++++
614

715
error[E0282]: type annotations needed
8-
--> $DIR/hidden-type-is-opaque-2.rs:18:9
16+
--> $DIR/hidden-type-is-opaque-2.rs:18:17
917
|
18+
LL | Thunk::new(|mut cont| {
19+
| ^^^^^^^^
20+
LL |
1021
LL | cont.reify_as();
11-
| ^^^^ cannot infer type
22+
| ---- type must be known at this point
23+
|
24+
help: consider giving this closure parameter an explicit type
25+
|
26+
LL | Thunk::new(|mut cont: /* Type */| {
27+
| ++++++++++++
1228

1329
error: aborting due to 2 previous errors
1430

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// check-fail
2+
3+
fn main() {
4+
let mut v = vec![(1,)];
5+
let compare = |(a,), (e,)| todo!();
6+
v.sort_by(compare);
7+
//~^ ERROR type mismatch in closure arguments
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error[E0631]: type mismatch in closure arguments
2+
--> $DIR/closure-ref-114180.rs:6:15
3+
|
4+
LL | let compare = |(a,), (e,)| todo!();
5+
| ------------ found signature defined here
6+
LL | v.sort_by(compare);
7+
| ------- ^^^^^^^ expected due to this
8+
| |
9+
| required by a bound introduced by this call
10+
|
11+
= note: expected closure signature `for<'a, 'b> fn(&'a ({integer},), &'b ({integer},)) -> _`
12+
found closure signature `fn((_,), (_,)) -> _`
13+
note: required by a bound in `slice::<impl [T]>::sort_by`
14+
--> $SRC_DIR/alloc/src/slice.rs:LL:COL
15+
help: consider adjusting the signature so it borrows its arguments
16+
|
17+
LL | let compare = |&(a,), &(e,)| todo!();
18+
| + +
19+
20+
error: aborting due to previous error
21+
22+
For more information about this error, try `rustc --explain E0631`.

tests/ui/mismatched_types/ref-pat-suggestions.stderr

+22-22
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,10 @@ error[E0308]: mismatched types
103103
--> $DIR/ref-pat-suggestions.rs:11:23
104104
|
105105
LL | let _: fn(u32) = |&_a| ();
106-
| ^--
107-
| ||
108-
| |expected due to this
106+
| ^^^
107+
| |
109108
| expected `u32`, found `&_`
109+
| expected due to this
110110
|
111111
= note: expected type `u32`
112112
found reference `&_`
@@ -120,10 +120,10 @@ error[E0308]: mismatched types
120120
--> $DIR/ref-pat-suggestions.rs:12:23
121121
|
122122
LL | let _: fn(u32) = |&mut _a| ();
123-
| ^^^^^--
124-
| | |
125-
| | expected due to this
123+
| ^^^^^^^
124+
| |
126125
| expected `u32`, found `&mut _`
126+
| expected due to this
127127
|
128128
= note: expected type `u32`
129129
found mutable reference `&mut _`
@@ -142,10 +142,10 @@ error[E0308]: mismatched types
142142
--> $DIR/ref-pat-suggestions.rs:13:25
143143
|
144144
LL | let _: fn(&u32) = |&&_a| ();
145-
| ^--
146-
| ||
147-
| |expected due to this
148-
| expected `u32`, found `&_`
145+
| -^^^
146+
| ||
147+
| |expected `u32`, found `&_`
148+
| expected due to this
149149
|
150150
= note: expected type `u32`
151151
found reference `&_`
@@ -159,10 +159,10 @@ error[E0308]: mismatched types
159159
--> $DIR/ref-pat-suggestions.rs:14:33
160160
|
161161
LL | let _: fn(&mut u32) = |&mut &_a| ();
162-
| ^--
163-
| ||
164-
| |expected due to this
165-
| expected `u32`, found `&_`
162+
| -----^^^
163+
| | |
164+
| | expected `u32`, found `&_`
165+
| expected due to this
166166
|
167167
= note: expected type `u32`
168168
found reference `&_`
@@ -176,10 +176,10 @@ error[E0308]: mismatched types
176176
--> $DIR/ref-pat-suggestions.rs:15:25
177177
|
178178
LL | let _: fn(&u32) = |&&mut _a| ();
179-
| ^^^^^--
180-
| | |
181-
| | expected due to this
182-
| expected `u32`, found `&mut _`
179+
| -^^^^^^^
180+
| ||
181+
| |expected `u32`, found `&mut _`
182+
| expected due to this
183183
|
184184
= note: expected type `u32`
185185
found mutable reference `&mut _`
@@ -193,10 +193,10 @@ error[E0308]: mismatched types
193193
--> $DIR/ref-pat-suggestions.rs:16:33
194194
|
195195
LL | let _: fn(&mut u32) = |&mut &mut _a| ();
196-
| ^^^^^--
197-
| | |
198-
| | expected due to this
199-
| expected `u32`, found `&mut _`
196+
| -----^^^^^^^
197+
| | |
198+
| | expected `u32`, found `&mut _`
199+
| expected due to this
200200
|
201201
= note: expected type `u32`
202202
found mutable reference `&mut _`

0 commit comments

Comments
 (0)