use alloc::borrow::ToOwned;
use alloc::boxed::Box;
use alloc::format;
use alloc::string::{String, ToString};
use alloc::vec;
use alloc::vec::Vec;
use core::hash::{BuildHasher, Hash, Hasher};
use core::{fmt, str};
use crate::rustc_arena::DroplessArena;
use crate::rustc_data_structures::fx::FxBuildHasher;
use crate::rustc_data_structures::hash_table::{Entry, HashTable};
use crate::rustc_data_structures::stable_hash::{StableCompare, StableHash, StableHashCtxt, StableHasher};
use crate::rustc_data_structures::sync::Lock;
use rustc_macros::{Decodable, Encodable, StableHash, symbols};
use crate::rustc_span::edit_distance::find_best_match_for_name;
use crate::rustc_span::{DUMMY_SP, Edition, Span, with_session_globals};
#[cfg(test)]
mod tests;
symbols! {
Keywords {
DollarCrate: "$crate",
PathRoot: "{{root}}",
Underscore: "_",
As: "as",
Break: "break",
Const: "const",
Continue: "continue",
Crate: "crate",
Else: "else",
Enum: "enum",
Extern: "extern",
False: "false",
Fn: "fn",
For: "for",
If: "if",
Impl: "impl",
In: "in",
Let: "let",
Loop: "loop",
Match: "match",
Mod: "mod",
Move: "move",
Mut: "mut",
Pub: "pub",
Ref: "ref",
Return: "return",
SelfLower: "self",
SelfUpper: "Self",
Static: "static",
Struct: "struct",
Super: "super",
Trait: "trait",
True: "true",
Type: "type",
Unsafe: "unsafe",
Use: "use",
Where: "where",
While: "while",
Abstract: "abstract",
Become: "become",
Box: "box",
Do: "do",
Final: "final",
Macro: "macro",
Override: "override",
Priv: "priv",
Typeof: "typeof",
Unsized: "unsized",
Virtual: "virtual",
Yield: "yield",
Async: "async", Await: "await", Dyn: "dyn",
Gen: "gen", Try: "try",
StaticLifetime: "'static",
UnderscoreLifetime: "'_",
Auto: "auto",
Builtin: "builtin",
Catch: "catch",
ContractEnsures: "contract_ensures",
ContractRequires: "contract_requires",
Default: "default",
MacroRules: "macro_rules",
Pin: "pin",
Raw: "raw",
Reuse: "reuse",
Safe: "safe",
Union: "union",
Yeet: "yeet",
}
Symbols {
Abi,
AcqRel,
Acquire,
Active,
ActiveOnly,
Alignment,
Arc,
ArcWeak,
Array,
AsMut,
AsRef,
AssertParamIsClone,
AssertParamIsCopy,
AssertParamIsEq,
AsyncGenFinished,
AsyncGenPending,
AsyncGenReady,
Atomic,
BTreeMap,
Bool,
Borrow,
BorrowMut,
Break,
BuildHasher,
CStr,
CallOnceFuture,
CallRefFuture,
Capture,
Cell,
Char,
Cleanup,
Client,
Clone,
CoercePointee,
CoercePointeeValidated,
CoerceShared,
CoerceUnsized,
Const,
ConstParamTy,
ConstParamTy_,
Context,
Continue,
ControlFlow,
Copy,
Cow,
Debug,
Default,
Deref,
DispatchFromDyn,
Display,
Dual,
DualOnly,
Dualv,
DualvOnly,
Duplicated,
DuplicatedOnly,
DynTrait,
Enum,
Eq,
Equal,
Err,
Expected,
ExternC,
ExternRust,
Float,
FmtArgumentsNew,
Fn,
FnMut,
FnOnce,
FnPtr,
Formatter,
Forward,
Found,
From,
FromIterator,
FromResidual,
GlobalAlloc,
Hash,
HashMap,
HashSet,
Hasher,
InCleanup,
IndexOutput,
Input,
Int,
Into,
IntoAsyncIterator,
IntoFuture,
IntoIterator,
IntoIteratorItem,
IoBufReader,
IrTyKind,
Item,
ItemContext,
Iterator,
IteratorItem,
IteratorMap,
Layout,
Lifetime,
LintPass,
LocalKey,
Mutex,
MutexGuard,
Named,
NonZero,
None,
Normal,
Ok,
Option,
Ord,
Ordering,
Other,
Output,
ParamSet,
PartialEq,
PartialOrd,
Pending,
PinDerefMutHelper,
PinMacroHelper,
Pointer,
Poll,
Range,
RangeCopy,
RangeFrom,
RangeFromCopy,
RangeFull,
RangeInclusive,
RangeInclusiveCopy,
RangeMax,
RangeMin,
RangeSub,
RangeTo,
RangeToInclusive,
RangeToInclusiveCopy,
Rc,
RcWeak,
Ready,
Reborrow,
RefCell,
Reference,
Relaxed,
Release,
Result,
ResumeTy,
Reverse,
Rust,
RustEmbed,
RustaceansAreAwesome,
RwLock,
RwLockReadGuard,
RwLockWriteGuard,
SelfTy,
Send,
SeqCst,
Sized,
Slice,
SliceIndex,
Some,
Source,
SpanCtxt,
StdinLock,
Str,
String,
Struct,
StructuralPartialEq,
SymbolIntern,
Sync,
SyncUnsafeCell,
Target,
This,
TokenStream,
TrivialClone,
Try,
TryCaptureGeneric,
TryCapturePrintable,
TryFrom,
TryInto,
Tuple,
Ty,
TyCtxt,
TyKind,
Type,
Union,
Unresolved,
Unsize,
Vec,
Wrapper,
_DECLS,
__H,
__S,
__awaitee,
__try_var,
_t,
_task_context,
a32,
aarch64,
aarch64_target_feature,
aarch64_unstable_target_feature,
aarch64_ver_target_feature,
abi,
abi_amdgpu_kernel,
abi_avr_interrupt,
abi_c_cmse_nonsecure_call,
abi_cmse_nonsecure_call,
abi_custom,
abi_efiapi,
abi_gpu_kernel,
abi_msp430_interrupt,
abi_ptx,
abi_riscv_interrupt,
abi_swift,
abi_sysv64,
abi_thiscall,
abi_unadjusted,
abi_vectorcall,
abi_x86_interrupt,
abort,
add,
add_assign,
add_with_overflow,
address,
adt_const_params,
advanced_slice_patterns,
adx_target_feature,
aes,
aggregate_raw_ptr,
alias,
align,
align_of,
align_of_val,
alignment,
all,
alloc,
alloc_error_handler,
alloc_layout,
alloc_zeroed,
allocator,
allocator_api,
allocator_internals,
allow,
allow_fail,
allow_internal_unsafe,
allow_internal_unstable,
altivec,
alu32,
always,
amdgpu,
amdgpu_dispatch_ptr,
analysis,
and,
and_then,
anon,
anon_assoc,
anonymous_lifetime_in_impl_trait,
any,
apx_target_feature,
arbitrary_enum_discriminant,
arbitrary_self_types,
arbitrary_self_types_pointers,
areg,
args,
arith_offset,
arm,
arm64ec,
arm_a32: "arm::a32",
arm_t32: "arm::t32",
arm_target_feature,
array,
as_dash_needed: "as-needed",
as_ref,
asm,
asm_cfg,
asm_const,
asm_const_ptr,
asm_experimental_arch,
asm_experimental_reg,
asm_goto,
asm_goto_with_outputs,
asm_sym,
asm_unwind,
assert,
assert_eq,
assert_eq_macro,
assert_fields_are_eq,
assert_inhabited,
assert_macro,
assert_mem_uninitialized_valid,
assert_ne_macro,
assert_receiver_is_total_eq,
assert_zero_valid,
asserting,
associated_const_equality,
associated_consts,
associated_type_bounds,
associated_type_defaults,
associated_types,
assume,
assume_init,
asterisk: "*",
async_await,
async_call,
async_call_mut,
async_call_once,
async_closure,
async_drop,
async_drop_in_place,
async_fn,
async_fn_in_dyn_trait,
async_fn_in_trait,
async_fn_kind_helper,
async_fn_kind_upvars,
async_fn_mut,
async_fn_once,
async_fn_once_output,
async_fn_track_caller,
async_fn_traits,
async_for_loop,
async_gen_internals,
async_iterator,
async_iterator_poll_next,
async_trait_bounds,
atomic,
atomic_and,
atomic_cxchg,
atomic_cxchgweak,
atomic_fence,
atomic_load,
atomic_max,
atomic_min,
atomic_nand,
atomic_or,
atomic_singlethreadfence,
atomic_store,
atomic_umax,
atomic_umin,
atomic_xadd,
atomic_xchg,
atomic_xor,
atomic_xsub,
atomics,
att_syntax,
attr,
attr_literals,
attribute,
attributes,
audit_that,
augmented_assignments,
auto_cfg,
auto_traits,
autodiff,
autodiff_forward,
autodiff_reverse,
automatically_derived,
available_externally,
avr,
avr_target_feature,
avx,
avx10_target_feature,
avx512_target_feature,
avx512bw,
avx512f,
await_macro,
backchain,
backend_repr,
begin_panic,
bench,
bevy_ecs,
bikeshed,
bikeshed_guaranteed_no_drop,
bin,
bind_by_move_pattern_guards,
bindings_after_at,
bitand,
bitand_assign,
bitor,
bitor_assign,
bitreverse,
bits,
bitxor,
bitxor_assign,
black_box,
block,
blocking,
bool,
borrowck_graphviz_format,
borrowck_graphviz_postflow,
box_new,
box_patterns,
box_syntax,
boxed_slice,
bpf,
bpf_target_feature,
braced_empty_structs,
branch,
breakpoint,
breg,
bridge,
bswap,
built,
builtin_syntax,
bundle,
c_dash_variadic,
c_str_literals,
c_unwind,
c_variadic,
c_variadic_experimental_arch,
c_variadic_naked_functions,
c_void,
call,
call_mut,
call_once,
call_once_future,
call_ref_future,
caller,
caller_location,
capture_disjoint_fields,
carrying_mul_add,
carryless_mul,
catch_unwind,
cause,
cdylib,
ceilf16,
ceilf32,
ceilf64,
ceilf128,
cfg,
cfg_accessible,
cfg_attr,
cfg_attr_multi,
cfg_boolean_literals,
cfg_contract_checks,
cfg_doctest,
cfg_eval,
cfg_overflow_checks,
cfg_panic,
cfg_relocation_model,
cfg_sanitize,
cfg_sanitizer_cfi,
cfg_select,
cfg_target_abi,
cfg_target_compact,
cfg_target_feature,
cfg_target_has_atomic,
cfg_target_has_atomic_equal_alignment,
cfg_target_has_reliable_f16_f128,
cfg_target_has_threads,
cfg_target_object_format,
cfg_target_thread_local,
cfg_target_vendor,
cfg_ub_checks,
cfg_version,
cfi,
cfi_encoding,
char,
checked_type_aliases,
clflushopt_target_feature,
client,
clippy,
clobber_abi,
clone,
clone_closures,
clone_fn,
clone_from,
close_fn,
closure,
closure_lifetime_binder,
closure_to_fn_coercion,
closure_track_caller,
cmp,
cmp_ord_max,
cmp_ord_min,
cmp_partialeq_eq,
cmp_partialeq_ne,
cmp_partialord_cmp,
cmp_partialord_ge,
cmp_partialord_gt,
cmp_partialord_le,
cmp_partialord_lt,
cmpxchg16b_target_feature,
cmse_nonsecure_entry,
code,
coerce_pointee_validated,
coerce_shared,
coerce_shared_target,
coerce_unsized,
coff,
cold,
cold_path,
collapse_debuginfo,
column,
common,
compare_bytes,
compare_exchange,
compare_exchange_weak,
compile_error,
compiler,
compiler_builtins,
compiler_copy,
compiler_fence,
compiler_move,
complex,
concat,
concat_bytes,
conservative_impl_trait,
console,
const_allocate,
const_async_blocks,
const_block_items,
const_c_variadic,
const_closures,
const_compare_raw_pointers,
const_constructor,
const_continue,
const_deallocate,
const_destruct,
const_eval_limit,
const_eval_select,
const_evaluatable_checked,
const_extern_fn,
const_fn,
const_fn_floating_point_arithmetic,
const_fn_fn_ptr_basics,
const_fn_trait_bound,
const_fn_transmute,
const_fn_union,
const_fn_unsize,
const_for,
const_format_args,
const_generics,
const_generics_defaults,
const_if_match,
const_impl_trait,
const_in_array_repeat_expressions,
const_indexing,
const_let,
const_loop,
const_make_global,
const_mut_refs,
const_panic,
const_panic_fmt,
const_param_ty,
const_param_ty_unchecked,
const_precise_live_drops,
const_ptr_cast,
const_raw_ptr_deref,
const_raw_ptr_to_usize_cast,
const_refs_to_cell,
const_refs_to_static,
const_trait_bound_opt_out,
const_trait_impl,
const_try,
const_ty_placeholder: "<const_ty>",
constant,
constructor,
contract_build_check_ensures,
contract_check_ensures,
contract_check_requires,
contract_checks,
contracts,
contracts_ensures,
contracts_internals,
contracts_requires,
convert,
coprocessor,
copy,
copy_closures,
copy_nonoverlapping,
copysignf16,
copysignf32,
copysignf64,
copysignf128,
core,
core_panic,
core_panic_2015_macro,
core_panic_macro,
coroutine,
coroutine_clone,
coroutine_resume,
coroutine_return,
coroutine_state,
coroutine_yield,
coroutines,
cosf16,
cosf32,
cosf64,
cosf128,
count,
covariant_unsafe_cell,
coverage,
coverage_attribute,
cr,
crate_in_paths,
crate_local,
crate_name,
crate_type,
crate_visibility_modifier,
crt_dash_static: "crt-static",
csky,
csky_target_feature,
cstr_type,
cstring_type,
ctlz,
ctlz_nonzero,
ctpop,
ctr,
cttz,
cttz_nonzero,
custom_attribute,
custom_code_classes_in_docs,
custom_derive,
custom_inner_attributes,
custom_mir,
custom_test_frameworks,
d32,
dead_code,
dead_code_pub_in_binary,
dealloc,
debug,
debug_assert_eq_macro,
debug_assert_macro,
debug_assert_ne_macro,
debug_assertions,
debug_c_like_enum_write_str,
debug_struct_fields_finish,
debug_tuple_fields_finish,
debugger_visualizer,
decl_macro,
declare_lint_pass,
decorated,
default_alloc_error_handler,
default_field_values,
default_fn,
default_lib_allocator,
default_method_body_is_const,
default_trait1,
default_trait2,
default_trait3,
default_trait4,
default_type_parameter_fallback,
default_type_params,
define_opaque,
deny,
deprecated,
deprecated_safe,
deprecated_suggestion,
deref,
deref_method,
deref_mut,
deref_patterns,
deref_pure,
deref_target,
derive,
derive_const,
derive_const_issue: "118304",
derive_default_enum,
derive_from,
derive_smart_pointer,
destruct,
destructuring_assignment,
diagnostic,
diagnostic_namespace,
diagnostic_on_const,
diagnostic_on_move,
diagnostic_on_type_error,
diagnostic_on_unknown,
diagnostic_on_unmatch_args,
diagnostic_on_unmatched_args,
diagnostic_opaque,
dialect,
direct,
direct_const_arg,
discriminant_kind,
discriminant_type,
discriminant_value,
disjoint_bitor,
dispatch_from_dyn,
div,
div_assign,
diverging_block_default,
dl,
do_not_recommend,
doc,
doc_alias,
doc_auto_cfg,
doc_cfg,
doc_cfg_hide,
doc_keyword,
doc_masked,
doc_notable_trait,
doc_primitive,
doc_spotlight,
doctest,
dotdot_in_tuple_patterns,
dotdoteq_in_patterns,
dreg,
dreg_low8,
dreg_low16,
drop,
drop_glue,
drop_in_place,
drop_types_in_const,
dropck_eyepatch,
dropck_parametricity,
dummy: "<!dummy!>", dummy_cgu_name,
dylib,
dyn_compatible_for_dispatch,
dyn_metadata,
dyn_star,
dyn_trait,
dynamic_no_pic: "dynamic-no-pic",
edition_panic,
effective_target_features,
effects,
eh_personality,
eii,
eii_declaration,
eii_internals,
eii_shared_macro,
element_ty,
elf,
empty: "",
empty_braces: "{}",
empty_brackets: "[]",
empty_parens: "()",
enable,
end,
entry_nops,
env,
env_CFG_RELEASE: env!("CFG_RELEASE"),
eq,
ergonomic_clones,
ermsb_target_feature,
exact_div,
except,
exception,
exception_handling: "exception-handling",
exclusive_range_pattern,
exhaustive_integer_patterns,
exhaustive_patterns,
existential_type,
exists,
exp2f16,
exp2f32,
exp2f64,
exp2f128,
expand1,
expand2,
expect,
expected,
expf16,
expf32,
expf64,
expf128,
explicit_extern_abis,
explicit_generic_args_with_impl_trait,
explicit_tail_calls,
export_name,
export_stable,
export_symbols: "export-symbols",
expr,
expr_2021,
expr_fragment_specifier_2024,
extended_key_value_attributes,
extended_varargs_abi_support,
extendedl32r,
extern_absolute_paths,
extern_crate_item_prelude,
extern_crate_self,
extern_in_paths,
extern_item_impls,
extern_prelude,
extern_system_varargs,
extern_types,
extern_weak,
external,
external_doc,
f16,
f16_nan,
f16c_target_feature,
f32,
f32_nan,
f64,
f64_nan,
f128,
f128_nan,
fabs,
fadd_algebraic,
fadd_fast,
fake_variadic,
fallback,
fdiv_algebraic,
fdiv_fast,
feature,
fence,
ferris: "🦀",
fetch_update,
ffi_const,
ffi_pure,
ffi_returns_twice,
field,
field_base,
field_init_shorthand,
field_of,
field_offset,
field_projections,
field_representing_type,
field_representing_type_actual_type_id,
field_representing_type_name,
field_representing_type_offset,
field_representing_type_raw,
field_type,
fields,
file,
final_associated_functions,
float_to_int_unchecked,
floorf16,
floorf32,
floorf64,
floorf128,
fma4_target_feature,
fmaf16,
fmaf32,
fmaf64,
fmaf128,
fmt,
fmt_debug,
fmul_algebraic,
fmul_fast,
fmuladdf16,
fmuladdf32,
fmuladdf64,
fmuladdf128,
fn_align,
fn_body,
fn_delegation,
fn_must_use,
fn_mut,
fn_once,
fn_once_output,
fn_ptr_as_ptr,
fn_ptr_from_ptr,
fn_ptr_trait,
fn_static,
forall,
forbid,
force_target_feature,
forget,
format_args,
format_args_capture,
format_args_nl,
format_argument,
format_arguments,
format_macro,
format_placeholder,
format_unsafe_arg,
fp,
fpregs,
framework,
freeze,
freeze_impls,
freg,
frem_algebraic,
frem_fast,
from,
from_desugaring,
from_iter,
from_output,
from_residual,
from_size_align_unchecked,
from_size_alignment_unchecked,
from_str,
from_str_nonconst,
from_usize,
from_yeet,
frontmatter,
fsub_algebraic,
fsub_fast,
full,
fundamental,
fused_iterator,
future_output,
future_trait,
fxsr,
gdb_script_file,
ge,
gen_blocks,
gen_future,
generator_clone,
generators,
generic_arg_infer,
generic_assert,
generic_associated_types,
generic_associated_types_extended,
generic_const_args,
generic_const_exprs,
generic_const_items,
generic_const_parameter_types,
generic_param_attrs,
generic_pattern_types,
generics,
get_context,
global_alloc_ty,
global_allocator,
global_asm,
global_registration,
globs,
gpu_kernel: "gpu-kernel",
gpu_launch_sized_workgroup_mem,
gt,
guard,
guard_patterns,
half_open_range_patterns,
half_open_range_patterns_in_slices,
hash,
hexagon,
hexagon_target_feature,
hidden,
hide,
highpriinterrupts,
hint,
homogeneous_aggregate,
html_favicon_url,
html_logo_url,
html_no_source,
html_playground_url,
html_root_url,
hvx,
hvx_length64b: "hvx-length64b",
hvx_length128b: "hvx-length128b",
hwaddress,
i8,
i16,
i32,
i64,
i128,
i128_type,
ident,
if_let,
if_let_guard,
if_let_rescope,
if_while_or_patterns,
ignore,
immediate_abort: "immediate-abort",
impl_header_lifetime_elision,
impl_lint_pass,
impl_restriction,
impl_trait_in_assoc_type,
impl_trait_in_bindings,
impl_trait_in_fn_trait_return,
impl_trait_projections,
implied_by,
import,
import_name_type,
import_shadowing,
import_trait_associated_functions,
imported_main,
in_band_lifetimes,
include,
include_bytes,
include_str,
inclusive_range_syntax,
incomplete_features,
index,
index_mut,
infer_outlives_requirements,
infer_static_outlives_requirements,
inherent_associated_types,
initial,
inlateout,
inline,
inline_const,
inline_const_pat,
inout,
inputs,
instruction_set,
instrument_fn,
integer_: "integer", integral,
internal,
internal_eq_trait_method_impls,
internal_features,
interrupt,
into_async_iter_into_iter,
into_future,
into_iter,
into_try_type,
intra_doc_pointers,
intrinsics,
irrefutable_let_patterns,
is,
is_auto,
is_splatted,
is_val_statically_known,
isa_attribute,
isize,
issue,
issue_5723_bootstrap,
issue_tracker_base_url,
item,
item_like_imports,
iter,
iter_mut,
iterator,
iterator_collect_fn,
kcfi,
kernel_address,
kernel_hwaddress,
keylocker_x86,
keyword,
kind,
kreg,
kreg0,
label,
label_break_value,
lahfsahf_target_feature,
lang,
lang_items,
large_assignments,
largest_niche,
last,
lasx,
late_bound_turbofishing,
lateout,
lazy_normalization_consts,
lazy_type_alias,
le,
legacy_receiver,
len,
let_chains,
let_else,
lhs,
lib,
libc,
lifetime,
lifetime_capture_rules_2024,
lifetimes,
line,
link,
link_arg_attribute,
link_args,
link_cfg,
link_dash_arg: "link-arg",
link_llvm_intrinsics,
link_name,
link_ordinal,
link_section,
linkage,
linker,
linker_info,
linker_messages,
linkonce,
linkonce_odr,
lint_reasons,
literal,
little, big,
load,
loaded_from_disk,
local,
local_inner_macros,
log2f16,
log2f32,
log2f64,
log2f128,
log10f16,
log10f32,
log10f64,
log10f128,
log_syntax,
logf16,
logf32,
logf64,
logf128,
loongarch32,
loongarch64,
loongarch_target_feature,
loop_break_value,
loop_hints,
loop_match,
lr,
lsx,
lt,
m68k,
m68k_target_feature,
mac16,
macho: "mach-o",
macro_at_most_once_rep,
macro_attr,
macro_attributes_in_derive_output,
macro_derive,
macro_escape,
macro_export,
macro_guard_matcher,
macro_lifetime_matcher,
macro_literal_matcher,
macro_metavar_expr,
macro_metavar_expr_concat,
macro_reexport,
macro_use,
macro_vis_matcher,
macroless_generic_const_args,
macros_in_extern,
main,
managed_boxes,
manually_drop,
map,
map_err,
marker,
marker_trait_attr,
masked,
match_beginning_vert,
match_default_bindings,
maximum_number_nsz_f16,
maximum_number_nsz_f32,
maximum_number_nsz_f64,
maximum_number_nsz_f128,
maximumf16,
maximumf32,
maximumf64,
maximumf128,
may_dangle,
may_unwind,
maybe_dangling,
maybe_uninit,
maybe_uninit_uninit,
maybe_uninit_zeroed,
mem,
mem_align_const,
mem_discriminant,
mem_drop,
mem_forget,
mem_size_const,
mem_swap,
mem_uninitialized,
mem_variant_count,
mem_zeroed,
member_constraints,
memory,
memtag,
message,
meta,
meta_sized,
metadata_type,
mgca_type_const_syntax,
min_adt_const_params,
min_const_fn,
min_const_generics,
min_const_unsafe_fn,
min_exhaustive_patterns,
min_generic_const_args,
min_specialization,
min_type_alias_impl_trait,
minimum_number_nsz_f16,
minimum_number_nsz_f32,
minimum_number_nsz_f64,
minimum_number_nsz_f128,
minimumf16,
minimumf32,
minimumf64,
minimumf128,
mips,
mips32r6,
mips64,
mips64r6,
mips_target_feature,
mir_assume,
mir_basic_block,
mir_call,
mir_cast_ptr_to_ptr,
mir_cast_transmute,
mir_cast_unsize,
mir_checked,
mir_debuginfo,
mir_discriminant,
mir_drop,
mir_field,
mir_goto,
mir_make_place,
mir_move,
mir_offset,
mir_ptr_metadata,
mir_return,
mir_return_to,
mir_set_discriminant,
mir_static,
mir_static_mut,
mir_storage_dead,
mir_storage_live,
mir_tail_call,
mir_unreachable,
mir_unwind_cleanup,
mir_unwind_continue,
mir_unwind_resume,
mir_unwind_terminate,
mir_unwind_terminate_reason,
mir_unwind_unreachable,
mir_variant,
miri,
misc,
miscsr,
mmx_reg,
modifiers,
module,
module_path,
more_maybe_bounds,
more_qualified_paths,
more_struct_aliases,
movbe_target_feature,
move_expr,
move_ref_pattern,
move_size_limit,
movrs_target_feature,
msa,
msp430,
mul,
mul_assign,
mul_with_overflow,
multiple_supertrait_upcastable,
must_not_suspend,
must_use,
mut_preserve_binding_mode_2024,
mut_ref,
mut_restriction,
mutable,
naked,
naked_asm,
naked_functions,
naked_functions_rustic_abi,
naked_functions_target_feature,
name,
named_fn_trait_parameters,
names,
native_link_modifiers,
native_link_modifiers_as_needed,
native_link_modifiers_bundle,
native_link_modifiers_verbatim,
native_link_modifiers_whole_archive,
natvis_file,
ne,
needs_allocator,
needs_drop,
needs_panic_runtime,
neg,
negate_unsigned,
negative_bounds,
negative_impls,
neon,
nested,
never,
never_patterns,
never_type,
never_type_fallback,
new,
new_binary,
new_debug,
new_debug_noop,
new_display,
new_lower_exp,
new_lower_hex,
new_octal,
new_pointer,
new_range,
new_unchecked,
new_upper_exp,
new_upper_hex,
next,
niko,
nll,
no,
no_builtins,
no_core,
no_coverage,
no_crate_inject,
no_debug,
no_default_passes,
no_implicit_prelude,
no_inline,
no_link,
no_main,
no_mangle,
no_sanitize,
no_stack_check,
no_std,
nomem,
non_ascii_idents,
non_exhaustive,
non_exhaustive_omitted_patterns_lint,
non_lifetime_binders,
non_modrs_mods,
non_null,
nonblocking,
none,
nontemporal_store,
noop_method_borrow,
noop_method_clone,
noop_method_deref,
noprefix,
noreturn,
nostack,
not,
notable_trait,
note,
null,
nvptx64,
nvptx_target_feature,
object_safe_for_dispatch,
of,
off,
offload,
offload_get_num_devices,
offload_kernel,
offset,
offset_of,
offset_of_enum,
offset_of_nested,
offset_of_slice,
ok_or_else,
old_name,
omit_gdb_pretty_printer_section,
on,
on_const,
on_move,
on_type_error,
on_unimplemented,
on_unknown,
on_unmatched_args,
opaque,
opaque_module_name_placeholder: "<opaque>",
ops,
opt_out_copy,
optimize,
optimize_attribute,
optimized,
optin_builtin_traits,
option,
option_env,
options,
or,
or_patterns,
ord_cmp_method,
other,
out,
output,
overflow_checks,
overlapping_marker_traits,
owned_box,
packed,
packed_bundled_libs,
panic,
panic_2015,
panic_2021,
panic_abort,
panic_bounds_check,
panic_cannot_unwind,
panic_const_add_overflow,
panic_const_async_fn_resumed,
panic_const_async_fn_resumed_drop,
panic_const_async_fn_resumed_panic,
panic_const_async_gen_fn_resumed,
panic_const_async_gen_fn_resumed_drop,
panic_const_async_gen_fn_resumed_panic,
panic_const_coroutine_resumed,
panic_const_coroutine_resumed_drop,
panic_const_coroutine_resumed_panic,
panic_const_div_by_zero,
panic_const_div_overflow,
panic_const_gen_fn_none,
panic_const_gen_fn_none_drop,
panic_const_gen_fn_none_panic,
panic_const_mul_overflow,
panic_const_neg_overflow,
panic_const_rem_by_zero,
panic_const_rem_overflow,
panic_const_shl_overflow,
panic_const_shr_overflow,
panic_const_sub_overflow,
panic_display,
panic_fmt,
panic_handler,
panic_impl,
panic_implementation,
panic_in_cleanup,
panic_info,
panic_invalid_enum_construction,
panic_location,
panic_misaligned_pointer_dereference,
panic_nounwind,
panic_null_pointer_dereference,
panic_null_reference_constructed,
panic_runtime,
panic_str_2015,
panic_unwind,
panicking,
param_attrs,
parent_label,
partial_cmp,
partial_ord,
passes,
pat,
pat_param,
patchable_function_entry,
path,
pattern_complexity_limit,
pattern_parentheses,
pattern_type,
pattern_type_range_trait,
pattern_types,
phantom_data,
phase,
pic,
pie,
pin_drop,
pin_ergonomics,
pin_v2,
platform_intrinsics,
plugin,
plugin_registrar,
plugins,
pointee,
pointee_sized,
pointee_trait,
pointer,
poll,
post_cleanup: "post-cleanup",
post_dash_lto: "post-lto",
postfix_match,
powerpc,
powerpc64,
powerpc_target_feature,
powf16,
powf32,
powf64,
powf128,
powif16,
powif32,
powif64,
powif128,
pre_dash_lto: "pre-lto",
precise_capturing,
precise_capturing_in_traits,
precise_pointer_size_matching,
predicates,
pref_align_of,
prefetch_read_data,
prefetch_read_instruction,
prefetch_write_data,
prefetch_write_instruction,
prefix_nops,
preg,
prelude,
prelude_import,
preserves_flags,
prfchw_target_feature,
prid,
primitive,
proc_dash_macro: "proc-macro",
proc_macro,
proc_macro_attribute,
proc_macro_derive,
proc_macro_expr,
proc_macro_gen,
proc_macro_hygiene,
proc_macro_internals,
proc_macro_mod,
proc_macro_non_items,
proc_macro_path_invoc,
profiler_runtime,
ptr,
ptr_cast,
ptr_cast_const,
ptr_cast_mut,
ptr_const_is_null,
ptr_copy,
ptr_copy_nonoverlapping,
ptr_drop_in_place,
ptr_drop_in_place_self,
ptr_from_ref,
ptr_guaranteed_cmp,
ptr_is_null,
ptr_mask,
ptr_metadata,
ptr_null,
ptr_null_mut,
ptr_offset_from,
ptr_offset_from_unsigned,
ptr_read,
ptr_read_unaligned,
ptr_replace,
ptr_swap,
ptr_swap_nonoverlapping,
ptr_write,
ptr_write_bytes,
ptr_write_unaligned,
ptr_write_volatile,
pub_macro_rules,
pub_restricted,
public,
pure,
pushpop_unsafe,
qreg,
qreg_low4,
qreg_low8,
quad_precision_float,
question_mark,
quote,
range_inclusive_new,
raw_dash_dylib: "raw-dylib",
raw_dylib,
raw_dylib_elf,
raw_eq,
raw_identifiers,
raw_ref_op,
re_rebalance_coherence,
read_via_copy,
readonly,
realloc,
realtime,
reason,
reborrow,
receiver,
receiver_target,
recursion_limit,
reexport_test_harness_main,
ref_pat_eat_one_layer_2024,
ref_pat_eat_one_layer_2024_structural,
ref_pat_everywhere,
ref_unwind_safe_trait,
reference,
reflect,
reg,
reg16,
reg32,
reg64,
reg_abcd,
reg_addr,
reg_byte,
reg_data,
reg_iw,
reg_nonzero,
reg_pair,
reg_ptr,
reg_upper,
register_attr,
register_attribute_tool,
register_lint_tool,
register_tool,
relaxed_adts,
relaxed_struct_unsize,
relocation_model,
rem,
rem_assign,
repr,
repr128,
repr_align,
repr_align_enum,
repr_packed,
repr_simd,
repr_transparent,
require,
reserve_x18: "reserve-x18",
residual,
result,
result_ffi_guarantees,
return_address,
return_position_impl_trait_in_trait,
return_type_notation,
right_arrow: "->",
riscv32,
riscv64,
riscv_target_feature,
rlib,
ropi,
ropi_rwpi: "ropi-rwpi",
rotate_left,
rotate_right,
round_ties_even_f16,
round_ties_even_f32,
round_ties_even_f64,
round_ties_even_f128,
roundf16,
roundf32,
roundf64,
roundf128,
rtm_target_feature,
runtime,
rust,
rust_2015,
rust_2018,
rust_2018_preview,
rust_2021,
rust_2024,
rust_analyzer,
rust_begin_unwind,
rust_cold_cc,
rust_dash_call: "rust-call",
rust_eh_personality,
rust_future,
rust_logo,
rust_out,
rust_preserve_none_cc,
rust_tail_cc,
rustc,
rustc_abi,
rustc_align,
rustc_align_static,
rustc_allocator,
rustc_allocator_zeroed,
rustc_allocator_zeroed_variant,
rustc_allow_const_fn_unstable,
rustc_allow_incoherent_impl,
rustc_allow_lifetime_dependent_specialization,
rustc_allowed_through_unstable_modules,
rustc_as_ptr,
rustc_attrs,
rustc_autodiff,
rustc_builtin_macro,
rustc_canonical_symbol,
rustc_capture_analysis,
rustc_clean,
rustc_coherence_is_core,
rustc_coinductive,
rustc_comptime,
rustc_confusables,
rustc_const_stable,
rustc_const_stable_indirect,
rustc_const_unstable,
rustc_conversion_suggestion,
rustc_deallocator,
rustc_default_body_unstable,
rustc_delayed_bug_from_inside_query,
rustc_deny_explicit_impl,
rustc_deprecated_safe_2024,
rustc_diagnostic_item,
rustc_diagnostic_macros,
rustc_diagnostic_opaque,
rustc_do_not_const_check,
rustc_doc_primitive,
rustc_driver,
rustc_dummy,
rustc_dump_clauses,
rustc_dump_def_parents,
rustc_dump_def_path,
rustc_dump_generics,
rustc_dump_hidden_type_of_opaques,
rustc_dump_inferred_outlives,
rustc_dump_item_bounds,
rustc_dump_layout,
rustc_dump_object_lifetime_defaults,
rustc_dump_symbol_name,
rustc_dump_user_args,
rustc_dump_variances,
rustc_dump_variances_of_opaques,
rustc_dump_vtable,
rustc_dyn_incompatible_trait,
rustc_effective_visibility,
rustc_eii_foreign_item,
rustc_evaluate_where_clauses,
rustc_expected_cgu_reuse,
rustc_force_inline,
rustc_has_incoherent_inherent_impls,
rustc_if_this_changed,
rustc_inherit_overflow_checks,
rustc_insignificant_dtor,
rustc_intrinsic,
rustc_intrinsic_const_stable_indirect,
rustc_legacy_const_generics,
rustc_lint_opt_deny_field_access,
rustc_lint_opt_ty,
rustc_lint_query_instability,
rustc_lint_untracked_query_information,
rustc_macro_transparency,
rustc_main,
rustc_mir,
rustc_must_implement_one_of,
rustc_must_match_exhaustively,
rustc_never_returns_null_ptr,
rustc_no_implicit_autorefs,
rustc_no_implicit_bounds,
rustc_no_mir_inline,
rustc_no_writable,
rustc_non_const_trait_method,
rustc_nonnull_optimization_guaranteed,
rustc_nounwind,
rustc_objc_class,
rustc_objc_selector,
rustc_offload_kernel,
rustc_on_unimplemented,
rustc_panics_when_zero,
rustc_paren_sugar,
rustc_partition_codegened,
rustc_partition_reused,
rustc_pass_by_value,
rustc_pass_indirectly_in_non_rustic_abis,
rustc_peek,
rustc_peek_liveness,
rustc_peek_maybe_init,
rustc_peek_maybe_uninit,
rustc_preserve_ub_checks,
rustc_private,
rustc_proc_macro_decls,
rustc_promotable,
rustc_pub_transparent,
rustc_reallocator,
rustc_regions,
rustc_scalable_vector,
rustc_should_not_be_called_on_const_items,
rustc_simd_monomorphize_lane_limit,
rustc_skip_during_method_dispatch,
rustc_specialization_trait,
rustc_splat,
rustc_std_internal_symbol,
rustc_strict_coherence,
rustc_test_marker,
rustc_then_this_would_need,
rustc_trivial_field_reads,
rustc_unroll,
rustdoc,
rustdoc_internals,
rustdoc_missing_doc_code_examples,
rustfmt,
rvalue_static_promotion,
rvector,
rwpi,
s32c1i,
s390x,
s390x_target_feature,
s390x_target_feature_vector,
safestack,
safety,
sanitize,
sanitizer_cfi_generalize_pointers,
sanitizer_cfi_normalize_integers,
sanitizer_runtime,
saturating_add,
saturating_sub,
sdylib,
search_unbox,
section,
select_unpredictable,
self_in_typedefs,
self_struct_ctor,
semiopaque,
sgpr32,
sgpr64,
sgpr96,
sgpr128,
sgpr256,
sgpr512,
sha2,
sha3,
sha512_sm_x86,
shadow_call_stack,
shallow,
shl,
shl_assign,
shorter_tail_lifetimes,
should_panic,
show,
shr,
shr_assign,
signed,
simd,
simd_add,
simd_and,
simd_arith_offset,
simd_as,
simd_bitmask,
simd_bitreverse,
simd_bswap,
simd_carryless_mul,
simd_cast,
simd_cast_ptr,
simd_ceil,
simd_ctlz,
simd_ctpop,
simd_cttz,
simd_div,
simd_eq,
simd_expose_provenance,
simd_extract,
simd_extract_dyn,
simd_fabs,
simd_fcos,
simd_fexp,
simd_fexp2,
simd_ffi,
simd_flog,
simd_flog2,
simd_flog10,
simd_floor,
simd_fma,
simd_fsin,
simd_fsqrt,
simd_funnel_shl,
simd_funnel_shr,
simd_gather,
simd_ge,
simd_gt,
simd_insert,
simd_insert_dyn,
simd_le,
simd_lt,
simd_masked_load,
simd_masked_store,
simd_maximum_number_nsz,
simd_minimum_number_nsz,
simd_mul,
simd_ne,
simd_neg,
simd_or,
simd_reduce_add_ordered,
simd_reduce_add_unordered,
simd_reduce_all,
simd_reduce_and,
simd_reduce_any,
simd_reduce_max,
simd_reduce_min,
simd_reduce_mul_ordered,
simd_reduce_mul_unordered,
simd_reduce_or,
simd_reduce_xor,
simd_relaxed_fma,
simd_rem,
simd_round,
simd_round_ties_even,
simd_saturating_add,
simd_saturating_sub,
simd_scatter,
simd_select,
simd_select_bitmask,
simd_shl,
simd_shr,
simd_shuffle,
simd_shuffle_const_generic,
simd_splat,
simd_sub,
simd_trunc,
simd_with_exposed_provenance,
simd_xor,
since,
sinf16,
sinf32,
sinf64,
sinf128,
size,
size_of,
size_of_type_id,
size_of_val,
sized,
sized_hierarchy,
slice,
slice_from_raw_parts,
slice_from_raw_parts_mut,
slice_get_unchecked,
slice_len_fn,
slice_patterns,
slicing_syntax,
soft_float: "soft-float",
sparc,
sparc64,
sparc_target_feature,
spe_acc,
specialization,
speed,
spirv,
splat,
splatted_index,
spotlight,
sqrtf16,
sqrtf32,
sqrtf64,
sqrtf128,
sreg,
sreg_low16,
sse,
sse2,
sse4a_target_feature,
stable,
staged_api,
start,
state,
static_align,
static_in_const,
static_nobundle,
static_recursion,
staticlib,
std,
std_lib_injection,
std_panic,
std_panic_2015_macro,
std_panic_macro,
stmt,
stmt_expr_attributes,
stop_after_dataflow,
store,
str,
str_from_utf8,
str_from_utf8_mut,
str_from_utf8_unchecked,
str_from_utf8_unchecked_mut,
str_inherent_from_utf8,
str_inherent_from_utf8_mut,
str_inherent_from_utf8_unchecked,
str_inherent_from_utf8_unchecked_mut,
strict_provenance_lints,
string_deref_patterns,
stringify,
struct_field_attributes,
struct_inherit,
struct_variant,
structural_match,
structural_peq,
sub,
sub_assign,
sub_with_overflow,
suggestion,
super_let,
supertrait_item_shadowing,
sve_cast,
sve_tuple_create2,
sve_tuple_create3,
sve_tuple_create4,
sve_tuple_get,
sve_tuple_set,
sym,
sync,
synthetic,
t32,
target,
target_abi,
target_arch,
target_endian,
target_env,
target_family,
target_feature,
target_feature_11,
target_feature_inline_always,
target_has_atomic,
target_has_atomic_load_store,
target_has_atomic_primitive_alignment,
target_has_reliable_f16,
target_has_reliable_f16_math,
target_has_reliable_f128,
target_has_reliable_f128_math,
target_has_threads,
target_object_format,
target_os,
target_pointer_width,
target_thread_local,
target_vendor,
tbm_target_feature,
termination,
termination_trait,
termination_trait_test,
test,
test_2018_feature,
test_accepted_feature,
test_binder_constraints,
test_case,
test_incomplete_feature,
test_removed_feature,
test_runner,
test_unstable_lint,
thread,
thread_local,
threadptr,
three_way_compare,
thumb2,
thumb_mode: "thumb-mode",
time,
tmm_reg,
to_owned_method,
to_string,
to_vec,
tool_attributes,
tool_lints,
trace_macros,
track_caller,
trait_alias,
trait_ty,
trait_upcasting,
transmute,
transmute_generic_consts,
transmute_opts,
transmute_trait,
transmute_unchecked,
transparent,
transparent_enums,
transparent_unions,
trivial_bounds,
trivial_clone,
truncf16,
truncf32,
truncf64,
truncf128,
try_as_dyn,
try_blocks,
try_blocks_heterogeneous,
try_capture,
try_from,
try_into,
try_trait_v2,
try_trait_v2_residual,
try_update,
tt,
tuple,
tuple_indexing,
tuple_trait,
two_phase,
ty,
type_alias_enum_variants,
type_alias_impl_trait,
type_ascribe,
type_ascription,
type_changing_struct_update,
type_id,
type_id_eq,
type_id_field_representing_type,
type_id_fields,
type_id_generics,
type_id_is_signed,
type_id_variants,
type_id_vtable,
type_info,
type_info_generic,
type_ir,
type_ir_infer_ctxt_like,
type_ir_inherent,
type_ir_interner,
type_length_limit,
type_macros,
type_name,
type_of,
type_privacy_lints,
typed_swap_nonoverlapping,
u8,
u8_legacy_const_max,
u8_legacy_const_min,
u8_legacy_fn_max_value,
u8_legacy_fn_min_value,
u8_legacy_mod,
u16,
u16_legacy_const_max,
u16_legacy_const_min,
u16_legacy_fn_max_value,
u16_legacy_fn_min_value,
u16_legacy_mod,
u32,
u32_legacy_const_max,
u32_legacy_const_min,
u32_legacy_fn_max_value,
u32_legacy_fn_min_value,
u32_legacy_mod,
u64,
u64_legacy_const_max,
u64_legacy_const_min,
u64_legacy_fn_max_value,
u64_legacy_fn_min_value,
u64_legacy_mod,
u128,
u128_legacy_const_max,
u128_legacy_const_min,
u128_legacy_fn_max_value,
u128_legacy_fn_min_value,
u128_legacy_mod,
ub_checks,
unaligned_volatile_load,
unaligned_volatile_store,
unboxed_closures,
unchecked_add,
unchecked_div,
unchecked_funnel_shl,
unchecked_funnel_shr,
unchecked_mul,
unchecked_rem,
unchecked_shl,
unchecked_shr,
unchecked_sub,
undecorated,
underscore_const_names,
underscore_imports,
underscore_lifetimes,
uniform_paths,
unimplemented,
unit,
universal_impl_trait,
unix,
unlikely,
unmarked_api,
unnamed_enum_variants,
unnamed_fields,
unpin,
unqualified_local_imports,
unreachable,
unreachable_2015,
unreachable_2015_macro,
unreachable_2021,
unreachable_code,
unreachable_display,
unreachable_macro,
unrestricted_attribute_tokens,
unsafe_attributes,
unsafe_binders,
unsafe_block_in_unsafe_fn,
unsafe_cell,
unsafe_cell_raw_get,
unsafe_eii,
unsafe_extern_blocks,
unsafe_fields,
unsafe_no_drop_flag,
unsafe_pinned,
unsafe_unpin,
unsafety,
unsize,
unsized_const_param_ty,
unsized_const_params,
unsized_fn_params,
unsized_locals,
unsized_tuple_coercion,
unstable,
unstable_feature_bound,
unstable_location_reason_default: "this crate is being loaded from the sysroot, an \
unstable location; did you mean to load this crate \
from crates.io via `Cargo.toml` instead?",
unstable_removed,
untagged_unions,
unused_imports,
unwind,
unwind_attributes,
unwind_safe_trait,
unwrap,
unwrap_binder,
unwrap_or,
update,
use_cloned,
use_extern_macros,
use_nested_groups,
used,
used_with_arg,
using,
usize,
usize_legacy_const_max,
usize_legacy_const_min,
usize_legacy_fn_max_value,
usize_legacy_fn_min_value,
usize_legacy_mod,
v1,
v8plus,
v9,
va_arg,
va_arg_safe,
va_copy,
va_end,
va_list,
val,
validity,
value,
values,
var,
variadic,
variant_count,
variant_name,
variant_non_exhaustive,
variants,
vec,
vector,
verbatim,
version,
vfp2,
vgpr16,
vgpr32,
vgpr64,
vgpr96,
vgpr128,
vgpr160,
vgpr192,
vgpr224,
vgpr256,
vgpr288,
vgpr320,
vgpr352,
vgpr384,
vgpr512,
vgpr1024,
view_type,
view_types,
vis,
visible_private_types,
volatile,
volatile_copy_memory,
volatile_copy_nonoverlapping_memory,
volatile_load,
volatile_set_memory,
volatile_store,
vreg,
vreg_low16,
vreg_pair,
vsreg,
vsx,
vtable_align,
vtable_size,
warn,
wasip2,
wasm,
wasm32,
wasm64,
wasm_abi,
wasm_import_module,
wasm_target_feature,
weak,
weak_odr,
where_clause_attrs,
while_let,
whole_dash_archive: "whole-archive",
width,
windowed,
windows,
windows_subsystem,
with_negative_coherence,
wrap_binder,
wrapping_add,
wrapping_div,
wrapping_mul,
wrapping_rem,
wrapping_rem_euclid,
wrapping_sub,
wreg,
write_box_via_move,
write_bytes,
write_fmt,
write_macro,
write_str,
write_via_move,
writeln_macro,
x86,
x86_64,
x86_amx_intrinsics,
x87_reg,
x87_target_feature,
xcoff,
xer,
xloop,
xmm_reg,
xop_target_feature,
xreg,
xtensa,
xtensa_target_feature,
yeet_desugar_details,
yeet_expr,
yes,
yield_expr,
ymm_reg,
yreg,
zca,
zfh,
zfhmin,
zmm_reg,
ztso,
}
}
pub const STDLIB_STABLE_CRATES: &[Symbol] = &[sym::std, sym::core, sym::alloc, sym::proc_macro];
#[derive(Copy, Clone, Eq, StableHash, Encodable, Decodable)]
pub struct Ident {
pub name: Symbol,
pub span: Span,
}
impl Ident {
#[inline]
pub fn new(name: Symbol, span: Span) -> Ident {
debug_assert_ne!(name, sym::empty);
Ident { name, span }
}
#[inline]
pub fn with_dummy_span(name: Symbol) -> Ident {
Ident::new(name, DUMMY_SP)
}
#[inline]
pub fn dummy() -> Ident {
Ident::with_dummy_span(sym::dummy)
}
pub fn from_str(string: &str) -> Ident {
Ident::with_dummy_span(Symbol::intern(string))
}
pub fn from_str_and_span(string: &str, span: Span) -> Ident {
Ident::new(Symbol::intern(string), span)
}
pub fn with_span_pos(self, span: Span) -> Ident {
Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
}
pub fn without_first_quote(self) -> Ident {
self.as_str()
.strip_prefix('\'')
.map_or(self, |name| Ident::new(Symbol::intern(name), self.span))
}
pub fn normalize_to_macros_2_0(self) -> Ident {
Ident::new(self.name, self.span.normalize_to_macros_2_0())
}
#[inline]
pub fn normalize_to_macro_rules(self) -> Ident {
Ident::new(self.name, self.span.normalize_to_macro_rules())
}
pub fn as_str(&self) -> &str {
self.name.as_str()
}
}
impl PartialEq for Ident {
#[inline]
fn eq(&self, rhs: &Self) -> bool {
self.name == rhs.name && self.span.eq_ctxt(rhs.span)
}
}
impl Hash for Ident {
fn hash<H: Hasher>(&self, state: &mut H) {
self.name.hash(state);
self.span.ctxt().hash(state);
}
}
impl fmt::Debug for Ident {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)?;
fmt::Debug::fmt(&self.span.ctxt(), f)
}
}
impl fmt::Display for Ident {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&IdentPrinter::new(self.name, self.guess_print_mode(), None), f)
}
}
pub enum IdentPrintMode {
Normal,
RawIdent,
RawLifetime,
}
pub struct IdentPrinter {
symbol: Symbol,
mode: IdentPrintMode,
convert_dollar_crate: Option<Span>,
}
impl IdentPrinter {
pub fn new(
symbol: Symbol,
mode: IdentPrintMode,
convert_dollar_crate: Option<Span>,
) -> IdentPrinter {
IdentPrinter { symbol, mode, convert_dollar_crate }
}
pub fn for_ast_ident(ident: Ident, mode: IdentPrintMode) -> IdentPrinter {
IdentPrinter::new(ident.name, mode, Some(ident.span))
}
}
impl fmt::Display for IdentPrinter {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self.mode {
IdentPrintMode::Normal
if self.symbol == kw::DollarCrate
&& let Some(span) = self.convert_dollar_crate =>
{
let converted = span.ctxt().dollar_crate_name();
if !converted.is_path_segment_keyword() {
f.write_str("::")?;
}
converted
}
IdentPrintMode::Normal => self.symbol,
IdentPrintMode::RawIdent => {
f.write_str("r#")?;
self.symbol
}
IdentPrintMode::RawLifetime => {
f.write_str("'r#")?;
let s = self
.symbol
.as_str()
.strip_prefix("'")
.expect("only lifetime idents should be passed with RawLifetime mode");
Symbol::intern(s)
}
};
s.fmt(f)
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct MacroRulesNormalizedIdent(Ident);
impl MacroRulesNormalizedIdent {
#[inline]
pub fn new(ident: Ident) -> Self {
MacroRulesNormalizedIdent(ident.normalize_to_macro_rules())
}
pub fn symbol(&self) -> Symbol {
self.0.name
}
pub fn ident(&self) -> Ident {
self.0
}
}
impl fmt::Debug for MacroRulesNormalizedIdent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.0, f)
}
}
impl fmt::Display for MacroRulesNormalizedIdent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Symbol(SymbolIndex);
crate::rustc_index::newtype_index! {
#[orderable]
struct SymbolIndex {}
}
impl Symbol {
pub const fn new(n: u32) -> Self {
Symbol(SymbolIndex::from_u32(n))
}
#[inline]
pub fn intern(str: &str) -> Self {
with_session_globals(|session_globals| session_globals.symbol_interner.intern_str(str))
}
#[inline]
pub fn as_str(&self) -> &str {
with_session_globals(|session_globals| unsafe {
core::mem::transmute::<&str, &str>(session_globals.symbol_interner.get_str(*self))
})
}
pub fn as_u32(self) -> u32 {
self.0.as_u32()
}
pub fn is_empty(self) -> bool {
self == sym::empty
}
pub fn to_ident_string(self) -> String {
if self == sym::empty { String::new() } else { Ident::with_dummy_span(self).to_string() }
}
pub fn find_similar(
self,
candidates: &[Symbol],
) -> Option<(Symbol, /* is incorrect case */ bool)> {
let lowercase = self.as_str().to_lowercase();
let lowercase_sym = Symbol::intern(&lowercase);
if candidates.contains(&lowercase_sym) {
Some((lowercase_sym, true))
} else if let Some(similar_sym) = find_best_match_for_name(candidates, self, None) {
Some((similar_sym, false))
} else {
None
}
}
}
impl fmt::Debug for Symbol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.as_str(), f)
}
}
impl fmt::Display for Symbol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self.as_str(), f)
}
}
impl StableHash for Symbol {
#[inline]
fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
self.as_str().stable_hash(hcx, hasher);
}
}
impl StableCompare for Symbol {
const CAN_USE_UNSTABLE_SORT: bool = true;
fn stable_cmp(&self, other: &Self) -> core::cmp::Ordering {
self.as_str().cmp(other.as_str())
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ByteSymbol(SymbolIndex);
impl ByteSymbol {
pub const fn new(n: u32) -> Self {
ByteSymbol(SymbolIndex::from_u32(n))
}
pub fn intern(byte_str: &[u8]) -> Self {
with_session_globals(|session_globals| {
session_globals.symbol_interner.intern_byte_str(byte_str)
})
}
pub fn as_byte_str(&self) -> &[u8] {
with_session_globals(|session_globals| unsafe {
core::mem::transmute::<&[u8], &[u8]>(session_globals.symbol_interner.get_byte_str(*self))
})
}
pub fn as_u32(self) -> u32 {
self.0.as_u32()
}
}
impl fmt::Debug for ByteSymbol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.as_byte_str(), f)
}
}
impl StableHash for ByteSymbol {
#[inline]
fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
self.as_byte_str().stable_hash(hcx, hasher);
}
}
pub(crate) struct Interner(Lock<InternerInner>);
struct InternerInner {
arena: DroplessArena,
indices: HashTable<(&'static [u8], u32)>,
byte_strs: Vec<&'static [u8]>,
}
impl Interner {
fn prefill(init: &[&'static str], extra: &[&'static str]) -> Self {
let values = init.iter().copied().chain(extra.iter().copied()).map(|str| str.as_bytes());
let (size_hint, _) = values.size_hint();
let mut conflicting_values: Vec<&[u8]> = Vec::new();
let mut indices: HashTable<(&'static [u8], u32)> = HashTable::with_capacity(size_hint);
let hasher = FxBuildHasher::default();
let mut byte_strs: Vec<&'static [u8]> = Vec::with_capacity(size_hint);
for v in values {
match indices.entry(hasher.hash_one(&v), |&(s, _)| s == v, |&(s, _)| hasher.hash_one(s))
{
Entry::Occupied(v) => conflicting_values.push(v.get().0),
Entry::Vacant(view) => {
view.insert((v, byte_strs.len() as u32));
byte_strs.push(v);
}
}
}
if conflicting_values.len() != 0 {
panic!(
"duplicate symbols in the rustc symbol list and the extra symbols added by the driver: {:?}",
conflicting_values
)
}
Interner(Lock::new(InternerInner { arena: Default::default(), indices, byte_strs }))
}
fn intern_str(&self, str: &str) -> Symbol {
Symbol::new(self.intern_inner(str.as_bytes()))
}
fn intern_byte_str(&self, byte_str: &[u8]) -> ByteSymbol {
ByteSymbol::new(self.intern_inner(byte_str))
}
#[inline]
fn intern_inner(&self, byte_str: &[u8]) -> u32 {
let hasher = FxBuildHasher::default();
let hash_of_byte_str = hasher.hash_one(byte_str);
self.0.with_lock(|inner| {
match inner.indices.entry(
hash_of_byte_str,
|&(s, _)| s == byte_str,
|&(s, _)| hasher.hash_one(s),
) {
Entry::Occupied(v) => v.get().1,
Entry::Vacant(view) => {
let byte_str: &[u8] = inner.arena.alloc_slice(byte_str);
let byte_str: &'static [u8] = unsafe { &*(byte_str as *const [u8]) };
let idx = inner.byte_strs.len() as u32;
view.insert((byte_str, idx));
inner.byte_strs.push(byte_str);
idx
}
}
})
}
fn get_str(&self, symbol: Symbol) -> &str {
let byte_str = self.get_inner(symbol.0.as_usize());
unsafe { str::from_utf8_unchecked(byte_str) }
}
fn get_byte_str(&self, symbol: ByteSymbol) -> &[u8] {
self.get_inner(symbol.0.as_usize())
}
fn get_inner(&self, index: usize) -> &[u8] {
self.0.with_lock(|inner| inner.byte_strs[index])
}
}
pub mod kw {
pub use super::kw_generated::*;
}
#[diagnostic::on_unknown(
label = "`{Unresolved}` is not a pre-interned symbol",
note = "consider adding `{Unresolved}` to the `symbols!` invocation in compiler/rustc_span/src/symbol.rs"
)]
pub mod sym {
use super::Symbol;
pub use super::kw::MacroRules as macro_rules;
#[doc(inline)]
pub use super::sym_generated::*;
pub const C: Symbol = ascii_letter_digit('C').unwrap();
#[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();
pub fn integer<N: TryInto<usize> + Copy + itoa::Integer>(n: N) -> Symbol {
if let Result::Ok(idx) = n.try_into() {
if idx < 10 {
return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
}
}
let mut buffer = itoa::Buffer::new();
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 {
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 {
fn is_special(self) -> bool {
self <= kw::Underscore
}
fn is_used_keyword_always(self) -> bool {
self >= kw::As && self <= kw::While
}
fn is_unused_keyword_always(self) -> bool {
self >= kw::Abstract && self <= kw::Yield
}
fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
(self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
}
fn is_unused_keyword_conditional(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
self == kw::Gen && edition().at_least_rust_2024()
|| self == kw::Try && edition().at_least_rust_2018()
}
pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
self.is_special()
|| self.is_used_keyword_always()
|| self.is_unused_keyword_always()
|| self.is_used_keyword_conditional(edition)
|| self.is_unused_keyword_conditional(edition)
}
pub fn is_weak(self) -> bool {
self >= kw::Auto && self <= kw::Yeet
}
pub fn is_path_segment_keyword(self) -> bool {
self == kw::Super
|| self == kw::SelfLower
|| self == kw::SelfUpper
|| self == kw::Crate
|| self == kw::PathRoot
|| self == kw::DollarCrate
}
pub fn is_bool_lit(self) -> bool {
self == kw::True || self == kw::False
}
pub fn can_be_raw(self) -> bool {
self != sym::empty && self != kw::Underscore && !self.is_path_segment_keyword()
}
pub fn is_predefined(index: u32) -> bool {
index < PREDEFINED_SYMBOLS_COUNT
}
}
impl Ident {
pub fn is_special(self) -> bool {
self.name.is_special()
}
pub fn is_used_keyword(self) -> bool {
self.name.is_used_keyword_always()
|| self.name.is_used_keyword_conditional(|| self.span.edition())
}
pub fn is_unused_keyword(self) -> bool {
self.name.is_unused_keyword_always()
|| self.name.is_unused_keyword_conditional(|| self.span.edition())
}
pub fn is_reserved(self) -> bool {
self.name.is_reserved(|| self.span.edition())
}
pub fn is_path_segment_keyword(self) -> bool {
self.name.is_path_segment_keyword()
}
pub fn is_raw_guess(self) -> bool {
self.name.can_be_raw() && self.is_reserved()
}
pub fn is_reserved_lifetime(self) -> bool {
self.is_reserved() && ![kw::Underscore, kw::Static].contains(&self.name)
}
pub fn is_raw_lifetime_guess(self) -> bool {
if self.name.as_str() == "'" {
return false;
}
let ident_without_apostrophe = self.without_first_quote();
ident_without_apostrophe.name != self.name
&& ident_without_apostrophe.name.can_be_raw()
&& ident_without_apostrophe.is_reserved_lifetime()
}
pub fn guess_print_mode(self) -> IdentPrintMode {
if self.is_raw_lifetime_guess() {
IdentPrintMode::RawLifetime
} else if self.is_raw_guess() {
IdentPrintMode::RawIdent
} else {
IdentPrintMode::Normal
}
}
pub fn is_numeric(self) -> bool {
self.as_str().bytes().all(|b| b.is_ascii_digit())
}
}
pub fn used_keywords(edition: impl Copy + FnOnce() -> Edition) -> Vec<Symbol> {
(kw::DollarCrate.as_u32()..kw::Yeet.as_u32())
.filter_map(|kw| {
let kw = Symbol::new(kw);
if kw.is_used_keyword_always() || kw.is_used_keyword_conditional(edition) {
Some(kw)
} else {
None
}
})
.collect()
}