mirror of https://github.com/rust-lang/rust
81 lines
3.1 KiB
Rust
81 lines
3.1 KiB
Rust
// This test is about the treatment of invalid literals. In particular, some
|
|
// literals are only considered invalid if they survive to HIR lowering.
|
|
//
|
|
// Literals with bad suffixes
|
|
// --------------------------
|
|
// Literals consist of a primary part and an optional suffix.
|
|
// https://doc.rust-lang.org/reference/tokens.html#suffixes says:
|
|
//
|
|
// Any kind of literal (string, integer, etc) with any suffix is valid as a
|
|
// token, and can be passed to a macro without producing an error. The macro
|
|
// itself will decide how to interpret such a token and whether to produce an
|
|
// error or not.
|
|
//
|
|
// ```
|
|
// macro_rules! blackhole { ($tt:tt) => () }
|
|
// blackhole!("string"suffix); // OK
|
|
// ```
|
|
//
|
|
// However, suffixes on literal tokens parsed as Rust code are restricted.
|
|
// Any suffixes are rejected on non-numeric literal tokens, and numeric
|
|
// literal tokens are accepted only with suffixes from the list below.
|
|
//
|
|
// Integer: u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize
|
|
// Floating-point: f32, f64
|
|
//
|
|
// This means that something like `"string"any_suffix` is a token accepted by
|
|
// the lexer, but rejected later for being an invalid combination of primary
|
|
// part and suffix.
|
|
//
|
|
// `0b10f32` is a similar case. `0b10` is a valid primary part that is a valid
|
|
// *integer* literal when no suffix is present. It only causes an error later
|
|
// when combined with the `f32` float suffix.
|
|
//
|
|
// However, `0b10.0f32` is different. It is rejected by the lexer because
|
|
// `0b10.0` is not a valid token even on its own.
|
|
//
|
|
// This difference is unfortunate, but it's baked into the language now.
|
|
//
|
|
// Too-large integer literals
|
|
// --------------------------
|
|
// https://doc.rust-lang.org/reference/tokens.html#integer-literals says that
|
|
// literals like `128_i8` and `256_u8` "are too big for their type, but are
|
|
// still valid tokens".
|
|
|
|
macro_rules! sink {
|
|
($($x:tt;)*) => {()}
|
|
}
|
|
|
|
// The invalid literals are ignored because the macro consumes them. Except for
|
|
// `0b10.0f32` because it's a lexer error.
|
|
const _: () = sink! {
|
|
"string"any_suffix; // OK
|
|
10u123; // OK
|
|
10.0f123; // OK
|
|
0b10f32; // OK
|
|
0b10.0f32; //~ ERROR binary float literal is not supported
|
|
999340282366920938463463374607431768211455999; // OK
|
|
};
|
|
|
|
// The invalid literals used to cause errors, but this was changed by #102944.
|
|
// Except for `0b010.0f32`, because it's a lexer error.
|
|
#[cfg(FALSE)]
|
|
fn configured_out() {
|
|
"string"any_suffix; // OK
|
|
10u123; // OK
|
|
10.0f123; // OK
|
|
0b10f32; // OK
|
|
0b10.0f32; //~ ERROR binary float literal is not supported
|
|
999340282366920938463463374607431768211455999; // OK
|
|
}
|
|
|
|
// All the invalid literals cause errors.
|
|
fn main() {
|
|
"string"any_suffix; //~ ERROR suffixes on string literals are invalid
|
|
10u123; //~ ERROR invalid width `123` for integer literal
|
|
10.0f123; //~ ERROR invalid width `123` for float literal
|
|
0b10f32; //~ ERROR binary float literal is not supported
|
|
0b10.0f32; //~ ERROR binary float literal is not supported
|
|
999340282366920938463463374607431768211455999; //~ ERROR integer literal is too large
|
|
}
|