Skip to content

Commit edd2574

Browse files
authored
Rollup merge of #144711 - compiler-errors:op-span, r=petrochenkov
Consider operator's span when computing binop expr span When computing the span of a binop consisting of `lhs` and `rhs`, we previously just took the spans of `lhs.span.to(rhs.span)`. In the case that both `lhs` and `rhs` are both arguments to a macro, this can produce a wildly incorrect span. To fix this, first compute the span between `lhs` and the binary operator, which will cause `lhs` to possibly be adjusted to a relevant macro metavar, and then compute that span extended to `rhs`, which will cause it to also be adjusted to a relevant macro metavar. This coincidentally fixes a FIXME in `tests/ui/lint/wide_pointer_comparisons.rs` and suppresses a nonsense suggestion.
2 parents eec13cd + 51cd9b5 commit edd2574

File tree

4 files changed

+20
-17
lines changed

4 files changed

+20
-17
lines changed

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,11 @@ impl<'a> Parser<'a> {
263263
continue;
264264
}
265265

266+
let op_span = op.span;
266267
let op = op.node;
267268
// Special cases:
268269
if op == AssocOp::Cast {
269-
lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Cast)?;
270+
lhs = self.parse_assoc_op_cast(lhs, lhs_span, op_span, ExprKind::Cast)?;
270271
continue;
271272
} else if let AssocOp::Range(limits) = op {
272273
// If we didn't have to handle `x..`/`x..=`, it would be pretty easy to
@@ -284,7 +285,7 @@ impl<'a> Parser<'a> {
284285
this.parse_expr_assoc_with(min_prec, attrs)
285286
})?;
286287

287-
let span = self.mk_expr_sp(&lhs, lhs_span, rhs.span);
288+
let span = self.mk_expr_sp(&lhs, lhs_span, op_span, rhs.span);
288289
lhs = match op {
289290
AssocOp::Binary(ast_op) => {
290291
let binary = self.mk_binary(source_map::respan(cur_op_span, ast_op), lhs, rhs);
@@ -429,7 +430,7 @@ impl<'a> Parser<'a> {
429430
None
430431
};
431432
let rhs_span = rhs.as_ref().map_or(cur_op_span, |x| x.span);
432-
let span = self.mk_expr_sp(&lhs, lhs.span, rhs_span);
433+
let span = self.mk_expr_sp(&lhs, lhs.span, cur_op_span, rhs_span);
433434
let range = self.mk_range(Some(lhs), rhs, limits);
434435
Ok(self.mk_expr(span, range))
435436
}
@@ -654,10 +655,11 @@ impl<'a> Parser<'a> {
654655
&mut self,
655656
lhs: P<Expr>,
656657
lhs_span: Span,
658+
op_span: Span,
657659
expr_kind: fn(P<Expr>, P<Ty>) -> ExprKind,
658660
) -> PResult<'a, P<Expr>> {
659661
let mk_expr = |this: &mut Self, lhs: P<Expr>, rhs: P<Ty>| {
660-
this.mk_expr(this.mk_expr_sp(&lhs, lhs_span, rhs.span), expr_kind(lhs, rhs))
662+
this.mk_expr(this.mk_expr_sp(&lhs, lhs_span, op_span, rhs.span), expr_kind(lhs, rhs))
661663
};
662664

663665
// Save the state of the parser before parsing type normally, in case there is a
@@ -4005,11 +4007,12 @@ impl<'a> Parser<'a> {
40054007

40064008
/// Create expression span ensuring the span of the parent node
40074009
/// is larger than the span of lhs and rhs, including the attributes.
4008-
fn mk_expr_sp(&self, lhs: &P<Expr>, lhs_span: Span, rhs_span: Span) -> Span {
4010+
fn mk_expr_sp(&self, lhs: &P<Expr>, lhs_span: Span, op_span: Span, rhs_span: Span) -> Span {
40094011
lhs.attrs
40104012
.iter()
40114013
.find(|a| a.style == AttrStyle::Outer)
40124014
.map_or(lhs_span, |a| a.span)
4015+
.to(op_span)
40134016
.to(rhs_span)
40144017
}
40154018

compiler/rustc_parse/src/validate_attr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Met
106106
res
107107
} else {
108108
// Example cases:
109-
// - `#[foo = 1+1]`: results in `ast::ExprKind::BinOp`.
109+
// - `#[foo = 1+1]`: results in `ast::ExprKind::Binary`.
110110
// - `#[foo = include_str!("nonexistent-file.rs")]`:
111111
// results in `ast::ExprKind::Err`. In that case we delay
112112
// the error because an earlier error will have already

tests/ui/lint/wide_pointer_comparisons.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,10 @@ fn main() {
146146
{
147147
macro_rules! cmp {
148148
($a:tt, $b:tt) => { $a == $b }
149+
//~^ WARN ambiguous wide pointer comparison
149150
}
150151

151-
// FIXME: This lint uses some custom span combination logic.
152-
// Rewrite it to adapt to the new metavariable span rules.
153152
cmp!(a, b);
154-
//~^ WARN ambiguous wide pointer comparison
155153
}
156154

157155
{

tests/ui/lint/wide_pointer_comparisons.stderr

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -720,18 +720,20 @@ LL + std::ptr::eq(*a, *b)
720720
|
721721

722722
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
723-
--> $DIR/wide_pointer_comparisons.rs:153:14
723+
--> $DIR/wide_pointer_comparisons.rs:148:33
724724
|
725+
LL | ($a:tt, $b:tt) => { $a == $b }
726+
| ^^^^^^^^
727+
...
725728
LL | cmp!(a, b);
726-
| ^^^^
727-
|
728-
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
729+
| ---------- in this macro invocation
729730
|
730-
LL | cmp!(std::ptr::addr_eq(a, b));
731-
| ++++++++++++++++++ +
731+
= help: use explicit `std::ptr::eq` method to compare metadata and addresses
732+
= help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
733+
= note: this warning originates in the macro `cmp` (in Nightly builds, run with -Z macro-backtrace for more info)
732734

733735
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
734-
--> $DIR/wide_pointer_comparisons.rs:159:39
736+
--> $DIR/wide_pointer_comparisons.rs:157:39
735737
|
736738
LL | ($a:ident, $b:ident) => { $a == $b }
737739
| ^^^^^^^^
@@ -747,7 +749,7 @@ LL + ($a:ident, $b:ident) => { std::ptr::addr_eq($a, $b) }
747749
|
748750

749751
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
750-
--> $DIR/wide_pointer_comparisons.rs:169:37
752+
--> $DIR/wide_pointer_comparisons.rs:167:37
751753
|
752754
LL | ($a:expr, $b:expr) => { $a == $b }
753755
| ^^^^^^^^

0 commit comments

Comments
 (0)