about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/check/_match.rs24
-rw-r--r--src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr2
-rw-r--r--src/test/ui/suggestions/dont-suggest-dereference-on-arg.rs21
-rw-r--r--src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr10
4 files changed, 53 insertions, 4 deletions
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index ea0fa945c37..f03f782ebb4 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -120,15 +120,33 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         .pat_adjustments_mut()
                         .insert(pat.hir_id, pat_adjustments);
                 } else {
+                    let mut ref_sp = pat.span;
+                    let mut id = pat.id;
+                    loop {  // make span include all enclosing `&` to avoid confusing diag output
+                        id = tcx.hir.get_parent_node(id);
+                        let node = tcx.hir.find(id);
+                        if let Some(hir::map::NodePat(pat)) = node {
+                            if let hir::PatKind::Ref(..) = pat.node {
+                                ref_sp = pat.span;
+                            } else {
+                                break;
+                            }
+                        } else {
+                            break;
+                        }
+                    }
+                    let sp = ref_sp.to(pat.span);
                     let mut err = feature_gate::feature_err(
                         &tcx.sess.parse_sess,
                         "match_default_bindings",
-                        pat.span,
+                        sp,
                         feature_gate::GateIssue::Language,
                         "non-reference pattern used to match a reference",
                     );
-                    if let Ok(snippet) = tcx.sess.codemap().span_to_snippet(pat.span) {
-                        err.span_suggestion(pat.span, "consider using", format!("&{}", &snippet));
+                    if let Ok(snippet) = tcx.sess.codemap().span_to_snippet(sp) {
+                        err.span_suggestion(sp,
+                                            "consider using a reference",
+                                            format!("&{}", &snippet));
                     }
                     err.emit();
                 }
diff --git a/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr b/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr
index b10980d6bd6..ebf9e498ffd 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr
+++ b/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr
@@ -2,7 +2,7 @@ error: non-reference pattern used to match a reference (see issue #42640)
   --> $DIR/suggestion.rs:12:12
    |
 12 |     if let Some(y) = &Some(22) { //~ ERROR non-reference pattern
-   |            ^^^^^^^ help: consider using: `&Some(y)`
+   |            ^^^^^^^ help: consider using a reference: `&Some(y)`
    |
    = help: add #![feature(match_default_bindings)] to the crate attributes to enable
 
diff --git a/src/test/ui/suggestions/dont-suggest-dereference-on-arg.rs b/src/test/ui/suggestions/dont-suggest-dereference-on-arg.rs
new file mode 100644
index 00000000000..72269768e0f
--- /dev/null
+++ b/src/test/ui/suggestions/dont-suggest-dereference-on-arg.rs
@@ -0,0 +1,21 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn foo(s: &str) -> bool { true }
+
+fn main() {
+    let x = vec![(String::new(), String::new())];
+    x.iter()
+        .filter(|&(ref a, _)| foo(a))
+        //~^ ERROR non-reference pattern used to match a reference
+        //~| HELP consider using a reference
+        //~| HELP add
+        .collect();
+}
diff --git a/src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr b/src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr
new file mode 100644
index 00000000000..799d9080b9d
--- /dev/null
+++ b/src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr
@@ -0,0 +1,10 @@
+error: non-reference pattern used to match a reference (see issue #42640)
+  --> $DIR/dont-suggest-dereference-on-arg.rs:16:18
+   |
+16 |         .filter(|&(ref a, _)| foo(a))
+   |                  ^^^^^^^^^^^ help: consider using a reference: `&&(ref a, _)`
+   |
+   = help: add #![feature(match_default_bindings)] to the crate attributes to enable
+
+error: aborting due to previous error
+