diff --git a/Cargo.lock b/Cargo.lock index 9f82b2e164027..7e59d5e0c5e3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3457,6 +3457,7 @@ dependencies = [ "rustc_index", "rustc_macros", "rustc_middle", + "rustc_parse", "rustc_session", "rustc_span", "rustc_target", diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index 8cc4521e0a78d..285468bae1f84 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -17,6 +17,7 @@ rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } +rustc_parse = { path = "../rustc_parse" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index a44b408feec25..b60028119ceb7 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -14,7 +14,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_middle::span_bug; -use rustc_session::errors::report_lit_error; +use rustc_parse::parser::report_lit_error; use rustc_span::source_map::{respan, Spanned}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::DUMMY_SP; diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs index 6b8330bfdaf92..6c83e8868bd31 100644 --- a/compiler/rustc_builtin_macros/src/concat.rs +++ b/compiler/rustc_builtin_macros/src/concat.rs @@ -1,7 +1,7 @@ use rustc_ast as ast; use rustc_ast::tokenstream::TokenStream; use rustc_expand::base::{self, DummyResult}; -use rustc_session::errors::report_lit_error; +use rustc_parse::parser::report_lit_error; use rustc_span::symbol::Symbol; use crate::errors; diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs index 96e9584c20955..4ae328160f0c8 100644 --- a/compiler/rustc_builtin_macros/src/concat_bytes.rs +++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs @@ -1,7 +1,7 @@ use rustc_ast as ast; use rustc_ast::{ptr::P, tokenstream::TokenStream}; use rustc_expand::base::{self, DummyResult}; -use rustc_session::errors::report_lit_error; +use rustc_parse::parser::report_lit_error; use rustc_span::Span; use crate::errors; diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 11db4bb401762..c9bbea47185b7 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -21,8 +21,7 @@ use rustc_errors::{ use rustc_feature::Features; use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT; use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics, RegisteredTools}; -use rustc_parse::{parser, MACRO_ARGUMENTS}; -use rustc_session::errors::report_lit_error; +use rustc_parse::{self, parser, MACRO_ARGUMENTS}; use rustc_session::{parse::ParseSess, Limit, Session}; use rustc_span::def_id::{CrateNum, DefId, LocalDefId}; use rustc_span::edition::Edition; @@ -1251,7 +1250,7 @@ pub fn expr_to_spanned_string<'a>( } Ok(ast::LitKind::Err) => None, Err(err) => { - report_lit_error(&cx.sess.parse_sess, err, token_lit, expr.span); + parser::report_lit_error(&cx.sess.parse_sess, err, token_lit, expr.span); None } _ => Some((cx.struct_span_err(expr.span, err_msg), false)), diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 59bea69af68d3..b6b8f108bbb41 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -59,6 +59,8 @@ parse_bare_cr = {$double_quotes -> parse_bare_cr_in_raw_string = bare CR not allowed in raw string +parse_binary_float_literal_not_supported = binary float literal is not supported + parse_bounds_not_allowed_on_trait_aliases = bounds are not allowed on trait aliases parse_box_not_pat = expected pattern, found {$descr} @@ -292,7 +294,11 @@ parse_generic_parameters_without_angle_brackets = generic parameters without sur parse_generics_in_path = unexpected generic arguments in path parse_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml` + parse_help_set_edition_standalone = pass `--edition {$edition}` to `rustc` + +parse_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported + parse_if_expression_missing_condition = missing condition for `if` expression .condition_label = expected condition here .block_label = if this block is the condition of the `if` expression, then it must be followed by another block @@ -364,6 +370,9 @@ parse_inner_doc_comment_not_permitted = expected outer doc comment .label_does_not_annotate_this = the inner doc comment doesn't annotate this {$item} .sugg_change_inner_to_outer = to annotate the {$item}, change the doc comment from inner to outer style +parse_int_literal_too_large = integer literal is too large + .note = value exceeds limit of `{$limit}` + parse_invalid_block_macro_segment = cannot use a `block` macro fragment here .label = the `block` fragment is within this context .suggestion = wrap this in another block @@ -388,8 +397,18 @@ parse_invalid_dyn_keyword = invalid `dyn` keyword .suggestion = remove this keyword parse_invalid_expression_in_let_else = a `{$operator}` expression cannot be directly assigned in `let...else` +parse_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal + .label = invalid suffix `{$suffix}` + .help = valid suffixes are `f32` and `f64` + +parse_invalid_float_literal_width = invalid width `{$width}` for float literal + .help = valid widths are 32 and 64 + parse_invalid_identifier_with_leading_number = identifiers cannot start with a number +parse_invalid_int_literal_width = invalid width `{$width}` for integer literal + .help = valid widths are 8, 16, 32, 64 and 128 + parse_invalid_interpolated_expression = invalid interpolated expression parse_invalid_literal_suffix = suffixes on {$kind} literals are invalid @@ -408,6 +427,14 @@ parse_invalid_logical_operator = `{$incorrect}` is not a logical operator parse_invalid_meta_item = expected unsuffixed literal or identifier, found `{$token}` +parse_invalid_num_literal_base_prefix = invalid base prefix for number literal + .note = base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + .suggestion = try making the prefix lowercase + +parse_invalid_num_literal_suffix = invalid suffix `{$suffix}` for number literal + .label = invalid suffix `{$suffix}` + .help = the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) + parse_invalid_unicode_escape = invalid unicode character escape .label = invalid escape .help = unicode escape must {$surrogate -> @@ -614,6 +641,8 @@ parse_note_pattern_alternatives_use_single_vert = alternatives in or-patterns ar parse_nul_in_c_str = null characters in C string literals are not supported +parse_octal_float_literal_not_supported = octal float literal is not supported + parse_or_pattern_not_allowed_in_fn_parameters = top-level or-patterns are not allowed in function parameters parse_or_pattern_not_allowed_in_let_binding = top-level or-patterns are not allowed in `let` bindings parse_out_of_range_hex_escape = out of range hex escape diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 878433a4dc63e..3f6a361c32c5c 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2902,3 +2902,95 @@ pub(crate) struct TransposeDynOrImplSugg<'a> { pub insertion_span: Span, pub kw: &'a str, } + +#[derive(Diagnostic)] +#[diag(parse_invalid_literal_suffix)] +pub(crate) struct InvalidLiteralSuffix<'a> { + #[primary_span] + #[label] + pub span: Span, + // FIXME(#100717) + pub kind: &'a str, + pub suffix: Symbol, +} + +#[derive(Diagnostic)] +#[diag(parse_invalid_int_literal_width)] +#[help] +pub(crate) struct InvalidIntLiteralWidth { + #[primary_span] + pub span: Span, + pub width: String, +} + +#[derive(Diagnostic)] +#[diag(parse_invalid_num_literal_base_prefix)] +#[note] +pub(crate) struct InvalidNumLiteralBasePrefix { + #[primary_span] + #[suggestion(applicability = "maybe-incorrect", code = "{fixed}")] + pub span: Span, + pub fixed: String, +} + +#[derive(Diagnostic)] +#[diag(parse_invalid_num_literal_suffix)] +#[help] +pub(crate) struct InvalidNumLiteralSuffix { + #[primary_span] + #[label] + pub span: Span, + pub suffix: String, +} + +#[derive(Diagnostic)] +#[diag(parse_invalid_float_literal_width)] +#[help] +pub(crate) struct InvalidFloatLiteralWidth { + #[primary_span] + pub span: Span, + pub width: String, +} + +#[derive(Diagnostic)] +#[diag(parse_invalid_float_literal_suffix)] +#[help] +pub(crate) struct InvalidFloatLiteralSuffix { + #[primary_span] + #[label] + pub span: Span, + pub suffix: String, +} + +#[derive(Diagnostic)] +#[diag(parse_hexadecimal_float_literal_not_supported)] +pub(crate) struct HexadecimalFloatLiteralNotSupported { + #[primary_span] + #[label(parse_not_supported)] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(parse_octal_float_literal_not_supported)] +pub(crate) struct OctalFloatLiteralNotSupported { + #[primary_span] + #[label(parse_not_supported)] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(parse_binary_float_literal_not_supported)] +pub(crate) struct BinaryFloatLiteralNotSupported { + #[primary_span] + #[label(parse_not_supported)] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(parse_int_literal_too_large)] +#[note] +pub(crate) struct IntLiteralTooLarge { + #[primary_span] + pub span: Span, + pub limit: String, +} diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 5b0011e9f706c..e48e1c1a7be74 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -17,6 +17,7 @@ use rustc_ast::token::{self, Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::Spacing; use rustc_ast::util::case::Case; use rustc_ast::util::classify; +use rustc_ast::util::literal::LitError; use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity}; use rustc_ast::visit::Visitor; use rustc_ast::{self as ast, AttrStyle, AttrVec, CaptureBy, ExprField, UnOp, DUMMY_NODE_ID}; @@ -30,9 +31,10 @@ use rustc_errors::{ PResult, StashKey, }; use rustc_macros::Subdiagnostic; -use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded}; +use rustc_session::errors::ExprParenthesesNeeded; use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP; use rustc_session::lint::BuiltinLintDiagnostics; +use rustc_session::parse::ParseSess; use rustc_span::source_map::{self, Spanned}; use rustc_span::symbol::kw::PathRoot; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -3665,6 +3667,90 @@ impl<'a> Parser<'a> { } } +pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span: Span) { + // Checks if `s` looks like i32 or u1234 etc. + fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool { + s.len() > 1 && s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit()) + } + + // Try to lowercase the prefix if the prefix and suffix are valid. + fn fix_base_capitalisation(prefix: &str, suffix: &str) -> Option { + let mut chars = suffix.chars(); + + let base_char = chars.next().unwrap(); + let base = match base_char { + 'B' => 2, + 'O' => 8, + 'X' => 16, + _ => return None, + }; + + // check that the suffix contains only base-appropriate characters + let valid = prefix == "0" + && chars + .filter(|c| *c != '_') + .take_while(|c| *c != 'i' && *c != 'u') + .all(|c| c.to_digit(base).is_some()); + + valid.then(|| format!("0{}{}", base_char.to_ascii_lowercase(), &suffix[1..])) + } + + let token::Lit { kind, symbol, suffix, .. } = lit; + match err { + // `LexerError` is an error, but it was already reported + // by lexer, so here we don't report it the second time. + LitError::LexerError => {} + LitError::InvalidSuffix => { + if let Some(suffix) = suffix { + sess.emit_err(errors::InvalidLiteralSuffix { span, kind: kind.descr(), suffix }); + } + } + LitError::InvalidIntSuffix => { + let suf = suffix.expect("suffix error with no suffix"); + let suf = suf.as_str(); + if looks_like_width_suffix(&['i', 'u'], suf) { + // If it looks like a width, try to be helpful. + sess.emit_err(errors::InvalidIntLiteralWidth { span, width: suf[1..].into() }); + } else if let Some(fixed) = fix_base_capitalisation(symbol.as_str(), suf) { + sess.emit_err(errors::InvalidNumLiteralBasePrefix { span, fixed }); + } else { + sess.emit_err(errors::InvalidNumLiteralSuffix { span, suffix: suf.to_string() }); + } + } + LitError::InvalidFloatSuffix => { + let suf = suffix.expect("suffix error with no suffix"); + let suf = suf.as_str(); + if looks_like_width_suffix(&['f'], suf) { + // If it looks like a width, try to be helpful. + sess.emit_err(errors::InvalidFloatLiteralWidth { + span, + width: suf[1..].to_string(), + }); + } else { + sess.emit_err(errors::InvalidFloatLiteralSuffix { span, suffix: suf.to_string() }); + } + } + LitError::NonDecimalFloat(base) => { + match base { + 16 => sess.emit_err(errors::HexadecimalFloatLiteralNotSupported { span }), + 8 => sess.emit_err(errors::OctalFloatLiteralNotSupported { span }), + 2 => sess.emit_err(errors::BinaryFloatLiteralNotSupported { span }), + _ => unreachable!(), + }; + } + LitError::IntTooLarge(base) => { + let max = u128::MAX; + let limit = match base { + 2 => format!("{max:#b}"), + 8 => format!("{max:#o}"), + 16 => format!("{max:#x}"), + _ => format!("{max}"), + }; + sess.emit_err(errors::IntLiteralTooLarge { span, limit }); + } + } +} + /// Used to forbid `let` expressions in certain syntactic locations. #[derive(Clone, Copy, Subdiagnostic)] pub(crate) enum ForbiddenLetReason { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 2baedb2766fc6..2acbf0e948c7b 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -11,6 +11,7 @@ mod stmt; mod ty; use crate::lexer::UnmatchedDelim; +pub use crate::parser::expr::report_lit_error; pub use attr_wrapper::AttrWrapper; pub use diagnostics::AttemptLocalParseRecovery; pub(crate) use expr::ForbiddenLetReason; diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index 4f824f9f62e24..712388775fc30 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -1,4 +1,3 @@ -session_binary_float_literal_not_supported = binary float literal is not supported session_branch_protection_requires_aarch64 = `-Zbranch-protection` is only supported on aarch64 session_cannot_enable_crt_static_linux = sanitizer is incompatible with statically linked libc, disable it using `-C target-feature=-crt-static` @@ -32,48 +31,18 @@ session_function_return_requires_x86_or_x86_64 = `-Zfunction-return` (except `ke session_function_return_thunk_extern_requires_non_large_code_model = `-Zfunction-return=thunk-extern` is only supported on non-large code models -session_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported - session_incompatible_linker_flavor = linker flavor `{$flavor}` is incompatible with the current target .note = compatible flavors are: {$compatible_list} session_instrumentation_not_supported = {$us} instrumentation is not supported for this target -session_int_literal_too_large = integer literal is too large - .note = value exceeds limit of `{$limit}` - session_invalid_character_in_create_name = invalid character `{$character}` in crate name: `{$crate_name}` session_invalid_character_in_create_name_help = you can either pass `--crate-name` on the command line or add `#![crate_name="…"]` to set the crate name -session_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal - .label = invalid suffix `{$suffix}` - .help = valid suffixes are `f32` and `f64` - -session_invalid_float_literal_width = invalid width `{$width}` for float literal - .help = valid widths are 32 and 64 - -session_invalid_int_literal_width = invalid width `{$width}` for integer literal - .help = valid widths are 8, 16, 32, 64 and 128 - -session_invalid_literal_suffix = suffixes on {$kind} literals are invalid - .label = invalid suffix `{$suffix}` - -session_invalid_num_literal_base_prefix = invalid base prefix for number literal - .note = base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase - .suggestion = try making the prefix lowercase - -session_invalid_num_literal_suffix = invalid suffix `{$suffix}` for number literal - .label = invalid suffix `{$suffix}` - .help = the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) - session_linker_plugin_lto_windows_not_supported = linker plugin based LTO is not supported together with `-C prefer-dynamic` when targeting Windows-like targets session_not_circumvent_feature = `-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature gates, except when testing error paths in the CTFE engine -session_not_supported = not supported - -session_octal_float_literal_not_supported = octal float literal is not supported - session_optimization_fuel_exhausted = optimization-fuel-exhausted: {$msg} session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C profile-sample-use` does not exist. diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index c5ee5183b8ac6..2e26d5594f46a 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -1,8 +1,5 @@ use std::num::NonZeroU32; -use crate::parse::ParseSess; -use rustc_ast::token; -use rustc_ast::util::literal::LitError; use rustc_errors::{error_code, DiagnosticMessage, ErrorGuaranteed, IntoDiagnostic, MultiSpan}; use rustc_macros::Diagnostic; use rustc_span::{Span, Symbol}; @@ -237,179 +234,6 @@ pub enum UnleashedFeatureHelp { }, } -#[derive(Diagnostic)] -#[diag(session_invalid_literal_suffix)] -pub(crate) struct InvalidLiteralSuffix<'a> { - #[primary_span] - #[label] - pub span: Span, - // FIXME(#100717) - pub kind: &'a str, - pub suffix: Symbol, -} - -#[derive(Diagnostic)] -#[diag(session_invalid_int_literal_width)] -#[help] -pub(crate) struct InvalidIntLiteralWidth { - #[primary_span] - pub span: Span, - pub width: String, -} - -#[derive(Diagnostic)] -#[diag(session_invalid_num_literal_base_prefix)] -#[note] -pub(crate) struct InvalidNumLiteralBasePrefix { - #[primary_span] - #[suggestion(applicability = "maybe-incorrect", code = "{fixed}")] - pub span: Span, - pub fixed: String, -} - -#[derive(Diagnostic)] -#[diag(session_invalid_num_literal_suffix)] -#[help] -pub(crate) struct InvalidNumLiteralSuffix { - #[primary_span] - #[label] - pub span: Span, - pub suffix: String, -} - -#[derive(Diagnostic)] -#[diag(session_invalid_float_literal_width)] -#[help] -pub(crate) struct InvalidFloatLiteralWidth { - #[primary_span] - pub span: Span, - pub width: String, -} - -#[derive(Diagnostic)] -#[diag(session_invalid_float_literal_suffix)] -#[help] -pub(crate) struct InvalidFloatLiteralSuffix { - #[primary_span] - #[label] - pub span: Span, - pub suffix: String, -} - -#[derive(Diagnostic)] -#[diag(session_int_literal_too_large)] -#[note] -pub(crate) struct IntLiteralTooLarge { - #[primary_span] - pub span: Span, - pub limit: String, -} - -#[derive(Diagnostic)] -#[diag(session_hexadecimal_float_literal_not_supported)] -pub(crate) struct HexadecimalFloatLiteralNotSupported { - #[primary_span] - #[label(session_not_supported)] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(session_octal_float_literal_not_supported)] -pub(crate) struct OctalFloatLiteralNotSupported { - #[primary_span] - #[label(session_not_supported)] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(session_binary_float_literal_not_supported)] -pub(crate) struct BinaryFloatLiteralNotSupported { - #[primary_span] - #[label(session_not_supported)] - pub span: Span, -} - -pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span: Span) { - // Checks if `s` looks like i32 or u1234 etc. - fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool { - s.len() > 1 && s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit()) - } - - // Try to lowercase the prefix if the prefix and suffix are valid. - fn fix_base_capitalisation(prefix: &str, suffix: &str) -> Option { - let mut chars = suffix.chars(); - - let base_char = chars.next().unwrap(); - let base = match base_char { - 'B' => 2, - 'O' => 8, - 'X' => 16, - _ => return None, - }; - - // check that the suffix contains only base-appropriate characters - let valid = prefix == "0" - && chars - .filter(|c| *c != '_') - .take_while(|c| *c != 'i' && *c != 'u') - .all(|c| c.to_digit(base).is_some()); - - valid.then(|| format!("0{}{}", base_char.to_ascii_lowercase(), &suffix[1..])) - } - - let token::Lit { kind, symbol, suffix, .. } = lit; - match err { - // `LexerError` is an error, but it was already reported - // by lexer, so here we don't report it the second time. - LitError::LexerError => {} - LitError::InvalidSuffix => { - if let Some(suffix) = suffix { - sess.emit_err(InvalidLiteralSuffix { span, kind: kind.descr(), suffix }); - } - } - LitError::InvalidIntSuffix => { - let suf = suffix.expect("suffix error with no suffix"); - let suf = suf.as_str(); - if looks_like_width_suffix(&['i', 'u'], suf) { - // If it looks like a width, try to be helpful. - sess.emit_err(InvalidIntLiteralWidth { span, width: suf[1..].into() }); - } else if let Some(fixed) = fix_base_capitalisation(symbol.as_str(), suf) { - sess.emit_err(InvalidNumLiteralBasePrefix { span, fixed }); - } else { - sess.emit_err(InvalidNumLiteralSuffix { span, suffix: suf.to_string() }); - } - } - LitError::InvalidFloatSuffix => { - let suf = suffix.expect("suffix error with no suffix"); - let suf = suf.as_str(); - if looks_like_width_suffix(&['f'], suf) { - // If it looks like a width, try to be helpful. - sess.emit_err(InvalidFloatLiteralWidth { span, width: suf[1..].to_string() }); - } else { - sess.emit_err(InvalidFloatLiteralSuffix { span, suffix: suf.to_string() }); - } - } - LitError::NonDecimalFloat(base) => { - match base { - 16 => sess.emit_err(HexadecimalFloatLiteralNotSupported { span }), - 8 => sess.emit_err(OctalFloatLiteralNotSupported { span }), - 2 => sess.emit_err(BinaryFloatLiteralNotSupported { span }), - _ => unreachable!(), - }; - } - LitError::IntTooLarge(base) => { - let max = u128::MAX; - let limit = match base { - 2 => format!("{max:#b}"), - 8 => format!("{max:#o}"), - 16 => format!("{max:#x}"), - _ => format!("{max}"), - }; - sess.emit_err(IntLiteralTooLarge { span, limit }); - } - } -} - #[derive(Diagnostic)] #[diag(session_optimization_fuel_exhausted)] pub struct OptimisationFuelExhausted {