Rollup merge of #61217 - estebank:issue-52820, r=Centril

Account for short-hand init structs when suggesting conversion

Fix #52820.
This commit is contained in:
Oliver Scherer 2019-05-29 14:41:05 +02:00 committed by GitHub
commit e83776f3ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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

@ -5010,6 +5010,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())
@ -5019,14 +5023,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`.