diff --git a/compiler/rustc_lexer/src/cursor.rs b/compiler/rustc_lexer/src/cursor.rs index eceef59802eb9..138fd016e1233 100644 --- a/compiler/rustc_lexer/src/cursor.rs +++ b/compiler/rustc_lexer/src/cursor.rs @@ -55,6 +55,12 @@ impl<'a> Cursor<'a> { iter.next().unwrap_or(EOF_CHAR) } + /// Allows peeking an unbounded number of symbols from the input stream + /// without consuming them. + pub(crate) fn all(&self) -> Chars<'a> { + self.chars.clone() + } + /// Checks if there is nothing more to consume. pub(crate) fn is_eof(&self) -> bool { self.chars.as_str().is_empty() diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index d511d2b1280d9..9921e4a9268cb 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -177,7 +177,7 @@ pub enum LiteralKind { /// "12_u8", "0o100", "0b120i99", "1f32". Int { base: Base, empty_int: bool }, /// "12.34f32", "1e3", but not "1f32". - Float { base: Base, empty_exponent: bool }, + Float { base: Base }, /// "'a'", "'\\'", "'''", "';" Char { terminated: bool }, /// "b'a'", "b'\\'", "b'''", "b';" @@ -578,6 +578,28 @@ impl Cursor<'_> { } fn number(&mut self, first_digit: char) -> LiteralKind { + // Scan ahead to determine if this is a valid exponent. + fn is_exponent(cursor: &mut Cursor<'_>) -> bool { + let mut iter = cursor.all(); + let c = iter.next(); + debug_assert!(matches!(c, Some('e' | 'E'))); + + // Exponent examples: `e3`, `e+3`, `e_3`, `e-___3`, + // Non-exponent examples: `ea`, `e+a`, `e_a`, `e-___a`, `e_` + match iter.next() { + Some('0'..='9') => return true, + Some('+' | '-' | '_') => {} + _ => return false, + } + loop { + match iter.next() { + Some('0'..='9') => return true, + Some('_') => {} + _ => return false, + } + } + } + debug_assert!('0' <= self.prev() && self.prev() <= '9'); let mut base = Base::Decimal; if first_digit == '0' { @@ -628,23 +650,28 @@ impl Cursor<'_> { // might have stuff after the ., and if it does, it needs to start // with a number self.bump(); - let mut empty_exponent = false; if self.first().is_digit(10) { self.eat_decimal_digits(); match self.first() { - 'e' | 'E' => { + // Scan ahead to decide if this is an exponent. If not, + // it'll just be handled (later) as a suffix. + 'e' | 'E' if is_exponent(self) => { self.bump(); - empty_exponent = !self.eat_float_exponent(); + let empty_exponent = !self.eat_float_exponent(); + debug_assert!(!empty_exponent); } _ => (), } } - Float { base, empty_exponent } + Float { base } } - 'e' | 'E' => { + // Scan ahead to decide if this is an exponent. If not, + // it'll just be handled (later) as a suffix. + 'e' | 'E' if is_exponent(self) => { self.bump(); let empty_exponent = !self.eat_float_exponent(); - Float { base, empty_exponent } + debug_assert!(!empty_exponent); + Float { base } } _ => Int { base, empty_int: false }, } diff --git a/compiler/rustc_lexer/src/tests.rs b/compiler/rustc_lexer/src/tests.rs index e4c1787f2ccef..48ac438c98d0c 100644 --- a/compiler/rustc_lexer/src/tests.rs +++ b/compiler/rustc_lexer/src/tests.rs @@ -283,9 +283,9 @@ br###"raw"###suffix Token { kind: Whitespace, len: 1 } Token { kind: Literal { kind: Int { base: Hexadecimal, empty_int: false }, suffix_start: 5 }, len: 5 } Token { kind: Whitespace, len: 1 } - Token { kind: Literal { kind: Float { base: Decimal, empty_exponent: false }, suffix_start: 3 }, len: 3 } + Token { kind: Literal { kind: Float { base: Decimal }, suffix_start: 3 }, len: 3 } Token { kind: Whitespace, len: 1 } - Token { kind: Literal { kind: Float { base: Decimal, empty_exponent: false }, suffix_start: 6 }, len: 6 } + Token { kind: Literal { kind: Float { base: Decimal }, suffix_start: 6 }, len: 6 } Token { kind: Whitespace, len: 1 } Token { kind: Literal { kind: Int { base: Decimal, empty_int: false }, suffix_start: 1 }, len: 3 } Token { kind: Whitespace, len: 1 } diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 2d0f466e236ce..c683caf18f911 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -642,8 +642,6 @@ parse_no_digits_literal = no valid digits found for number parse_invalid_digit_literal = invalid digit for a base {$base} literal -parse_empty_exponent_float = expected at least one digit in exponent - parse_float_literal_unsupported_base = {$base} float literal is not supported parse_more_than_one_char = character literal may only contain one codepoint diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 84494eab855c4..31caf33b9937b 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1762,13 +1762,6 @@ pub struct InvalidDigitLiteral { pub base: u32, } -#[derive(Diagnostic)] -#[diag(parse_empty_exponent_float)] -pub struct EmptyExponentFloat { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(parse_float_literal_unsupported_base)] pub struct FloatLiteralUnsupportedBase { diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 51e904890028a..6180f353b6999 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -479,11 +479,7 @@ impl<'a> StringReader<'a> { (token::Integer, self.symbol_from_to(start, end)) } } - rustc_lexer::LiteralKind::Float { base, empty_exponent } => { - if empty_exponent { - let span = self.mk_sp(start, self.pos); - self.sess.emit_err(errors::EmptyExponentFloat { span }); - } + rustc_lexer::LiteralKind::Float { base } => { let base = match base { Base::Hexadecimal => Some("hexadecimal"), Base::Octal => Some("octal"), diff --git a/tests/ui/consts/const-eval/issue-104390.rs b/tests/ui/consts/const-eval/issue-104390.rs deleted file mode 100644 index 602d818245a0d..0000000000000 --- a/tests/ui/consts/const-eval/issue-104390.rs +++ /dev/null @@ -1,10 +0,0 @@ -fn f1() -> impl Sized { & 2E } //~ ERROR expected at least one digit in exponent -fn f2() -> impl Sized { && 2E } //~ ERROR expected at least one digit in exponent -fn f3() -> impl Sized { &'a 2E } //~ ERROR expected at least one digit in exponent -//~^ ERROR borrow expressions cannot be annotated with lifetimes -fn f4() -> impl Sized { &'static 2E } //~ ERROR expected at least one digit in exponent -//~^ ERROR borrow expressions cannot be annotated with lifetimes -fn f5() -> impl Sized { *& 2E } //~ ERROR expected at least one digit in exponent -fn f6() -> impl Sized { &'_ 2E } //~ ERROR expected at least one digit in exponent -//~^ ERROR borrow expressions cannot be annotated with lifetimes -fn main() {} diff --git a/tests/ui/consts/const-eval/issue-104390.stderr b/tests/ui/consts/const-eval/issue-104390.stderr deleted file mode 100644 index 865b9996ea395..0000000000000 --- a/tests/ui/consts/const-eval/issue-104390.stderr +++ /dev/null @@ -1,65 +0,0 @@ -error: expected at least one digit in exponent - --> $DIR/issue-104390.rs:1:27 - | -LL | fn f1() -> impl Sized { & 2E } - | ^^ - -error: expected at least one digit in exponent - --> $DIR/issue-104390.rs:2:28 - | -LL | fn f2() -> impl Sized { && 2E } - | ^^ - -error: expected at least one digit in exponent - --> $DIR/issue-104390.rs:3:29 - | -LL | fn f3() -> impl Sized { &'a 2E } - | ^^ - -error: expected at least one digit in exponent - --> $DIR/issue-104390.rs:5:34 - | -LL | fn f4() -> impl Sized { &'static 2E } - | ^^ - -error: expected at least one digit in exponent - --> $DIR/issue-104390.rs:7:28 - | -LL | fn f5() -> impl Sized { *& 2E } - | ^^ - -error: expected at least one digit in exponent - --> $DIR/issue-104390.rs:8:29 - | -LL | fn f6() -> impl Sized { &'_ 2E } - | ^^ - -error: borrow expressions cannot be annotated with lifetimes - --> $DIR/issue-104390.rs:3:25 - | -LL | fn f3() -> impl Sized { &'a 2E } - | ^--^^^ - | | - | annotated with lifetime here - | help: remove the lifetime annotation - -error: borrow expressions cannot be annotated with lifetimes - --> $DIR/issue-104390.rs:5:25 - | -LL | fn f4() -> impl Sized { &'static 2E } - | ^-------^^^ - | | - | annotated with lifetime here - | help: remove the lifetime annotation - -error: borrow expressions cannot be annotated with lifetimes - --> $DIR/issue-104390.rs:8:25 - | -LL | fn f6() -> impl Sized { &'_ 2E } - | ^--^^^ - | | - | annotated with lifetime here - | help: remove the lifetime annotation - -error: aborting due to 9 previous errors - diff --git a/tests/ui/consts/invalid-const-in-body.rs b/tests/ui/consts/invalid-const-in-body.rs deleted file mode 100644 index f0fa3bb7bd136..0000000000000 --- a/tests/ui/consts/invalid-const-in-body.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn f() -> impl Sized { - 2.0E - //~^ ERROR expected at least one digit in exponent -} - -fn main() {} diff --git a/tests/ui/consts/invalid-const-in-body.stderr b/tests/ui/consts/invalid-const-in-body.stderr deleted file mode 100644 index 3be6583594612..0000000000000 --- a/tests/ui/consts/invalid-const-in-body.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected at least one digit in exponent - --> $DIR/invalid-const-in-body.rs:2:5 - | -LL | 2.0E - | ^^^^ - -error: aborting due to previous error - diff --git a/tests/ui/consts/issue-91434.rs b/tests/ui/consts/issue-91434.rs deleted file mode 100644 index 001dc708f8932..0000000000000 --- a/tests/ui/consts/issue-91434.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - [9; [[9E; h]]]; - //~^ ERROR: expected at least one digit in exponent - //~| ERROR: cannot find value `h` in this scope [E0425] -} diff --git a/tests/ui/consts/issue-91434.stderr b/tests/ui/consts/issue-91434.stderr deleted file mode 100644 index 08d3ad77053d5..0000000000000 --- a/tests/ui/consts/issue-91434.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: expected at least one digit in exponent - --> $DIR/issue-91434.rs:2:11 - | -LL | [9; [[9E; h]]]; - | ^^ - -error[E0425]: cannot find value `h` in this scope - --> $DIR/issue-91434.rs:2:15 - | -LL | [9; [[9E; h]]]; - | ^ not found in this scope - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs b/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs index 66d562d2eb519..89e6904d4dd53 100644 --- a/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs +++ b/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs @@ -1,6 +1,5 @@ const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² -//~^ ERROR expected at least one digit in exponent -//~| ERROR unknown start of token: \u{2212} -//~| ERROR cannot subtract `{integer}` from `{float}` +//~^ ERROR unknown start of token: \u{2212} +//~| ERROR invalid suffix `e` for float literal fn main() {} diff --git a/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr b/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr index 26986684f0c0a..a8c6409dc1753 100644 --- a/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr +++ b/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr @@ -1,9 +1,3 @@ -error: expected at least one digit in exponent - --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:47 - | -LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² - | ^^^^^^ - error: unknown start of token: \u{2212} --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:53 | @@ -15,24 +9,13 @@ help: Unicode character '−' (Minus Sign) looks like '-' (Minus/Hyphen), but it LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e-11; // m³⋅kg⁻¹⋅s⁻² | ~ -error[E0277]: cannot subtract `{integer}` from `{float}` - --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:53 +error: invalid suffix `e` for float literal + --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:47 | LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² - | ^ no implementation for `{float} - {integer}` + | ^^^^^^ invalid suffix `e` | - = help: the trait `Sub<{integer}>` is not implemented for `{float}` - = help: the following other types implement trait `Sub`: - <&'a f32 as Sub> - <&'a f64 as Sub> - <&'a i128 as Sub> - <&'a i16 as Sub> - <&'a i32 as Sub> - <&'a i64 as Sub> - <&'a i8 as Sub> - <&'a isize as Sub> - and 48 others + = help: valid suffixes are `f32` and `f64` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/lexer/lex-bad-numeric-literals.rs b/tests/ui/lexer/lex-bad-numeric-literals.rs index 56bdc50e40d68..728889b7fc896 100644 --- a/tests/ui/lexer/lex-bad-numeric-literals.rs +++ b/tests/ui/lexer/lex-bad-numeric-literals.rs @@ -11,7 +11,6 @@ fn main() { 0x8.0e+9; //~ ERROR: hexadecimal float literal is not supported 0x9.0e-9; //~ ERROR: hexadecimal float literal is not supported 0o; //~ ERROR: no valid digits - 1e+; //~ ERROR: expected at least one digit in exponent 0x539.0; //~ ERROR: hexadecimal float literal is not supported 9900000000000000000000000000999999999999999999999999999999; //~^ ERROR: integer literal is too large diff --git a/tests/ui/lexer/lex-bad-numeric-literals.stderr b/tests/ui/lexer/lex-bad-numeric-literals.stderr index 1457541970af4..7030472b1f508 100644 --- a/tests/ui/lexer/lex-bad-numeric-literals.stderr +++ b/tests/ui/lexer/lex-bad-numeric-literals.stderr @@ -52,56 +52,50 @@ error[E0768]: no valid digits found for number LL | 0o; | ^^ -error: expected at least one digit in exponent - --> $DIR/lex-bad-numeric-literals.rs:14:5 - | -LL | 1e+; - | ^^^ - error: hexadecimal float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:15:5 + --> $DIR/lex-bad-numeric-literals.rs:14:5 | LL | 0x539.0; | ^^^^^^^ error[E0768]: no valid digits found for number - --> $DIR/lex-bad-numeric-literals.rs:26:5 + --> $DIR/lex-bad-numeric-literals.rs:25:5 | LL | 0x; | ^^ error[E0768]: no valid digits found for number - --> $DIR/lex-bad-numeric-literals.rs:27:5 + --> $DIR/lex-bad-numeric-literals.rs:26:5 | LL | 0xu32; | ^^ error[E0768]: no valid digits found for number - --> $DIR/lex-bad-numeric-literals.rs:28:5 + --> $DIR/lex-bad-numeric-literals.rs:27:5 | LL | 0ou32; | ^^ error[E0768]: no valid digits found for number - --> $DIR/lex-bad-numeric-literals.rs:29:5 + --> $DIR/lex-bad-numeric-literals.rs:28:5 | LL | 0bu32; | ^^ error[E0768]: no valid digits found for number - --> $DIR/lex-bad-numeric-literals.rs:30:5 + --> $DIR/lex-bad-numeric-literals.rs:29:5 | LL | 0b; | ^^ error: octal float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:32:5 + --> $DIR/lex-bad-numeric-literals.rs:31:5 | LL | 0o123.456; | ^^^^^^^^^ error: binary float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:34:5 + --> $DIR/lex-bad-numeric-literals.rs:33:5 | LL | 0b111.101; | ^^^^^^^^^ @@ -113,7 +107,7 @@ LL | 0o2f32; | ^^^^^^ not supported error: integer literal is too large - --> $DIR/lex-bad-numeric-literals.rs:16:5 + --> $DIR/lex-bad-numeric-literals.rs:15:5 | LL | 9900000000000000000000000000999999999999999999999999999999; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -121,7 +115,7 @@ LL | 9900000000000000000000000000999999999999999999999999999999; = note: value exceeds limit of `340282366920938463463374607431768211455` error: integer literal is too large - --> $DIR/lex-bad-numeric-literals.rs:18:5 + --> $DIR/lex-bad-numeric-literals.rs:17:5 | LL | 9900000000000000000000000000999999999999999999999999999999; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -129,7 +123,7 @@ LL | 9900000000000000000000000000999999999999999999999999999999; = note: value exceeds limit of `340282366920938463463374607431768211455` error: integer literal is too large - --> $DIR/lex-bad-numeric-literals.rs:20:5 + --> $DIR/lex-bad-numeric-literals.rs:19:5 | LL | 0b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -137,7 +131,7 @@ LL | 0b111111111111111111111111111111111111111111111111111111111111111111111 = note: value exceeds limit of `0b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111` error: integer literal is too large - --> $DIR/lex-bad-numeric-literals.rs:22:5 + --> $DIR/lex-bad-numeric-literals.rs:21:5 | LL | 0o37777777777777777777777777777777777777777770; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +139,7 @@ LL | 0o37777777777777777777777777777777777777777770; = note: value exceeds limit of `0o3777777777777777777777777777777777777777777` error: integer literal is too large - --> $DIR/lex-bad-numeric-literals.rs:24:5 + --> $DIR/lex-bad-numeric-literals.rs:23:5 | LL | 0xffffffffffffffffffffffffffffffff0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -153,17 +147,17 @@ LL | 0xffffffffffffffffffffffffffffffff0; = note: value exceeds limit of `0xffffffffffffffffffffffffffffffff` error: octal float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:31:5 + --> $DIR/lex-bad-numeric-literals.rs:30:5 | LL | 0o123f64; | ^^^^^^^^ not supported error: binary float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:33:5 + --> $DIR/lex-bad-numeric-literals.rs:32:5 | LL | 0b101f64; | ^^^^^^^^ not supported -error: aborting due to 26 previous errors +error: aborting due to 25 previous errors For more information about this error, try `rustc --explain E0768`. diff --git a/tests/ui/lexer/tricky-exponents.rs b/tests/ui/lexer/tricky-exponents.rs new file mode 100644 index 0000000000000..11824a6e2fc7a --- /dev/null +++ b/tests/ui/lexer/tricky-exponents.rs @@ -0,0 +1,81 @@ +// This tests for integer literal suffixes involving 'e' that used to be mostly +// invalid, because they were seen as floats with invalid exponents, but were +// made valid for #111615. +// +// run-pass +// check-run-results + +// Print and preserve the tokens. For tokens that the parser will accept. +// +// The `stringify!` call here is realistic: a proc macro that takes these +// kinds of tokens will typically just stringify and reparse the tokens itself. +// This means, for example, a proc macro taking CSS colours doesn't know or +// care that `aabbcc` is a an identifier token, while `112233` is an integer +// token, and `1122aa` is an integer token with a suffix. +macro_rules! p { + ($x:tt) => { println!(stringify!($x)); _ = $x } +} + +// Print and consume the tokens. For tokens that the parser will not accept. +macro_rules! q { + ($($x:tt)*) => { println!(stringify!($($x)*)) } +} + +fn main() { + p!(1e_3); // always: equivalent to `1e3` float + p!(1e_3_); // always: equivalent to `1e3` float + p!(1e____3); // always: equivalent to `1e3` float + p!(1e____3_3__); // always: equivalent to `1e33` float + p!(1e+____3); // always: equivalent to `1e+3` float + p!(1e-____3_3__); // always: equivalent to `1e-33` float + + // Decimal integers with unit suffixes + q!(1kg); // always: `1` int + `kg` suffix + q!(1ns); // always: `1` int + `ns` suffix + q!(1MW); // always: `1` int + `MW` suffix + q!(1eV); // was: invalid, now: `1` int + `eV` suffix + + // Non-decimal integers with unit suffixes + q!(0x1em); // always: `0x1e` int + `m` suffix (because `e` is a hex digit!) + q!(0o1em); // was: invalid, now: `0o1` int + `em` suffix + q!(0b1em); // was: invalid, now: `0b1` int + `em` suffix + q!(0b1e ); // was: invalid, now: `0b1` int + `e` suffix + + // Non-exponent floats with unit suffixes + q!(2.0px ); // always: `2.0` + `px` suffix + q!(2.0e ); // was: invalid, now: `2.0` + `e` suffix + q!(2.0em ); // was: invalid, now: `2.0` + `em` suffix + q!(2.0e3em); // always: `2.0e3` + `em` suffix + + // Decimal integers with suffixes containing underscores + q!(0e_ ); // was: invalid, now `0` + `e_` suffix + q!(1e_a ); // was: invalid, now `1` + `e_a` suffix + q!(1e_a_ ); // was: invalid, now `1` + `e_a_` suffix + q!(1e++ ); // was: invalid, now `1` + `e` suffix + `+` ... + q!(1e+___ ); // was: invalid, now `1` + `e` suffix + `+` ... + q!(1e-_- ); // was: invalid, now `1` + `e` suffix + `-` ... + q!(1e+____a ); // was: invalid, now `1` + `e` suffix + `+` ... + q!(1e-____a_a__); // was: invalid, now `1` + `e` suffix + `-` ... + + // Floats with suffixes containing underscores + q!(3.3e_____); // was: invalid: now `3.3` + `e_____` suffix + + // Exponent floats with unit suffixes + q!(1e3foo); // always: `1e3` + `foo` suffix + q!(1.0e3foo); // always: `1.0e3` + `foo` suffix + + // CSS colours + q!(#aabbcc); // always: `aabbcc` ident + q!(#aabb11); // always: `aabb11` ident + q!(#112233); // always: `112233` int + q!(#1122aa); // always: `1122` int + `aa` suffix + q!(#112e33); // always: `112e33` float + q!(#112e3a); // always: `112e3` float + `a` suffix + q!(#11223e); // was: invalid, now: `11223` + `e` suffix + q!(#1122ea); // was: invalid, now: `1122` + `ea` suffix + + // UUIDs + q!(7ad85a2c-f2d0-11fd-afd0-b3104db0cb68); // always: valid + q!(7ad85a2c-f2d0-11ed-afd0-b3104db0cb68); // was: invalid (11ed), now ok + q!(7ad85a2c-f2d0-111e-afd0-b3104db0cb68); // was: invalid (111e-a), now ok +} diff --git a/tests/ui/lexer/tricky-exponents.run.stdout b/tests/ui/lexer/tricky-exponents.run.stdout new file mode 100644 index 0000000000000..88d9c65f93068 --- /dev/null +++ b/tests/ui/lexer/tricky-exponents.run.stdout @@ -0,0 +1,40 @@ +1e_3 +1e_3_ +1e____3 +1e____3_3__ +1e+____3 +1e-____3_3__ +1kg +1ns +1MW +1eV +0x1em +0o1em +0b1em +0b1e +2.0px +2.0e +2.0em +2.0e3em +0e_ +1e_a +1e_a_ +1e + + +1e + ___ +1e - _ - +1e + ____a +1e - ____a_a__ +3.3e_____ +1e3foo +1.0e3foo +# aabbcc +# aabb11 +# 112233 +# 1122aa +# 112e33 +# 112e3a +# 11223e +# 1122ea +7ad85a2c - f2d0 - 11fd - afd0 - b3104db0cb68 +7ad85a2c - f2d0 - 11ed - afd0 - b3104db0cb68 +7ad85a2c - f2d0 - 111e - afd0 - b3104db0cb68 diff --git a/tests/ui/parser/bad-lit-suffixes.rs b/tests/ui/parser/bad-lit-suffixes.rs index 8cb9ef7e0c921..61e3f5e0ae1a8 100644 --- a/tests/ui/parser/bad-lit-suffixes.rs +++ b/tests/ui/parser/bad-lit-suffixes.rs @@ -25,6 +25,8 @@ fn main() { 0b101suffix; //~ ERROR invalid suffix `suffix` for number literal 1.0suffix; //~ ERROR invalid suffix `suffix` for float literal 1.0e10suffix; //~ ERROR invalid suffix `suffix` for float literal + + 1234eee //~ ERROR invalid suffix `eee` for number literal } #[rustc_dummy = "string"suffix] diff --git a/tests/ui/parser/bad-lit-suffixes.stderr b/tests/ui/parser/bad-lit-suffixes.stderr index 756f99ab12c82..1e53ee8aa65e0 100644 --- a/tests/ui/parser/bad-lit-suffixes.stderr +++ b/tests/ui/parser/bad-lit-suffixes.stderr @@ -11,25 +11,25 @@ LL | "C"suffix | ^^^^^^^^^ invalid suffix `suffix` error: unexpected expression: `"string"suffix` - --> $DIR/bad-lit-suffixes.rs:30:17 + --> $DIR/bad-lit-suffixes.rs:32:17 | LL | #[rustc_dummy = "string"suffix] | ^^^^^^^^^^^^^^ error: unexpected expression: `"string"suffix` - --> $DIR/bad-lit-suffixes.rs:34:14 + --> $DIR/bad-lit-suffixes.rs:36:14 | LL | #[must_use = "string"suffix] | ^^^^^^^^^^^^^^ error: suffixes on string literals are invalid - --> $DIR/bad-lit-suffixes.rs:38:15 + --> $DIR/bad-lit-suffixes.rs:40:15 | LL | #[link(name = "string"suffix)] | ^^^^^^^^^^^^^^ invalid suffix `suffix` error: invalid suffix `suffix` for number literal - --> $DIR/bad-lit-suffixes.rs:42:41 + --> $DIR/bad-lit-suffixes.rs:44:41 | LL | #[rustc_layout_scalar_valid_range_start(0suffix)] | ^^^^^^^ invalid suffix `suffix` @@ -136,5 +136,13 @@ LL | 1.0e10suffix; | = help: valid suffixes are `f32` and `f64` -error: aborting due to 20 previous errors +error: invalid suffix `eee` for number literal + --> $DIR/bad-lit-suffixes.rs:29:5 + | +LL | 1234eee + | ^^^^^^^ invalid suffix `eee` + | + = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) + +error: aborting due to 21 previous errors diff --git a/tests/ui/parser/float-field.rs b/tests/ui/parser/float-field.rs index eaa7465dc4d06..33504dc8a0dc2 100644 --- a/tests/ui/parser/float-field.rs +++ b/tests/ui/parser/float-field.rs @@ -7,12 +7,6 @@ fn main() { s.1.; //~ ERROR unexpected token: `;` s.1.1; s.1.1e1; //~ ERROR no field `1e1` on type `(u8, u8)` - { s.1e+; } //~ ERROR unexpected token: `1e+` - //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+` - //~| ERROR expected at least one digit in exponent - { s.1e-; } //~ ERROR unexpected token: `1e-` - //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-` - //~| ERROR expected at least one digit in exponent { s.1e+1; } //~ ERROR unexpected token: `1e+1` //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+1` { s.1e-1; } //~ ERROR unexpected token: `1e-1` @@ -45,12 +39,6 @@ fn main() { s.1.1f32; //~ ERROR suffixes on a tuple index are invalid s.1.1e1f32; //~ ERROR no field `1e1` on type `(u8, u8)` //~| ERROR suffixes on a tuple index are invalid - { s.1e+f32; } //~ ERROR unexpected token: `1e+f32` - //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+f32` - //~| ERROR expected at least one digit in exponent - { s.1e-f32; } //~ ERROR unexpected token: `1e-f32` - //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-f32` - //~| ERROR expected at least one digit in exponent { s.1e+1f32; } //~ ERROR unexpected token: `1e+1f32` //~| ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+1f32` { s.1e-1f32; } //~ ERROR unexpected token: `1e-1f32` diff --git a/tests/ui/parser/float-field.stderr b/tests/ui/parser/float-field.stderr index 7090efc5014b3..12932135b4a7f 100644 --- a/tests/ui/parser/float-field.stderr +++ b/tests/ui/parser/float-field.stderr @@ -1,263 +1,191 @@ -error: expected at least one digit in exponent - --> $DIR/float-field.rs:10:9 - | -LL | { s.1e+; } - | ^^^ - -error: expected at least one digit in exponent - --> $DIR/float-field.rs:13:9 - | -LL | { s.1e-; } - | ^^^ - error: hexadecimal float literal is not supported - --> $DIR/float-field.rs:25:7 + --> $DIR/float-field.rs:19:7 | LL | s.0x1.; | ^^^^ error: hexadecimal float literal is not supported - --> $DIR/float-field.rs:28:7 + --> $DIR/float-field.rs:22:7 | LL | s.0x1.1; | ^^^^^ error: hexadecimal float literal is not supported - --> $DIR/float-field.rs:30:7 + --> $DIR/float-field.rs:24:7 | LL | s.0x1.1e1; | ^^^^^^^ error: hexadecimal float literal is not supported - --> $DIR/float-field.rs:36:9 + --> $DIR/float-field.rs:30:9 | LL | { s.0x1.1e+1; } | ^^^^^^^^ error: hexadecimal float literal is not supported - --> $DIR/float-field.rs:39:9 + --> $DIR/float-field.rs:33:9 | LL | { s.0x1.1e-1; } | ^^^^^^^^ -error: expected at least one digit in exponent - --> $DIR/float-field.rs:48:9 - | -LL | { s.1e+f32; } - | ^^^^^^ - -error: expected at least one digit in exponent - --> $DIR/float-field.rs:51:9 - | -LL | { s.1e-f32; } - | ^^^^^^ - error: unexpected token: `;` --> $DIR/float-field.rs:7:9 | LL | s.1.; | ^ -error: unexpected token: `1e+` - --> $DIR/float-field.rs:10:9 - | -LL | { s.1e+; } - | ^^^ - -error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+` - --> $DIR/float-field.rs:10:9 - | -LL | { s.1e+; } - | ^^^ expected one of `.`, `;`, `?`, `}`, or an operator - -error: unexpected token: `1e-` - --> $DIR/float-field.rs:13:9 - | -LL | { s.1e-; } - | ^^^ - -error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-` - --> $DIR/float-field.rs:13:9 - | -LL | { s.1e-; } - | ^^^ expected one of `.`, `;`, `?`, `}`, or an operator - error: unexpected token: `1e+1` - --> $DIR/float-field.rs:16:9 + --> $DIR/float-field.rs:10:9 | LL | { s.1e+1; } | ^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+1` - --> $DIR/float-field.rs:16:9 + --> $DIR/float-field.rs:10:9 | LL | { s.1e+1; } | ^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `1e-1` - --> $DIR/float-field.rs:18:9 + --> $DIR/float-field.rs:12:9 | LL | { s.1e-1; } | ^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-1` - --> $DIR/float-field.rs:18:9 + --> $DIR/float-field.rs:12:9 | LL | { s.1e-1; } | ^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `1.1e+1` - --> $DIR/float-field.rs:20:9 + --> $DIR/float-field.rs:14:9 | LL | { s.1.1e+1; } | ^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e+1` - --> $DIR/float-field.rs:20:9 + --> $DIR/float-field.rs:14:9 | LL | { s.1.1e+1; } | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `1.1e-1` - --> $DIR/float-field.rs:22:9 + --> $DIR/float-field.rs:16:9 | LL | { s.1.1e-1; } | ^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e-1` - --> $DIR/float-field.rs:22:9 + --> $DIR/float-field.rs:16:9 | LL | { s.1.1e-1; } | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `;` - --> $DIR/float-field.rs:25:11 + --> $DIR/float-field.rs:19:11 | LL | s.0x1.; | ^ error: expected expression, found `;` - --> $DIR/float-field.rs:32:14 + --> $DIR/float-field.rs:26:14 | LL | { s.0x1e+; } | ^ expected expression error: expected expression, found `;` - --> $DIR/float-field.rs:33:14 + --> $DIR/float-field.rs:27:14 | LL | { s.0x1e-; } | ^ expected expression error: unexpected token: `0x1.1e+1` - --> $DIR/float-field.rs:36:9 + --> $DIR/float-field.rs:30:9 | LL | { s.0x1.1e+1; } | ^^^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e+1` - --> $DIR/float-field.rs:36:9 + --> $DIR/float-field.rs:30:9 | LL | { s.0x1.1e+1; } | ^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `0x1.1e-1` - --> $DIR/float-field.rs:39:9 + --> $DIR/float-field.rs:33:9 | LL | { s.0x1.1e-1; } | ^^^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `0x1.1e-1` - --> $DIR/float-field.rs:39:9 + --> $DIR/float-field.rs:33:9 | LL | { s.0x1.1e-1; } | ^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: suffixes on a tuple index are invalid - --> $DIR/float-field.rs:42:7 + --> $DIR/float-field.rs:36:7 | LL | s.1e1f32; | ^^^^^^ invalid suffix `f32` error: suffixes on a tuple index are invalid - --> $DIR/float-field.rs:45:7 + --> $DIR/float-field.rs:39:7 | LL | s.1.1f32; | ^^^^^^ invalid suffix `f32` error: suffixes on a tuple index are invalid - --> $DIR/float-field.rs:46:7 + --> $DIR/float-field.rs:40:7 | LL | s.1.1e1f32; | ^^^^^^^^ invalid suffix `f32` -error: unexpected token: `1e+f32` - --> $DIR/float-field.rs:48:9 - | -LL | { s.1e+f32; } - | ^^^^^^ - -error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+f32` - --> $DIR/float-field.rs:48:9 - | -LL | { s.1e+f32; } - | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator - -error: unexpected token: `1e-f32` - --> $DIR/float-field.rs:51:9 - | -LL | { s.1e-f32; } - | ^^^^^^ - -error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-f32` - --> $DIR/float-field.rs:51:9 - | -LL | { s.1e-f32; } - | ^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator - error: unexpected token: `1e+1f32` - --> $DIR/float-field.rs:54:9 + --> $DIR/float-field.rs:42:9 | LL | { s.1e+1f32; } | ^^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e+1f32` - --> $DIR/float-field.rs:54:9 + --> $DIR/float-field.rs:42:9 | LL | { s.1e+1f32; } | ^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `1e-1f32` - --> $DIR/float-field.rs:56:9 + --> $DIR/float-field.rs:44:9 | LL | { s.1e-1f32; } | ^^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1e-1f32` - --> $DIR/float-field.rs:56:9 + --> $DIR/float-field.rs:44:9 | LL | { s.1e-1f32; } | ^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `1.1e+1f32` - --> $DIR/float-field.rs:58:9 + --> $DIR/float-field.rs:46:9 | LL | { s.1.1e+1f32; } | ^^^^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e+1f32` - --> $DIR/float-field.rs:58:9 + --> $DIR/float-field.rs:46:9 | LL | { s.1.1e+1f32; } | ^^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator error: unexpected token: `1.1e-1f32` - --> $DIR/float-field.rs:60:9 + --> $DIR/float-field.rs:48:9 | LL | { s.1.1e-1f32; } | ^^^^^^^^^ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `1.1e-1f32` - --> $DIR/float-field.rs:60:9 + --> $DIR/float-field.rs:48:9 | LL | { s.1.1e-1f32; } | ^^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator @@ -277,7 +205,7 @@ LL | s.1.1e1; | ^^^ error[E0609]: no field `0x1e1` on type `S` - --> $DIR/float-field.rs:24:7 + --> $DIR/float-field.rs:18:7 | LL | s.0x1e1; | ^^^^^ unknown field @@ -285,7 +213,7 @@ LL | s.0x1e1; = note: available fields are: `0`, `1` error[E0609]: no field `0x1` on type `S` - --> $DIR/float-field.rs:25:7 + --> $DIR/float-field.rs:19:7 | LL | s.0x1.; | ^^^ unknown field @@ -293,7 +221,7 @@ LL | s.0x1.; = note: available fields are: `0`, `1` error[E0609]: no field `0x1` on type `S` - --> $DIR/float-field.rs:28:7 + --> $DIR/float-field.rs:22:7 | LL | s.0x1.1; | ^^^ unknown field @@ -301,7 +229,7 @@ LL | s.0x1.1; = note: available fields are: `0`, `1` error[E0609]: no field `0x1` on type `S` - --> $DIR/float-field.rs:30:7 + --> $DIR/float-field.rs:24:7 | LL | s.0x1.1e1; | ^^^ unknown field @@ -309,7 +237,7 @@ LL | s.0x1.1e1; = note: available fields are: `0`, `1` error[E0609]: no field `0x1e` on type `S` - --> $DIR/float-field.rs:34:7 + --> $DIR/float-field.rs:28:7 | LL | s.0x1e+1; | ^^^^ unknown field @@ -317,7 +245,7 @@ LL | s.0x1e+1; = note: available fields are: `0`, `1` error[E0609]: no field `0x1e` on type `S` - --> $DIR/float-field.rs:35:7 + --> $DIR/float-field.rs:29:7 | LL | s.0x1e-1; | ^^^^ unknown field @@ -325,7 +253,7 @@ LL | s.0x1e-1; = note: available fields are: `0`, `1` error[E0609]: no field `1e1` on type `S` - --> $DIR/float-field.rs:42:7 + --> $DIR/float-field.rs:36:7 | LL | s.1e1f32; | ^^^^^^ unknown field @@ -333,17 +261,17 @@ LL | s.1e1f32; = note: available fields are: `0`, `1` error[E0609]: no field `f32` on type `(u8, u8)` - --> $DIR/float-field.rs:44:9 + --> $DIR/float-field.rs:38:9 | LL | s.1.f32; | ^^^ error[E0609]: no field `1e1` on type `(u8, u8)` - --> $DIR/float-field.rs:46:7 + --> $DIR/float-field.rs:40:7 | LL | s.1.1e1f32; | ^^^^^^^^ -error: aborting due to 55 previous errors +error: aborting due to 43 previous errors For more information about this error, try `rustc --explain E0609`. diff --git a/tests/ui/parser/issue-90728.rs b/tests/ui/parser/issue-90728.rs deleted file mode 100644 index d6a898361ccaf..0000000000000 --- a/tests/ui/parser/issue-90728.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - a.5.2E+ - //~^ ERROR: unexpected token: `5.2E+` - //~| ERROR: expected one of `.`, `;`, `?`, `}`, or an operator, found `5.2E+` - //~| ERROR: expected at least one digit in exponent -} diff --git a/tests/ui/parser/issue-90728.stderr b/tests/ui/parser/issue-90728.stderr deleted file mode 100644 index b55c460306688..0000000000000 --- a/tests/ui/parser/issue-90728.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: expected at least one digit in exponent - --> $DIR/issue-90728.rs:2:7 - | -LL | a.5.2E+ - | ^^^^^ - -error: unexpected token: `5.2E+` - --> $DIR/issue-90728.rs:2:7 - | -LL | a.5.2E+ - | ^^^^^ - -error: expected one of `.`, `;`, `?`, `}`, or an operator, found `5.2E+` - --> $DIR/issue-90728.rs:2:7 - | -LL | a.5.2E+ - | ^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator - -error: aborting due to 3 previous errors -