Skip to content

Commit

Permalink
Account for short-hand init structs when suggesting conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed May 26, 2019
1 parent 02f5786 commit 24b2e20
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 7 deletions.
6 changes: 5 additions & 1 deletion src/librustc_typeck/check/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
None
}

fn is_hir_id_from_struct_pattern_shorthand_field(&self, hir_id: hir::HirId, sp: Span) -> bool {
crate fn is_hir_id_from_struct_pattern_shorthand_field(
&self,
hir_id: hir::HirId,
sp: Span,
) -> bool {
let cm = self.sess().source_map();
let parent_id = self.tcx.hir().get_parent_node_by_hir_id(hir_id);
if let Some(parent) = self.tcx.hir().find_by_hir_id(parent_id) {
Expand Down
20 changes: 14 additions & 6 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5014,6 +5014,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
Applicability::MachineApplicable,
);
} else if !self.check_for_cast(err, expr, found, expected) {
let is_struct_pat_shorthand_field = self.is_hir_id_from_struct_pattern_shorthand_field(
expr.hir_id,
expr.span,
);
let methods = self.get_conversion_methods(expr.span, expected, found);
if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
let mut suggestions = iter::repeat(&expr_text).zip(methods.iter())
Expand All @@ -5023,14 +5027,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
None // do not suggest code that is already there (#53348)
} else {
let method_call_list = [".to_vec()", ".to_string()"];
if receiver.ends_with(".clone()")
let sugg = if receiver.ends_with(".clone()")
&& method_call_list.contains(&method_call.as_str()) {
let max_len = receiver.rfind(".").unwrap();
Some(format!("{}{}", &receiver[..max_len], method_call))
}
else {
Some(format!("{}{}", receiver, method_call))
}
format!("{}{}", &receiver[..max_len], method_call)
} else {
format!("{}{}", receiver, method_call)
};
Some(if is_struct_pat_shorthand_field {
format!("{}: {}", receiver, sugg)
} else {
sugg
})
}
}).peekable();
if suggestions.peek().is_some() {
Expand Down
12 changes: 12 additions & 0 deletions src/test/ui/suggestions/issue-52820.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
struct Bravery {
guts: String,
brains: String,
}

fn main() {
let guts = "mettle";
let _ = Bravery {
guts, //~ ERROR mismatched types
brains: guts.clone(), //~ ERROR mismatched types
};
}
27 changes: 27 additions & 0 deletions src/test/ui/suggestions/issue-52820.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
error[E0308]: mismatched types
--> $DIR/issue-52820.rs:9:9
|
LL | guts,
| ^^^^
| |
| expected struct `std::string::String`, found &str
| help: try using a conversion method: `guts: guts.to_string()`
|
= note: expected type `std::string::String`
found type `&str`

error[E0308]: mismatched types
--> $DIR/issue-52820.rs:10:17
|
LL | brains: guts.clone(),
| ^^^^^^^^^^^^
| |
| expected struct `std::string::String`, found &str
| help: try using a conversion method: `guts.to_string()`
|
= note: expected type `std::string::String`
found type `&str`

error: aborting due to 2 previous errors

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

0 comments on commit 24b2e20

Please sign in to comment.