diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2019-03-26 19:04:25 -0700 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2019-03-27 19:44:08 -0700 |
| commit | 4e7ec07bb910aef258a848d5fcfa96b3bab7b3b4 (patch) | |
| tree | 4aff2e0428cfa2423e8b5e20d1f74cd57c4f0be5 /src | |
| parent | 33ef0bad21d6bb646c7c3ab0dbf381ca96c324bf (diff) | |
| download | rust-4e7ec07bb910aef258a848d5fcfa96b3bab7b3b4.tar.gz rust-4e7ec07bb910aef258a848d5fcfa96b3bab7b3b4.zip | |
Account for short-hand field syntax when suggesting borrow
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_typeck/check/demand.rs | 48 | ||||
| -rw-r--r-- | src/test/ui/deref-suggestion.rs | 14 | ||||
| -rw-r--r-- | src/test/ui/deref-suggestion.stderr | 32 |
3 files changed, 82 insertions, 12 deletions
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index b1a249d821b..5939f965269 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -277,6 +277,24 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { return None; } + let parent_id = self.tcx.hir().get_parent_node_by_hir_id(expr.hir_id); + let mut is_struct_pat_shorthand_field = false; + if let Some(parent) = self.tcx.hir().find_by_hir_id(parent_id) { + // Account for fields + if let Node::Expr(hir::Expr { + node: hir::ExprKind::Struct(_, fields, ..), .. + }) = parent { + if let Ok(src) = cm.span_to_snippet(sp) { + for field in fields { + if field.ident.as_str() == src.as_str() && field.is_shorthand { + is_struct_pat_shorthand_field = true; + break; + } + } + } + } + }; + match (&expected.sty, &checked_ty.sty) { (&ty::Ref(_, exp, _), &ty::Ref(_, check, _)) => match (&exp.sty, &check.sty) { (&ty::Str, &ty::Array(arr, _)) | @@ -341,14 +359,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(sugg) = self.can_use_as_ref(expr) { return Some(sugg); } - return Some(match mutability { - hir::Mutability::MutMutable => { - (sp, "consider mutably borrowing here", format!("&mut {}", - sugg_expr)) + return Some(match (mutability, is_struct_pat_shorthand_field) { + (hir::Mutability::MutMutable, false) => { + (sp, "consider mutably borrowing here", + format!("&mut {}", sugg_expr)) } - hir::Mutability::MutImmutable => { + (hir::Mutability::MutImmutable, false) => { (sp, "consider borrowing here", format!("&{}", sugg_expr)) } + (hir::Mutability::MutMutable, true) => { + (sp, "consider mutably borrowing here", + format!("{}: &mut {}", sugg_expr, sugg_expr)) + } + (hir::Mutability::MutImmutable, true) => { + (sp, "consider borrowing here", + format!("{}: &{}", sugg_expr, sugg_expr)) + } }); } } @@ -389,12 +415,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { checked, sp) { // do not suggest if the span comes from a macro (#52783) - if let (Ok(code), - true) = (cm.span_to_snippet(sp), sp == expr.span) { + if let (Ok(code), true) = ( + cm.span_to_snippet(sp), + sp == expr.span, + ) { return Some(( sp, "consider dereferencing the borrow", - format!("*{}", code), + if is_struct_pat_shorthand_field { + format!("{}: *{}", code, code) + } else { + format!("*{}", code) + }, )); } } diff --git a/src/test/ui/deref-suggestion.rs b/src/test/ui/deref-suggestion.rs index 83e54b64f47..f156766f528 100644 --- a/src/test/ui/deref-suggestion.rs +++ b/src/test/ui/deref-suggestion.rs @@ -15,6 +15,14 @@ fn foo4(u: &u32) { //~^ ERROR mismatched types } +struct S<'a> { + u: &'a u32, +} + +struct R { + i: u32, +} + fn main() { let s = String::new(); let r_s = &s; @@ -27,4 +35,10 @@ fn main() { foo4(&0); assert_eq!(3i32, &3i32); //~^ ERROR mismatched types + let u = 3; + let s = S { u }; + //~^ ERROR mismatched types + let i = &4; + let r = R { i }; + //~^ ERROR mismatched types } diff --git a/src/test/ui/deref-suggestion.stderr b/src/test/ui/deref-suggestion.stderr index 8f061b3416e..bd0ebfac531 100644 --- a/src/test/ui/deref-suggestion.stderr +++ b/src/test/ui/deref-suggestion.stderr @@ -23,7 +23,7 @@ LL | foo3(u); found type `&u32` error[E0308]: mismatched types - --> $DIR/deref-suggestion.rs:22:9 + --> $DIR/deref-suggestion.rs:30:9 | LL | foo(&"aaa".to_owned()); | ^^^^^^^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | foo(&"aaa".to_owned()); found type `&std::string::String` error[E0308]: mismatched types - --> $DIR/deref-suggestion.rs:24:9 + --> $DIR/deref-suggestion.rs:32:9 | LL | foo(&mut "aaa".to_owned()); | ^^^^^^^^^^^^^^^^^^^^^ @@ -59,7 +59,7 @@ LL | foo3(borrow!(0)); found type `&{integer}` error[E0308]: mismatched types - --> $DIR/deref-suggestion.rs:28:5 + --> $DIR/deref-suggestion.rs:36:5 | LL | assert_eq!(3i32, &3i32); | ^^^^^^^^^^^^^^^^^^^^^^^^ expected i32, found &i32 @@ -68,6 +68,30 @@ LL | assert_eq!(3i32, &3i32); found type `&i32` = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error: aborting due to 6 previous errors +error[E0308]: mismatched types + --> $DIR/deref-suggestion.rs:39:17 + | +LL | let s = S { u }; + | ^ + | | + | expected &u32, found integer + | help: consider borrowing here: `u: &u` + | + = note: expected type `&u32` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/deref-suggestion.rs:42:17 + | +LL | let r = R { i }; + | ^ + | | + | expected u32, found &{integer} + | help: consider dereferencing the borrow: `i: *i` + | + = note: expected type `u32` + found type `&{integer}` + +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0308`. |
