Use get_parent_node
instead of using spans
This commit is contained in:
parent
7c2526a9d7
commit
2461b7a264
@ -23,9 +23,7 @@
|
||||
use std::cmp;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Spanned;
|
||||
use syntax::errors::DiagnosticBuilder;
|
||||
use syntax::feature_gate;
|
||||
use syntax::parse::ParseSess;
|
||||
use syntax::ptr::P;
|
||||
use syntax_pos::Span;
|
||||
|
||||
@ -122,32 +120,35 @@ pub fn check_pat_walk(
|
||||
.pat_adjustments_mut()
|
||||
.insert(pat.hir_id, pat_adjustments);
|
||||
} else {
|
||||
fn feature_err<'a>(sp: Span, sess: &'a ParseSess) -> DiagnosticBuilder<'a> {
|
||||
feature_gate::feature_err(
|
||||
sess,
|
||||
"match_default_bindings",
|
||||
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) {
|
||||
// The following is a bit of a hack. We probably should check the AST for
|
||||
// this instead, but this should be good enough for the expected cases.
|
||||
let prev_span = pat.span.prev_point();
|
||||
let (sp, sugg) = match tcx.sess.codemap().span_to_snippet(prev_span) {
|
||||
// Make the suggestion more obvious when having `&(_, _)`
|
||||
Ok(ref prev) if &*prev == "&" => {
|
||||
(prev_span.to(pat.span), format!("&&{}", &snippet)),
|
||||
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;
|
||||
}
|
||||
_ => (pat.span, format!("&{}", &snippet)),
|
||||
};
|
||||
let mut err = feature_err(sp, &tcx.sess.parse_sess);
|
||||
err.span_suggestion(sp, "consider using a reference", sugg);
|
||||
err.emit();
|
||||
} else {
|
||||
feature_err(pat.span, &tcx.sess.parse_sess).emit();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let sp = ref_sp.to(pat.span);
|
||||
let mut err = feature_gate::feature_err(
|
||||
&tcx.sess.parse_sess,
|
||||
"match_default_bindings",
|
||||
sp,
|
||||
feature_gate::GateIssue::Language,
|
||||
"non-reference pattern used to match a reference",
|
||||
);
|
||||
if let Ok(snippet) = tcx.sess.codemap().span_to_snippet(sp) {
|
||||
err.span_suggestion(sp,
|
||||
"consider using a reference",
|
||||
format!("&{}", &snippet));
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -159,18 +159,6 @@ pub fn next_point(self) -> Span {
|
||||
Span::new(BytePos(lo), BytePos(lo), span.ctxt)
|
||||
}
|
||||
|
||||
/// Returns a new span representing the previous character after the start-point of this span
|
||||
pub fn prev_point(self) -> Span {
|
||||
let span = self.data();
|
||||
let span_lo = span.lo.0;
|
||||
let lo = if span_lo == 0 {
|
||||
0
|
||||
} else {
|
||||
span_lo - 1
|
||||
};
|
||||
Span::new(BytePos(lo), BytePos(span_lo), span.ctxt)
|
||||
}
|
||||
|
||||
/// Returns `self` if `self` is not the dummy span, and `other` otherwise.
|
||||
pub fn substitute_dummy(self, other: Span) -> Span {
|
||||
if self.source_equal(&DUMMY_SP) { other } else { self }
|
||||
|
@ -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
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: non-reference pattern used to match a reference (see issue #42640)
|
||||
--> dont-suggest-dereference-on-arg.rs:16:19
|
||||
--> $DIR/dont-suggest-dereference-on-arg.rs:16:19
|
||||
|
|
||||
16 | .filter(|&(ref a, _)| foo(a))
|
||||
| ^^^^^^^^^^^ help: consider using: `&&(ref k, _)`
|
||||
| ^^^^^^^^^^^ help: consider using a reference: `&&(ref k, _)`
|
||||
|
|
||||
= help: add #![feature(match_default_bindings)] to the crate attributes to enable
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user