Skip to content

Commit 9a8ca69

Browse files
committed
Auto merge of rust-lang#77774 - petrochenkov:floatuple, r=estebank
rustc_parse: More precise spans for `tuple.0.0` This should help with rust-lang/rustfmt#4355, but I haven't verified, cc `@calebcartwright.`
2 parents 25d2d09 + dee7049 commit 9a8ca69

File tree

4 files changed

+45
-19
lines changed

4 files changed

+45
-19
lines changed

compiler/rustc_parse/src/parser/expr.rs

+33-7
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_ast_pretty::pprust;
1616
use rustc_errors::{Applicability, DiagnosticBuilder, PResult};
1717
use rustc_span::source_map::{self, Span, Spanned};
1818
use rustc_span::symbol::{kw, sym, Ident, Symbol};
19+
use rustc_span::{BytePos, Pos};
1920
use std::mem;
2021
use tracing::debug;
2122

@@ -839,9 +840,10 @@ impl<'a> Parser<'a> {
839840
}
840841
use FloatComponent::*;
841842

843+
let float_str = float.as_str();
842844
let mut components = Vec::new();
843845
let mut ident_like = String::new();
844-
for c in float.as_str().chars() {
846+
for c in float_str.chars() {
845847
if c == '_' || c.is_ascii_alphanumeric() {
846848
ident_like.push(c);
847849
} else if matches!(c, '.' | '+' | '-') {
@@ -857,30 +859,54 @@ impl<'a> Parser<'a> {
857859
components.push(IdentLike(ident_like));
858860
}
859861

860-
// FIXME: Make the span more precise.
862+
// With proc macros the span can refer to anything, the source may be too short,
863+
// or too long, or non-ASCII. It only makes sense to break our span into components
864+
// if its underlying text is identical to our float literal.
861865
let span = self.token.span;
866+
let can_take_span_apart =
867+
|| self.span_to_snippet(span).as_deref() == Ok(float_str).as_deref();
868+
862869
match &*components {
863870
// 1e2
864871
[IdentLike(i)] => {
865872
self.parse_tuple_field_access_expr(lo, base, Symbol::intern(&i), suffix, None)
866873
}
867874
// 1.
868875
[IdentLike(i), Punct('.')] => {
876+
let (ident_span, dot_span) = if can_take_span_apart() {
877+
let (span, ident_len) = (span.data(), BytePos::from_usize(i.len()));
878+
let ident_span = span.with_hi(span.lo + ident_len);
879+
let dot_span = span.with_lo(span.lo + ident_len);
880+
(ident_span, dot_span)
881+
} else {
882+
(span, span)
883+
};
869884
assert!(suffix.is_none());
870885
let symbol = Symbol::intern(&i);
871-
self.token = Token::new(token::Ident(symbol, false), span);
872-
let next_token = Token::new(token::Dot, span);
886+
self.token = Token::new(token::Ident(symbol, false), ident_span);
887+
let next_token = Token::new(token::Dot, dot_span);
873888
self.parse_tuple_field_access_expr(lo, base, symbol, None, Some(next_token))
874889
}
875890
// 1.2 | 1.2e3
876891
[IdentLike(i1), Punct('.'), IdentLike(i2)] => {
892+
let (ident1_span, dot_span, ident2_span) = if can_take_span_apart() {
893+
let (span, ident1_len) = (span.data(), BytePos::from_usize(i1.len()));
894+
let ident1_span = span.with_hi(span.lo + ident1_len);
895+
let dot_span = span
896+
.with_lo(span.lo + ident1_len)
897+
.with_hi(span.lo + ident1_len + BytePos(1));
898+
let ident2_span = self.token.span.with_lo(span.lo + ident1_len + BytePos(1));
899+
(ident1_span, dot_span, ident2_span)
900+
} else {
901+
(span, span, span)
902+
};
877903
let symbol1 = Symbol::intern(&i1);
878-
self.token = Token::new(token::Ident(symbol1, false), span);
879-
let next_token1 = Token::new(token::Dot, span);
904+
self.token = Token::new(token::Ident(symbol1, false), ident1_span);
905+
let next_token1 = Token::new(token::Dot, dot_span);
880906
let base1 =
881907
self.parse_tuple_field_access_expr(lo, base, symbol1, None, Some(next_token1));
882908
let symbol2 = Symbol::intern(&i2);
883-
let next_token2 = Token::new(token::Ident(symbol2, false), span);
909+
let next_token2 = Token::new(token::Ident(symbol2, false), ident2_span);
884910
self.bump_with(next_token2); // `.`
885911
self.parse_tuple_field_access_expr(lo, base1, symbol2, suffix, None)
886912
}

src/test/ui/parser/float-field.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -271,10 +271,10 @@ LL | s.1e1;
271271
= note: available fields are: `0`, `1`
272272

273273
error[E0609]: no field `1e1` on type `(u8, u8)`
274-
--> $DIR/float-field.rs:9:7
274+
--> $DIR/float-field.rs:9:9
275275
|
276276
LL | s.1.1e1;
277-
| ^^^^^
277+
| ^^^
278278

279279
error[E0609]: no field `0x1e1` on type `S`
280280
--> $DIR/float-field.rs:24:7
@@ -288,23 +288,23 @@ error[E0609]: no field `0x1` on type `S`
288288
--> $DIR/float-field.rs:25:7
289289
|
290290
LL | s.0x1.;
291-
| ^^^^ unknown field
291+
| ^^^ unknown field
292292
|
293293
= note: available fields are: `0`, `1`
294294

295295
error[E0609]: no field `0x1` on type `S`
296296
--> $DIR/float-field.rs:28:7
297297
|
298298
LL | s.0x1.1;
299-
| ^^^^^ unknown field
299+
| ^^^ unknown field
300300
|
301301
= note: available fields are: `0`, `1`
302302

303303
error[E0609]: no field `0x1` on type `S`
304304
--> $DIR/float-field.rs:30:7
305305
|
306306
LL | s.0x1.1e1;
307-
| ^^^^^^^ unknown field
307+
| ^^^ unknown field
308308
|
309309
= note: available fields are: `0`, `1`
310310

src/test/ui/tuple/index-invalid.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ error[E0609]: no field `1` on type `(((),),)`
22
--> $DIR/index-invalid.rs:2:22
33
|
44
LL | let _ = (((),),).1.0;
5-
| ^^^
5+
| ^
66

77
error[E0609]: no field `1` on type `((),)`
8-
--> $DIR/index-invalid.rs:4:22
8+
--> $DIR/index-invalid.rs:4:24
99
|
1010
LL | let _ = (((),),).0.1;
11-
| ^^^
11+
| ^
1212

1313
error[E0609]: no field `000` on type `(((),),)`
1414
--> $DIR/index-invalid.rs:6:22
1515
|
1616
LL | let _ = (((),),).000.000;
17-
| ^^^^^^^
17+
| ^^^
1818

1919
error: aborting due to 3 previous errors
2020

src/test/ui/union/union-deref.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ error: not automatically applying `DerefMut` on `ManuallyDrop` union field
2929
--> $DIR/union-deref.rs:23:14
3030
|
3131
LL | unsafe { u.f.0.0 = Vec::new() };
32-
| ^^^^^^^
32+
| ^^^^^
3333
|
3434
= help: writing to this reference calls the destructor for the old value
3535
= help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
@@ -38,7 +38,7 @@ error: not automatically applying `DerefMut` on `ManuallyDrop` union field
3838
--> $DIR/union-deref.rs:25:19
3939
|
4040
LL | unsafe { &mut u.f.0.0 };
41-
| ^^^^^^^
41+
| ^^^^^
4242
|
4343
= help: writing to this reference calls the destructor for the old value
4444
= help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
@@ -47,7 +47,7 @@ error: not automatically applying `DerefMut` on `ManuallyDrop` union field
4747
--> $DIR/union-deref.rs:27:14
4848
|
4949
LL | unsafe { u.f.0.0.push(0) };
50-
| ^^^^^^^
50+
| ^^^^^
5151
|
5252
= help: writing to this reference calls the destructor for the old value
5353
= help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor

0 commit comments

Comments
 (0)