Skip to content

Commit 64f6e4f

Browse files
committed
Fix bad suggestion for clone/is_some in field init shorthand
1 parent c90eb48 commit 64f6e4f

File tree

4 files changed

+104
-10
lines changed

4 files changed

+104
-10
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -985,13 +985,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
985985
)
986986
.must_apply_modulo_regions()
987987
{
988-
diag.span_suggestion_verbose(
989-
expr.span.shrink_to_hi(),
990-
"consider using clone here",
991-
".clone()",
992-
Applicability::MachineApplicable,
993-
);
994-
return true;
988+
let suggestion = match self.maybe_get_struct_pattern_shorthand_field(expr) {
989+
Some(ident) => format!(": {}.clone()", ident),
990+
None => ".clone()".to_string()
991+
};
992+
993+
diag.span_suggestion_verbose(
994+
expr.span.shrink_to_hi(),
995+
"consider using clone here",
996+
suggestion,
997+
Applicability::MachineApplicable,
998+
);
999+
return true;
9951000
}
9961001
false
9971002
}
@@ -1153,13 +1158,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11531158
return false;
11541159
}
11551160

1156-
diag.span_suggestion(
1161+
let suggestion = match self.maybe_get_struct_pattern_shorthand_field(expr) {
1162+
Some(ident) => format!(": {}.is_some()", ident),
1163+
None => ".is_some()".to_string(),
1164+
};
1165+
1166+
diag.span_suggestion_verbose(
11571167
expr.span.shrink_to_hi(),
11581168
"use `Option::is_some` to test if the `Option` has a value",
1159-
".is_some()",
1169+
suggestion,
11601170
Applicability::MachineApplicable,
11611171
);
1162-
11631172
true
11641173
}
11651174

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// run-rustfix
2+
#![allow(dead_code)]
3+
4+
struct Foo {
5+
t: Thing
6+
}
7+
8+
#[derive(Clone)]
9+
struct Thing;
10+
11+
fn test_clone() {
12+
let t = &Thing;
13+
let _f = Foo {
14+
t: t.clone() //~ ERROR mismatched types
15+
};
16+
}
17+
18+
struct Bar {
19+
t: bool
20+
}
21+
22+
fn test_is_some() {
23+
let t = Option::<i32>::Some(1);
24+
let _f = Bar {
25+
t: t.is_some() //~ ERROR mismatched types
26+
};
27+
}
28+
29+
fn main() {}

tests/ui/suggestions/issue-108470.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// run-rustfix
2+
#![allow(dead_code)]
3+
4+
struct Foo {
5+
t: Thing
6+
}
7+
8+
#[derive(Clone)]
9+
struct Thing;
10+
11+
fn test_clone() {
12+
let t = &Thing;
13+
let _f = Foo {
14+
t //~ ERROR mismatched types
15+
};
16+
}
17+
18+
struct Bar {
19+
t: bool
20+
}
21+
22+
fn test_is_some() {
23+
let t = Option::<i32>::Some(1);
24+
let _f = Bar {
25+
t //~ ERROR mismatched types
26+
};
27+
}
28+
29+
fn main() {}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/issue-108470.rs:14:9
3+
|
4+
LL | t
5+
| ^ expected `Thing`, found `&Thing`
6+
|
7+
help: consider using clone here
8+
|
9+
LL | t: t.clone()
10+
| +++++++++++
11+
12+
error[E0308]: mismatched types
13+
--> $DIR/issue-108470.rs:25:9
14+
|
15+
LL | t
16+
| ^ expected `bool`, found `Option<i32>`
17+
|
18+
= note: expected type `bool`
19+
found enum `Option<i32>`
20+
help: use `Option::is_some` to test if the `Option` has a value
21+
|
22+
LL | t: t.is_some()
23+
| +++++++++++++
24+
25+
error: aborting due to 2 previous errors
26+
27+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)