Skip to content

Commit 9d995d2

Browse files
committed
Rollup merge of #47942 - estebank:macro-spans, r=nikomatsakis 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 merging them. Fix #32072, #47778. CC #23480.
2 parents 7c6380c + aaec608 commit 9d995d2

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
@@ -347,13 +347,24 @@ impl Span {
347347

348348
/// Return a `Span` that would enclose both `self` and `end`.
349349
pub fn to(self, end: Span) -> Span {
350-
let span = self.data();
351-
let end = end.data();
350+
let span_data = self.data();
351+
let end_data = end.data();
352+
// FIXME(jseyfried): self.ctxt should always equal end.ctxt here (c.f. issue #23480)
353+
// Return the macro span on its own to avoid weird diagnostic output. It is preferable to
354+
// have an incomplete span than a completely nonsensical one.
355+
if span_data.ctxt != end_data.ctxt {
356+
if span_data.ctxt == SyntaxContext::empty() {
357+
return end;
358+
} else if end_data.ctxt == SyntaxContext::empty() {
359+
return self;
360+
}
361+
// both span fall within a macro
362+
// FIXME(estebank) check if it is the *same* macro
363+
}
352364
Span::new(
353-
cmp::min(span.lo, end.lo),
354-
cmp::max(span.hi, end.hi),
355-
// FIXME(jseyfried): self.ctxt should always equal end.ctxt here (c.f. issue #23480)
356-
if span.ctxt == SyntaxContext::empty() { end.ctxt } else { span.ctxt },
365+
cmp::min(span_data.lo, end_data.lo),
366+
cmp::max(span_data.hi, end_data.hi),
367+
if span_data.ctxt == SyntaxContext::empty() { end_data.ctxt } else { span_data.ctxt },
357368
)
358369
}
359370

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)