Skip to content

Commit dbc7327

Browse files
committed
Fix suggestions for nested refs and muts
1 parent 0eaa336 commit dbc7327

File tree

4 files changed

+47
-2
lines changed

4 files changed

+47
-2
lines changed

compiler/rustc_hir_typeck/src/method/suggest.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2577,10 +2577,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
25772577
&& matches!(parent_pat.kind, hir::PatKind::Ref(..)) =>
25782578
{
25792579
err.span_label(span, "you must specify a type for this binding");
2580+
2581+
let mut ref_muts = Vec::new();
2582+
let mut current_node = parent_node;
2583+
2584+
while let Node::Pat(parent_pat) = current_node {
2585+
if let hir::PatKind::Ref(_, mutability) = parent_pat.kind {
2586+
ref_muts.push(mutability);
2587+
current_node = self.tcx.parent_hir_node(parent_pat.hir_id);
2588+
} else {
2589+
break;
2590+
}
2591+
}
2592+
2593+
let mut type_annotation = String::new();
2594+
for mutability in ref_muts.iter().rev() {
2595+
match mutability {
2596+
hir::Mutability::Mut => type_annotation.push_str("&mut "),
2597+
hir::Mutability::Not => type_annotation.push('&'),
2598+
}
2599+
}
2600+
type_annotation.push_str(&concrete_type);
2601+
25802602
err.span_suggestion_verbose(
25812603
pat.span.shrink_to_hi(),
25822604
"specify the type in the closure argument list",
2583-
format!(": &{concrete_type}"),
2605+
format!(": {type_annotation}"),
25842606
Applicability::MaybeIncorrect,
25852607
);
25862608
}

tests/ui/inference/ambiguous-numeric-in-closure-ref.fixed

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,9 @@ fn main() {
66
let _ = (0..10).filter(|&v: &i32| v.pow(2) > 0);
77
//~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}`
88
//~| SUGGESTION &i32
9+
10+
let v = vec![0, 1, 2];
11+
let _ = v.iter().filter(|&&v: &&i32| v.pow(2) > 0);
12+
//~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}`
13+
//~| SUGGESTION &&i32
914
}

tests/ui/inference/ambiguous-numeric-in-closure-ref.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,9 @@ fn main() {
66
let _ = (0..10).filter(|&v| v.pow(2) > 0);
77
//~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}`
88
//~| SUGGESTION &i32
9+
10+
let v = vec![0, 1, 2];
11+
let _ = v.iter().filter(|&&v| v.pow(2) > 0);
12+
//~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}`
13+
//~| SUGGESTION &&i32
914
}

tests/ui/inference/ambiguous-numeric-in-closure-ref.stderr

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@ help: specify the type in the closure argument list
1111
LL | let _ = (0..10).filter(|&v: &i32| v.pow(2) > 0);
1212
| ++++++
1313

14-
error: aborting due to 1 previous error
14+
error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}`
15+
--> $DIR/ambiguous-numeric-in-closure-ref.rs:11:37
16+
|
17+
LL | let _ = v.iter().filter(|&&v| v.pow(2) > 0);
18+
| - ^^^
19+
| |
20+
| you must specify a type for this binding
21+
|
22+
help: specify the type in the closure argument list
23+
|
24+
LL | let _ = v.iter().filter(|&&v: &&i32| v.pow(2) > 0);
25+
| +++++++
26+
27+
error: aborting due to 2 previous errors
1528

1629
For more information about this error, try `rustc --explain E0689`.

0 commit comments

Comments
 (0)