Skip to content

Commit 24b2e20

Browse files
committed
Account for short-hand init structs when suggesting conversion
1 parent 02f5786 commit 24b2e20

File tree

4 files changed

+58
-7
lines changed

4 files changed

+58
-7
lines changed

src/librustc_typeck/check/demand.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
270270
None
271271
}
272272

273-
fn is_hir_id_from_struct_pattern_shorthand_field(&self, hir_id: hir::HirId, sp: Span) -> bool {
273+
crate fn is_hir_id_from_struct_pattern_shorthand_field(
274+
&self,
275+
hir_id: hir::HirId,
276+
sp: Span,
277+
) -> bool {
274278
let cm = self.sess().source_map();
275279
let parent_id = self.tcx.hir().get_parent_node_by_hir_id(hir_id);
276280
if let Some(parent) = self.tcx.hir().find_by_hir_id(parent_id) {

src/librustc_typeck/check/mod.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -5014,6 +5014,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
50145014
Applicability::MachineApplicable,
50155015
);
50165016
} else if !self.check_for_cast(err, expr, found, expected) {
5017+
let is_struct_pat_shorthand_field = self.is_hir_id_from_struct_pattern_shorthand_field(
5018+
expr.hir_id,
5019+
expr.span,
5020+
);
50175021
let methods = self.get_conversion_methods(expr.span, expected, found);
50185022
if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
50195023
let mut suggestions = iter::repeat(&expr_text).zip(methods.iter())
@@ -5023,14 +5027,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
50235027
None // do not suggest code that is already there (#53348)
50245028
} else {
50255029
let method_call_list = [".to_vec()", ".to_string()"];
5026-
if receiver.ends_with(".clone()")
5030+
let sugg = if receiver.ends_with(".clone()")
50275031
&& method_call_list.contains(&method_call.as_str()) {
50285032
let max_len = receiver.rfind(".").unwrap();
5029-
Some(format!("{}{}", &receiver[..max_len], method_call))
5030-
}
5031-
else {
5032-
Some(format!("{}{}", receiver, method_call))
5033-
}
5033+
format!("{}{}", &receiver[..max_len], method_call)
5034+
} else {
5035+
format!("{}{}", receiver, method_call)
5036+
};
5037+
Some(if is_struct_pat_shorthand_field {
5038+
format!("{}: {}", receiver, sugg)
5039+
} else {
5040+
sugg
5041+
})
50345042
}
50355043
}).peekable();
50365044
if suggestions.peek().is_some() {
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
struct Bravery {
2+
guts: String,
3+
brains: String,
4+
}
5+
6+
fn main() {
7+
let guts = "mettle";
8+
let _ = Bravery {
9+
guts, //~ ERROR mismatched types
10+
brains: guts.clone(), //~ ERROR mismatched types
11+
};
12+
}
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/issue-52820.rs:9:9
3+
|
4+
LL | guts,
5+
| ^^^^
6+
| |
7+
| expected struct `std::string::String`, found &str
8+
| help: try using a conversion method: `guts: guts.to_string()`
9+
|
10+
= note: expected type `std::string::String`
11+
found type `&str`
12+
13+
error[E0308]: mismatched types
14+
--> $DIR/issue-52820.rs:10:17
15+
|
16+
LL | brains: guts.clone(),
17+
| ^^^^^^^^^^^^
18+
| |
19+
| expected struct `std::string::String`, found &str
20+
| help: try using a conversion method: `guts.to_string()`
21+
|
22+
= note: expected type `std::string::String`
23+
found type `&str`
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)