Skip to content
Merged
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
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/deriving/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
22 changes: 16 additions & 6 deletions compiler/rustc_macros/src/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,14 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
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() {
Expand Down Expand Up @@ -234,12 +241,11 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
});
}

// 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,
});
}

Expand Down Expand Up @@ -285,9 +291,13 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
}

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
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(
Expand Down
18 changes: 9 additions & 9 deletions compiler/rustc_parse/src/parser/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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)),
Expand All @@ -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.
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_parse/src/parser/tokenstream/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down
31 changes: 26 additions & 5 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ symbols! {
BorrowMut,
Break,
BuildHasher,
C,
CStr,
CallOnceFuture,
CallRefFuture,
Expand Down Expand Up @@ -547,7 +546,6 @@ symbols! {
built,
builtin_syntax,
bundle,
c,
c_dash_variadic,
c_str_literals,
c_unwind,
Expand Down Expand Up @@ -751,7 +749,6 @@ symbols! {
custom_inner_attributes,
custom_mir,
custom_test_frameworks,
d,
d32,
dead_code,
dealloc,
Expand Down Expand Up @@ -845,7 +842,6 @@ symbols! {
dyn_star,
dyn_trait,
dynamic_no_pic: "dynamic-no-pic",
e,
edition_panic,
effective_target_features,
effects,
Expand Down Expand Up @@ -912,7 +908,6 @@ symbols! {
extern_weak,
external,
external_doc,
f,
f16,
f16_nan,
f16c_target_feature,
Expand Down Expand Up @@ -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
Expand All @@ -2784,6 +2788,23 @@ pub mod sym {
let printed = buffer.format(n);
Symbol::intern(printed)
}

pub const fn ascii_letter_digit(c: char) -> Option<Symbol> {
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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sad the name is character when everything else in this commit uses "letter".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i can do follow up with rename ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sad the name is character when everything else in this commit uses "letter".

I was going to name it letter at first, but then I though it would be strange to not include digits here too, and it has a fallback for other characters anyway, hence character. After all, it works on any character, but has a special fast path for ascii letters and digits.

There's ascii_letter_digit just above, which does exactly what it says it does, has no fallback for other characters, and thus can be made const.

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 {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/asm/riscv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl RiscVInlineAsmRegClass {
}

pub(crate) fn is_e(target_features: &FxIndexSet<Symbol>) -> bool {
target_features.contains(&sym::e)
target_features.contains(&sym::character('e'))
}

fn not_e(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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()
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_trait_selection/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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()
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/clean/types/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
10 changes: 2 additions & 8 deletions tests/ui/or-patterns/missing-bindings.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
18 changes: 6 additions & 12 deletions tests/ui/span/issue-39698.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/traits/item-privacy.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Loading