Account for short-hand init structs when suggesting conversion

This commit is contained in:
Esteban Küber 2019-05-26 11:39:48 -07:00
parent 02f5786a32
commit 24b2e20b31
4 changed files with 58 additions and 7 deletions

View File

@ -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) {

View File

@ -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())
@ -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() {

View File

@ -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
};
}

View File

@ -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`.