Skip to content

Allow integer suffixes starting with e. #111628

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions compiler/rustc_lexer/src/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
41 changes: 34 additions & 7 deletions compiler/rustc_lexer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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';"
Expand Down Expand Up @@ -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' {
Expand Down Expand Up @@ -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 },
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_lexer/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_parse/src/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down
10 changes: 0 additions & 10 deletions tests/ui/consts/const-eval/issue-104390.rs

This file was deleted.

65 changes: 0 additions & 65 deletions tests/ui/consts/const-eval/issue-104390.stderr

This file was deleted.

6 changes: 0 additions & 6 deletions tests/ui/consts/invalid-const-in-body.rs

This file was deleted.

8 changes: 0 additions & 8 deletions tests/ui/consts/invalid-const-in-body.stderr

This file was deleted.

5 changes: 0 additions & 5 deletions tests/ui/consts/issue-91434.rs

This file was deleted.

15 changes: 0 additions & 15 deletions tests/ui/consts/issue-91434.stderr

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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
|
Expand All @@ -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<Rhs>`:
<&'a f32 as Sub<f32>>
<&'a f64 as Sub<f64>>
<&'a i128 as Sub<i128>>
<&'a i16 as Sub<i16>>
<&'a i32 as Sub<i32>>
<&'a i64 as Sub<i64>>
<&'a i8 as Sub<i8>>
<&'a isize as Sub<isize>>
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`.
1 change: 0 additions & 1 deletion tests/ui/lexer/lex-bad-numeric-literals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading