diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 48a2f19261f62..004b13bcc333d 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -30,7 +30,7 @@ pub(crate) fn expand_deriving_debug( name: sym::fmt, generics: Bounds::empty(), explicit_self: true, - nonself_args: vec![(fmtr, sym::f)], + nonself_args: vec![(fmtr, sym::character('f'))], ret_ty: Path(path_std!(fmt::Result)), attributes: thin_vec![cx.attr_word(sym::inline, span)], fieldless_variants_strategy: diff --git a/compiler/rustc_macros/src/symbols.rs b/compiler/rustc_macros/src/symbols.rs index e3a70372110aa..44cd63e57af4c 100644 --- a/compiler/rustc_macros/src/symbols.rs +++ b/compiler/rustc_macros/src/symbols.rs @@ -189,7 +189,14 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec) { let mut keyword_stream = quote! {}; let mut symbols_stream = quote! {}; let mut prefill_stream = quote! {}; - let mut entries = Entries::with_capacity(input.keywords.len() + input.symbols.len() + 10); + let prefill_ints = 0..=9; + let prefill_letters = ('A'..='Z').chain('a'..='z'); + let mut entries = Entries::with_capacity( + input.keywords.len() + + input.symbols.len() + + prefill_ints.clone().count() + + prefill_letters.clone().count(), + ); // Generate the listed keywords. for keyword in input.keywords.iter() { @@ -234,12 +241,11 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec) { }); } - // Generate symbols for the strings "0", "1", ..., "9". - for n in 0..10 { - let n = n.to_string(); - entries.insert(Span::call_site(), &n, &mut errors); + // Generate symbols for ascii letters and digits + for s in prefill_ints.map(|n| n.to_string()).chain(prefill_letters.map(|c| c.to_string())) { + entries.insert(Span::call_site(), &s, &mut errors); prefill_stream.extend(quote! { - #n, + #s, }); } @@ -285,9 +291,13 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec) { } let symbol_digits_base = entries.map["0"].idx; + let symbol_uppercase_letters_base = entries.map["A"].idx; + let symbol_lowercase_letters_base = entries.map["a"].idx; let predefined_symbols_count = entries.len(); let output = quote! { const SYMBOL_DIGITS_BASE: u32 = #symbol_digits_base; + const SYMBOL_UPPERCASE_LETTERS_BASE: u32 = #symbol_uppercase_letters_base; + const SYMBOL_LOWERCASE_LETTERS_BASE: u32 = #symbol_lowercase_letters_base; /// The number of predefined symbols; this is the first index for /// extra pre-interned symbols in an Interner created via diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index f40969170a5bf..284e651d94ad0 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -647,7 +647,7 @@ impl<'a> Parser<'a> { // positive for a `cr#` that wasn't intended to start a c-string literal, but identifying // that in the parser requires unbounded lookahead, so we only add a hint to the existing // error rather than replacing it entirely. - if ((self.prev_token == TokenKind::Ident(sym::c, IdentIsRaw::No) + if ((self.prev_token == TokenKind::Ident(sym::character('c'), IdentIsRaw::No) && matches!(&self.token.kind, TokenKind::Literal(token::Lit { kind: token::Str, .. }))) || (self.prev_token == TokenKind::Ident(sym::cr, IdentIsRaw::No) && matches!( diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs index f9c3384458488..d43034645a6d2 100644 --- a/compiler/rustc_parse/src/parser/tests.rs +++ b/compiler/rustc_parse/src/parser/tests.rs @@ -2324,7 +2324,7 @@ fn string_to_tts_1() { let expected = TokenStream::new(vec![ TokenTree::token_alone(token::Ident(kw::Fn, IdentIsRaw::No), sp(0, 2)), TokenTree::token_joint_hidden( - token::Ident(Symbol::intern("a"), IdentIsRaw::No), + token::Ident(sym::character('a'), IdentIsRaw::No), sp(3, 4), ), TokenTree::Delimited( @@ -2335,7 +2335,7 @@ fn string_to_tts_1() { Delimiter::Parenthesis, TokenStream::new(vec![ TokenTree::token_joint( - token::Ident(Symbol::intern("b"), IdentIsRaw::No), + token::Ident(sym::character('b'), IdentIsRaw::No), sp(5, 6), ), TokenTree::token_alone(token::Colon, sp(6, 7)), @@ -2355,7 +2355,7 @@ fn string_to_tts_1() { Delimiter::Brace, TokenStream::new(vec![ TokenTree::token_joint( - token::Ident(Symbol::intern("b"), IdentIsRaw::No), + token::Ident(sym::character('b'), IdentIsRaw::No), sp(15, 16), ), // `Alone` because the `;` is followed by whitespace. @@ -2543,10 +2543,10 @@ fn look(p: &Parser<'_>, dist: usize, kind: rustc_ast::token::TokenKind) { #[test] fn look_ahead() { create_default_session_globals_then(|| { - let sym_f = Symbol::intern("f"); - let sym_x = Symbol::intern("x"); + let sym_f = sym::character('f'); + let sym_x = sym::character('x'); #[allow(non_snake_case)] - let sym_S = Symbol::intern("S"); + let sym_S = sym::character('S'); let raw_no = IdentIsRaw::No; let psess = ParseSess::new(); @@ -2618,10 +2618,10 @@ fn look_ahead() { #[test] fn look_ahead_non_outermost_stream() { create_default_session_globals_then(|| { - let sym_f = Symbol::intern("f"); - let sym_x = Symbol::intern("x"); + let sym_f = sym::character('f'); + let sym_x = sym::character('x'); #[allow(non_snake_case)] - let sym_S = Symbol::intern("S"); + let sym_S = sym::character('S'); let raw_no = IdentIsRaw::No; let psess = ParseSess::new(); diff --git a/compiler/rustc_parse/src/parser/tokenstream/tests.rs b/compiler/rustc_parse/src/parser/tokenstream/tests.rs index 63177a727449e..b54fdf6d8eaf8 100644 --- a/compiler/rustc_parse/src/parser/tokenstream/tests.rs +++ b/compiler/rustc_parse/src/parser/tokenstream/tests.rs @@ -2,7 +2,7 @@ use rustc_ast::token::{self, IdentIsRaw}; use rustc_ast::tokenstream::{TokenStream, TokenTree}; -use rustc_span::{BytePos, Span, Symbol, create_default_session_globals_then}; +use rustc_span::{BytePos, Span, create_default_session_globals_then, sym}; use crate::parser::tests::string_to_stream; @@ -92,7 +92,7 @@ fn test_is_empty() { create_default_session_globals_then(|| { let test0 = TokenStream::default(); let test1 = - TokenStream::token_alone(token::Ident(Symbol::intern("a"), IdentIsRaw::No), sp(0, 1)); + TokenStream::token_alone(token::Ident(sym::character('a'), IdentIsRaw::No), sp(0, 1)); let test2 = string_to_ts("foo(bar::baz)"); assert_eq!(test0.is_empty(), true); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9e16ee115212e..d17976ba9e8e7 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -189,7 +189,6 @@ symbols! { BorrowMut, Break, BuildHasher, - C, CStr, CallOnceFuture, CallRefFuture, @@ -547,7 +546,6 @@ symbols! { built, builtin_syntax, bundle, - c, c_dash_variadic, c_str_literals, c_unwind, @@ -751,7 +749,6 @@ symbols! { custom_inner_attributes, custom_mir, custom_test_frameworks, - d, d32, dead_code, dealloc, @@ -845,7 +842,6 @@ symbols! { dyn_star, dyn_trait, dynamic_no_pic: "dynamic-no-pic", - e, edition_panic, effective_target_features, effects, @@ -912,7 +908,6 @@ symbols! { extern_weak, external, external_doc, - f, f16, f16_nan, f16c_target_feature, @@ -2770,6 +2765,15 @@ pub mod sym { #[doc(inline)] pub use super::sym_generated::*; + // Used quite often in relation to C ABI. + pub const C: Symbol = ascii_letter_digit('C').unwrap(); + + // RISC-V stuff + #[expect(non_upper_case_globals)] + pub const f: Symbol = ascii_letter_digit('f').unwrap(); + #[expect(non_upper_case_globals)] + pub const d: Symbol = ascii_letter_digit('d').unwrap(); + /// Get the symbol for an integer. /// /// The first few non-negative integers each have a static symbol and therefore @@ -2784,6 +2788,23 @@ pub mod sym { let printed = buffer.format(n); Symbol::intern(printed) } + + pub const fn ascii_letter_digit(c: char) -> Option { + let i = c as u32; + Option::Some(Symbol::new(match c { + '0'..='9' => super::SYMBOL_DIGITS_BASE + (i - '0' as u32), + 'A'..='Z' => super::SYMBOL_UPPERCASE_LETTERS_BASE + (i - 'A' as u32), + 'a'..='z' => super::SYMBOL_LOWERCASE_LETTERS_BASE + (i - 'a' as u32), + _ => return Option::None, + })) + } + + pub fn character(c: char) -> Symbol { + ascii_letter_digit(c).unwrap_or_else(|| { + let mut buf: [u8; char::MAX_LEN_UTF8] = Default::default(); + Symbol::intern(c.encode_utf8(&mut buf)) + }) + } } impl Symbol { diff --git a/compiler/rustc_target/src/asm/riscv.rs b/compiler/rustc_target/src/asm/riscv.rs index 97eb93335818d..3976d9890256f 100644 --- a/compiler/rustc_target/src/asm/riscv.rs +++ b/compiler/rustc_target/src/asm/riscv.rs @@ -55,7 +55,7 @@ impl RiscVInlineAsmRegClass { } pub(crate) fn is_e(target_features: &FxIndexSet) -> bool { - target_features.contains(&sym::e) + target_features.contains(&sym::character('e')) } fn not_e( diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index 62ddbc3443226..9a6cc31303408 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -14,7 +14,7 @@ use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{ self, IsSuggestable, Region, Ty, TyCtxt, TypeVisitableExt as _, Upcast as _, }; -use rustc_span::{BytePos, ErrorGuaranteed, Span, Symbol, kw}; +use rustc_span::{BytePos, ErrorGuaranteed, Span, Symbol, kw, sym}; use tracing::{debug, instrument}; use super::ObligationCauseAsDiagArg; @@ -1431,9 +1431,9 @@ fn suggest_precise_capturing<'tcx>( }); } else { let mut next_fresh_param = || { - ["T", "U", "V", "W", "X", "Y", "A", "B", "C"] + ['T', 'U', 'V', 'W', 'X', 'Y', 'A', 'B', 'C'] .into_iter() - .map(Symbol::intern) + .map(sym::character) .chain((0..).map(|i| Symbol::intern(&format!("T{i}")))) .find(|s| captured_non_lifetimes.insert(*s)) .unwrap() diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 23234c2080690..84000aab87484 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -12,7 +12,7 @@ use rustc_hir::{self as hir, AmbigArg, FnRetTy, GenericParamKind, Node}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_middle::ty::print::{PrintTraitRefExt as _, TraitRefPrintOnlyTraitPath}; use rustc_middle::ty::{self, Binder, ClosureKind, FnSig, GenericArg, Region, Ty, TyCtxt}; -use rustc_span::{BytePos, Ident, Span, Symbol, kw}; +use rustc_span::{BytePos, Ident, Span, Symbol, kw, sym}; use crate::error_reporting::infer::ObligationCauseAsDiagArg; use crate::error_reporting::infer::need_type_info::UnderspecifiedArgKind; @@ -2062,9 +2062,9 @@ pub fn impl_trait_overcapture_suggestion<'tcx>( } let mut next_fresh_param = || { - ["T", "U", "V", "W", "X", "Y", "A", "B", "C"] + ['T', 'U', 'V', 'W', 'X', 'Y', 'A', 'B', 'C'] .into_iter() - .map(Symbol::intern) + .map(sym::character) .chain((0..).map(|i| Symbol::intern(&format!("T{i}")))) .find(|s| captured_non_lifetimes.insert(*s)) .unwrap() diff --git a/src/librustdoc/clean/types/tests.rs b/src/librustdoc/clean/types/tests.rs index 10a3857878c87..a0fc623c20c48 100644 --- a/src/librustdoc/clean/types/tests.rs +++ b/src/librustdoc/clean/types/tests.rs @@ -75,7 +75,7 @@ fn is_same_generic() { use crate::formats::cache::Cache; create_default_session_globals_then(|| { let cache = Cache::new(false, false); - let generic = Type::Generic(Symbol::intern("T")); + let generic = Type::Generic(sym::character('T')); let unit = Type::Primitive(PrimitiveType::Unit); assert!(!generic.is_doc_subtype_of(&unit, &cache)); assert!(unit.is_doc_subtype_of(&generic, &cache)); diff --git a/tests/ui/or-patterns/missing-bindings.stderr b/tests/ui/or-patterns/missing-bindings.stderr index 636f701664727..b742da2418cf0 100644 --- a/tests/ui/or-patterns/missing-bindings.stderr +++ b/tests/ui/or-patterns/missing-bindings.stderr @@ -129,10 +129,10 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; | | | pattern doesn't bind `e` | -help: you might have meant to use the similarly named previously used binding `c` +help: you might have meant to use the similarly named previously used binding `a` | LL - let (A(A(a, b) | B(c), d) | B(e)) = Y; -LL + let (A(A(a, b) | B(c), d) | B(c)) = Y; +LL + let (A(A(a, b) | B(c), d) | B(a)) = Y; | error[E0408]: variable `a` is not bound in all patterns @@ -262,12 +262,6 @@ LL | B(b), ... LL | V3(c), | ^^^^^ pattern doesn't bind `b` - | -help: you might have meant to use the similarly named previously used binding `c` - | -LL - B(b), -LL + B(c), - | error[E0408]: variable `c` is not bound in all patterns --> $DIR/missing-bindings.rs:59:13 diff --git a/tests/ui/span/issue-39698.stderr b/tests/ui/span/issue-39698.stderr index dd57fa0618665..5f002418c15fc 100644 --- a/tests/ui/span/issue-39698.stderr +++ b/tests/ui/span/issue-39698.stderr @@ -8,10 +8,10 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?} | | variable not in all patterns | pattern doesn't bind `b` | -help: you might have meant to use the similarly named previously used binding `c` +help: you might have meant to use the similarly named previously used binding `a` | LL - T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } -LL + T::T1(a, d) | T::T2(d, c) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } +LL + T::T1(a, d) | T::T2(d, a) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } | error[E0408]: variable `c` is not bound in all patterns @@ -24,10 +24,10 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?} | | pattern doesn't bind `c` | pattern doesn't bind `c` | -help: you might have meant to use the similarly named previously used binding `d` +help: you might have meant to use the similarly named previously used binding `a` | LL - T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } -LL + T::T1(a, d) | T::T2(d, b) | T::T3(d) | T::T4(a) => { println!("{:?}", a); } +LL + T::T1(a, d) | T::T2(d, b) | T::T3(a) | T::T4(a) => { println!("{:?}", a); } | error[E0408]: variable `a` is not bound in all patterns @@ -40,10 +40,10 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?} | | pattern doesn't bind `a` | variable not in all patterns | -help: you might have meant to use the similarly named previously used binding `c` +help: you might have meant to use the similarly named previously used binding `b` | LL - T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } -LL + T::T1(c, d) | T::T2(d, b) | T::T3(c) | T::T4(c) => { println!("{:?}", a); } +LL + T::T1(b, d) | T::T2(d, b) | T::T3(c) | T::T4(b) => { println!("{:?}", a); } | error[E0408]: variable `d` is not bound in all patterns @@ -55,12 +55,6 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?} | | | pattern doesn't bind `d` | | variable not in all patterns | variable not in all patterns - | -help: you might have meant to use the similarly named previously used binding `c` - | -LL - T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } -LL + T::T1(a, c) | T::T2(c, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } - | error[E0381]: used binding `a` is possibly-uninitialized --> $DIR/issue-39698.rs:10:79 diff --git a/tests/ui/traits/item-privacy.stderr b/tests/ui/traits/item-privacy.stderr index acb67af53f18c..8c33bb6de200f 100644 --- a/tests/ui/traits/item-privacy.stderr +++ b/tests/ui/traits/item-privacy.stderr @@ -150,9 +150,9 @@ LL | pub trait C: A + B { | - this trait is not dyn compatible... LL | const C: u8 = 0; | ^ ...because it contains associated const `C` - = help: consider moving `C` to another trait = help: consider moving `A` to another trait = help: consider moving `B` to another trait + = help: consider moving `C` to another trait = help: only type `S` implements `assoc_const::C`; consider using it directly instead. error[E0038]: the trait `assoc_const::C` is not dyn compatible @@ -175,9 +175,9 @@ LL | pub trait C: A + B { | - this trait is not dyn compatible... LL | const C: u8 = 0; | ^ ...because it contains associated const `C` - = help: consider moving `C` to another trait = help: consider moving `A` to another trait = help: consider moving `B` to another trait + = help: consider moving `C` to another trait = help: only type `S` implements `assoc_const::C`; consider using it directly instead. error[E0223]: ambiguous associated type