Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit aaec608

Browse files
committedFeb 1, 2018
Minimize weird spans involving macro context
Sometimes the parser attempts to synthesize spans from within a macro context with the span for the captured argument, leading to non-sensical spans with very bad output. Given that an incorrect span is worse than a partially incomplete span, when detecting this situation return only one of the spans without mergin them.
1 parent bacb5c5 commit aaec608

File tree

4 files changed

+55
-8
lines changed

4 files changed

+55
-8
lines changed
 

‎src/libsyntax_pos/lib.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -361,13 +361,24 @@ impl Span {
361361

362362
/// Return a `Span` that would enclose both `self` and `end`.
363363
pub fn to(self, end: Span) -> Span {
364-
let span = self.data();
365-
let end = end.data();
364+
let span_data = self.data();
365+
let end_data = end.data();
366+
// FIXME(jseyfried): self.ctxt should always equal end.ctxt here (c.f. issue #23480)
367+
// Return the macro span on its own to avoid weird diagnostic output. It is preferable to
368+
// have an incomplete span than a completely nonsensical one.
369+
if span_data.ctxt != end_data.ctxt {
370+
if span_data.ctxt == SyntaxContext::empty() {
371+
return end;
372+
} else if end_data.ctxt == SyntaxContext::empty() {
373+
return self;
374+
}
375+
// both span fall within a macro
376+
// FIXME(estebank) check if it is the *same* macro
377+
}
366378
Span::new(
367-
cmp::min(span.lo, end.lo),
368-
cmp::max(span.hi, end.hi),
369-
// FIXME(jseyfried): self.ctxt should always equal end.ctxt here (c.f. issue #23480)
370-
if span.ctxt == SyntaxContext::empty() { end.ctxt } else { span.ctxt },
379+
cmp::min(span_data.lo, end_data.lo),
380+
cmp::max(span_data.hi, end_data.hi),
381+
if span_data.ctxt == SyntaxContext::empty() { end_data.ctxt } else { span_data.ctxt },
371382
)
372383
}
373384

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
macro_rules! bad {
12+
($s:ident whatever) => {
13+
{
14+
let $s = 0;
15+
*&mut $s = 0;
16+
//~^ ERROR cannot borrow immutable local variable `foo` as mutable [E0596]
17+
}
18+
}
19+
}
20+
21+
fn main() {
22+
bad!(foo whatever);
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0596]: cannot borrow immutable local variable `foo` as mutable
2+
--> $DIR/span-covering-argument-1.rs:15:19
3+
|
4+
14 | let $s = 0;
5+
| -- consider changing this to `mut $s`
6+
15 | *&mut $s = 0;
7+
| ^^ cannot borrow mutably
8+
...
9+
22 | bad!(foo whatever);
10+
| ------------------- in this macro invocation
11+
12+
error: aborting due to previous error
13+

‎src/test/ui/span/macro-span-replacement.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
warning: struct is never used: `S`
2-
--> $DIR/macro-span-replacement.rs:17:9
2+
--> $DIR/macro-span-replacement.rs:17:14
33
|
44
17 | $b $a; //~ WARN struct is never used
5-
| ^^^^^^
5+
| ^
66
...
77
22 | m!(S struct);
88
| ------------- in this macro invocation

0 commit comments

Comments
 (0)
Please sign in to comment.