Skip to content

Commit a0036cb

Browse files
committed
Fix spans for binary operator expression with interpolated identifiers
1 parent 7a75d2b commit a0036cb

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

src/libsyntax/parse/parser.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,14 @@ fn maybe_append(mut lhs: Vec<Attribute>, rhs: Option<Vec<Attribute>>)
150150
lhs
151151
}
152152

153-
#[derive(Clone, PartialEq)]
153+
#[derive(Clone, Copy, PartialEq)]
154154
enum PrevTokenKind {
155155
DocComment,
156156
Comma,
157157
Plus,
158158
Interpolated,
159159
Eof,
160+
Ident,
160161
Other,
161162
}
162163

@@ -1040,6 +1041,7 @@ impl<'a> Parser<'a> {
10401041
token::BinOp(token::Plus) => PrevTokenKind::Plus,
10411042
token::Interpolated(..) => PrevTokenKind::Interpolated,
10421043
token::Eof => PrevTokenKind::Eof,
1044+
token::Ident(..) => PrevTokenKind::Ident,
10431045
_ => PrevTokenKind::Other,
10441046
};
10451047

@@ -2774,10 +2776,15 @@ impl<'a> Parser<'a> {
27742776
self.expected_tokens.push(TokenType::Operator);
27752777
while let Some(op) = AssocOp::from_token(&self.token) {
27762778

2777-
let lhs_span = if self.prev_token_kind == PrevTokenKind::Interpolated {
2778-
self.prev_span
2779-
} else {
2780-
lhs.span
2779+
// Adjust the span for interpolated LHS to point to the `$lhs` token and not to what
2780+
// it refers to. Interpolated identifiers are unwrapped early and never show up here
2781+
// as `PrevTokenKind::Interpolated` so if LHS is a single identifier we always process
2782+
// it as "interpolated", it doesn't change the answer for non-interpolated idents.
2783+
let lhs_span = match (self.prev_token_kind, &lhs.node) {
2784+
(PrevTokenKind::Interpolated, _) => self.prev_span,
2785+
(PrevTokenKind::Ident, &ExprKind::Path(None, ref path))
2786+
if path.segments.len() == 1 => self.prev_span,
2787+
_ => lhs.span,
27812788
};
27822789

27832790
let cur_op_span = self.span;

src/test/ui/issue-42954.rs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2017 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! is_plainly_printable {
12+
($i: ident) => {
13+
$i as u32 < 0
14+
};
15+
}
16+
17+
fn main() {
18+
let c = 'a';
19+
is_plainly_printable!(c);
20+
}

src/test/ui/issue-42954.stderr

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error: `<` is interpreted as a start of generic arguments for `u32`, not a comparison
2+
--> $DIR/issue-42954.rs:13:19
3+
|
4+
13 | $i as u32 < 0
5+
| - ^ interpreted as generic argument
6+
| |
7+
| not interpreted as comparison
8+
|
9+
help: if you want to compare the casted value then write:
10+
| ($i as u32) < 0
11+
12+
error: aborting due to previous error
13+

0 commit comments

Comments
 (0)