Skip to content

Commit 2461b7a

Browse files
committed
Use get_parent_node instead of using spans
1 parent 7c2526a commit 2461b7a

File tree

4 files changed

+30
-41
lines changed

4 files changed

+30
-41
lines changed

src/librustc_typeck/check/_match.rs

+27-26
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@ use std::collections::hash_map::Entry::{Occupied, Vacant};
2323
use std::cmp;
2424
use syntax::ast;
2525
use syntax::codemap::Spanned;
26-
use syntax::errors::DiagnosticBuilder;
2726
use syntax::feature_gate;
28-
use syntax::parse::ParseSess;
2927
use syntax::ptr::P;
3028
use syntax_pos::Span;
3129

@@ -122,32 +120,35 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
122120
.pat_adjustments_mut()
123121
.insert(pat.hir_id, pat_adjustments);
124122
} else {
125-
fn feature_err<'a>(sp: Span, sess: &'a ParseSess) -> DiagnosticBuilder<'a> {
126-
feature_gate::feature_err(
127-
sess,
128-
"match_default_bindings",
129-
sp,
130-
feature_gate::GateIssue::Language,
131-
"non-reference pattern used to match a reference",
132-
)
133-
}
134-
if let Ok(snippet) = tcx.sess.codemap().span_to_snippet(pat.span) {
135-
// The following is a bit of a hack. We probably should check the AST for
136-
// this instead, but this should be good enough for the expected cases.
137-
let prev_span = pat.span.prev_point();
138-
let (sp, sugg) = match tcx.sess.codemap().span_to_snippet(prev_span) {
139-
// Make the suggestion more obvious when having `&(_, _)`
140-
Ok(ref prev) if &*prev == "&" => {
141-
(prev_span.to(pat.span), format!("&&{}", &snippet)),
123+
let mut ref_sp = pat.span;
124+
let mut id = pat.id;
125+
loop { // make span include all enclosing `&` to avoid confusing diag output
126+
id = tcx.hir.get_parent_node(id);
127+
let node = tcx.hir.find(id);
128+
if let Some(hir::map::NodePat(pat)) = node {
129+
if let hir::PatKind::Ref(..) = pat.node {
130+
ref_sp = pat.span;
131+
} else {
132+
break;
142133
}
143-
_ => (pat.span, format!("&{}", &snippet)),
144-
};
145-
let mut err = feature_err(sp, &tcx.sess.parse_sess);
146-
err.span_suggestion(sp, "consider using a reference", sugg);
147-
err.emit();
148-
} else {
149-
feature_err(pat.span, &tcx.sess.parse_sess).emit();
134+
} else {
135+
break;
136+
}
137+
}
138+
let sp = ref_sp.to(pat.span);
139+
let mut err = feature_gate::feature_err(
140+
&tcx.sess.parse_sess,
141+
"match_default_bindings",
142+
sp,
143+
feature_gate::GateIssue::Language,
144+
"non-reference pattern used to match a reference",
145+
);
146+
if let Ok(snippet) = tcx.sess.codemap().span_to_snippet(sp) {
147+
err.span_suggestion(sp,
148+
"consider using a reference",
149+
format!("&{}", &snippet));
150150
}
151+
err.emit();
151152
}
152153
}
153154
}

src/libsyntax_pos/lib.rs

-12
Original file line numberDiff line numberDiff line change
@@ -159,18 +159,6 @@ impl Span {
159159
Span::new(BytePos(lo), BytePos(lo), span.ctxt)
160160
}
161161

162-
/// Returns a new span representing the previous character after the start-point of this span
163-
pub fn prev_point(self) -> Span {
164-
let span = self.data();
165-
let span_lo = span.lo.0;
166-
let lo = if span_lo == 0 {
167-
0
168-
} else {
169-
span_lo - 1
170-
};
171-
Span::new(BytePos(lo), BytePos(span_lo), span.ctxt)
172-
}
173-
174162
/// Returns `self` if `self` is not the dummy span, and `other` otherwise.
175163
pub fn substitute_dummy(self, other: Span) -> Span {
176164
if self.source_equal(&DUMMY_SP) { other } else { self }

src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: non-reference pattern used to match a reference (see issue #42640)
22
--> $DIR/suggestion.rs:12:12
33
|
44
12 | if let Some(y) = &Some(22) { //~ ERROR non-reference pattern
5-
| ^^^^^^^ help: consider using: `&Some(y)`
5+
| ^^^^^^^ help: consider using a reference: `&Some(y)`
66
|
77
= help: add #![feature(match_default_bindings)] to the crate attributes to enable
88

src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: non-reference pattern used to match a reference (see issue #42640)
2-
--> dont-suggest-dereference-on-arg.rs:16:19
2+
--> $DIR/dont-suggest-dereference-on-arg.rs:16:19
33
|
44
16 | .filter(|&(ref a, _)| foo(a))
5-
| ^^^^^^^^^^^ help: consider using: `&&(ref k, _)`
5+
| ^^^^^^^^^^^ help: consider using a reference: `&&(ref k, _)`
66
|
77
= help: add #![feature(match_default_bindings)] to the crate attributes to enable
88

0 commit comments

Comments
 (0)