about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2019-04-29 19:02:54 -0700
committerEsteban Küber <esteban@kuber.com.ar>2019-04-29 19:02:54 -0700
commit742b48dc39768fbafd5a072b4ee1dbcd207d12f9 (patch)
treea2882370a20dd26c9104a547e9c22ff69318a492
parent0e7e9382fa1a6e50c976cd74ca420d7cb10591fa (diff)
downloadrust-742b48dc39768fbafd5a072b4ee1dbcd207d12f9.tar.gz
rust-742b48dc39768fbafd5a072b4ee1dbcd207d12f9.zip
Be more specific in the suggestion filtering
-rw-r--r--src/librustc_typeck/check/_match.rs52
-rw-r--r--src/test/ui/destructure-trait-ref.stderr10
-rw-r--r--src/test/ui/mismatched_types/issue-38371.stderr5
3 files changed, 56 insertions, 11 deletions
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 715b82183a7..53d1ac7b024 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -380,23 +380,59 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                 if let PatKind::Binding(..) = inner.node {
                                     let parent_id = tcx.hir().get_parent_node_by_hir_id(pat.hir_id);
                                     let parent = tcx.hir().get_by_hir_id(parent_id);
+                                    debug!("inner {:?} pat {:?} parent {:?}", inner, pat, parent);
                                     match parent {
-                                        hir::Node::Item(_) |
-                                        hir::Node::ForeignItem(_) |
-                                        hir::Node::TraitItem(_) |
-                                        hir::Node::ImplItem(_)  => { // this pat is an argument
+                                        hir::Node::Item(hir::Item {
+                                            node: hir::ItemKind::Fn(..), ..
+                                        }) |
+                                        hir::Node::ForeignItem(hir::ForeignItem {
+                                            node: hir::ForeignItemKind::Fn(..), ..
+                                        }) |
+                                        hir::Node::TraitItem(hir::TraitItem {
+                                            node: hir::TraitItemKind::Method(..), ..
+                                        }) |
+                                        hir::Node::ImplItem(hir::ImplItem {
+                                            node: hir::ImplItemKind::Method(..), ..
+                                        }) => { // this pat is likely an argument
                                             if let Ok(snippet) = tcx.sess.source_map()
-                                                .span_to_snippet(pat.span)
+                                                .span_to_snippet(inner.span)
                                             { // FIXME: turn into structured suggestion, will need
-                                              // a span that also includes the the type.
+                                              // a span that also includes the the arg's type.
                                                 err.help(&format!(
                                                     "did you mean `{}: &{}`?",
-                                                    &snippet[1..],
+                                                    snippet,
                                                     expected,
                                                 ));
                                             }
                                         }
-                                        _ => {} // don't provide the suggestion from above #55175
+                                        hir::Node::Expr(hir::Expr {
+                                            node: hir::ExprKind::Match(..), ..
+                                        }) => { // rely on match ergonomics
+                                            if let Ok(snippet) = tcx.sess.source_map()
+                                                .span_to_snippet(inner.span)
+                                            {
+                                                err.span_suggestion(
+                                                    pat.span,
+                                                    "you can rely on match ergonomics and remove \
+                                                     the explicit borrow",
+                                                    snippet,
+                                                    Applicability::MaybeIncorrect,
+                                                );
+                                            }
+                                        }
+                                        hir::Node::Pat(_) => {  // nested `&&pat`
+                                            if let Ok(snippet) = tcx.sess.source_map()
+                                                .span_to_snippet(inner.span)
+                                            {
+                                                err.span_suggestion(
+                                                    pat.span,
+                                                    "you can probaly remove the explicit borrow",
+                                                    snippet,
+                                                    Applicability::MaybeIncorrect,
+                                                );
+                                            }
+                                        }
+                                        _ => {} // don't provide suggestions in other cases #55175
                                     }
                                 }
                                 err.emit();
diff --git a/src/test/ui/destructure-trait-ref.stderr b/src/test/ui/destructure-trait-ref.stderr
index 7f389299afb..47ecadfd01a 100644
--- a/src/test/ui/destructure-trait-ref.stderr
+++ b/src/test/ui/destructure-trait-ref.stderr
@@ -20,7 +20,10 @@ error[E0308]: mismatched types
   --> $DIR/destructure-trait-ref.rs:31:10
    |
 LL |     let &&x = &1isize as &T;
-   |          ^^ expected trait T, found reference
+   |          ^^
+   |          |
+   |          expected trait T, found reference
+   |          help: you can probaly remove the explicit borrow: `x`
    |
    = note: expected type `dyn T`
               found type `&_`
@@ -29,7 +32,10 @@ error[E0308]: mismatched types
   --> $DIR/destructure-trait-ref.rs:36:11
    |
 LL |     let &&&x = &(&1isize as &T);
-   |           ^^ expected trait T, found reference
+   |           ^^
+   |           |
+   |           expected trait T, found reference
+   |           help: you can probaly remove the explicit borrow: `x`
    |
    = note: expected type `dyn T`
               found type `&_`
diff --git a/src/test/ui/mismatched_types/issue-38371.stderr b/src/test/ui/mismatched_types/issue-38371.stderr
index 30da48ba4a8..833b8998c33 100644
--- a/src/test/ui/mismatched_types/issue-38371.stderr
+++ b/src/test/ui/mismatched_types/issue-38371.stderr
@@ -12,7 +12,10 @@ error[E0308]: mismatched types
   --> $DIR/issue-38371.rs:18:9
    |
 LL | fn agh(&&bar: &u32) {
-   |         ^^^^ expected u32, found reference
+   |         ^^^^
+   |         |
+   |         expected u32, found reference
+   |         help: you can probaly remove the explicit borrow: `bar`
    |
    = note: expected type `u32`
               found type `&_`