diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index ea0fa945c3783..f03f782ebb452 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 b10980d6bd605..ebf9e498ffd9e 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 0000000000000..72269768e0f5c --- /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 or the MIT license +// , 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 0000000000000..799d9080b9d18 --- /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 +