| //! An "interner" is a data structure that associates values with usize tags and | |
| //! allows bidirectional lookup; i.e., given a value, one can easily find the | |
| //! type, and vice versa. | |
| use std::hash::{Hash, Hasher}; | |
| use std::{fmt, str}; | |
| use rustc_arena::DroplessArena; | |
| use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; | |
| use rustc_data_structures::stable_hash::{StableCompare, StableHash, StableHashCtxt, StableHasher}; | |
| use rustc_data_structures::sync::Lock; | |
| use rustc_macros::{Decodable, Encodable, StableHash, symbols}; | |
| use crate::edit_distance::find_best_match_for_name; | |
| use crate::{DUMMY_SP, Edition, Span, with_session_globals}; | |
| #[cfg(test)] | |
| mod tests; | |
| // The proc macro code for this is in `compiler/rustc_macros/src/symbols.rs`. | |
| symbols! { | |
| // This list includes things that are definitely keywords (e.g. `if`), a | |
| // few things that are definitely not keywords (e.g. `{{root}}`) and things | |
| // where there is disagreement between people and/or documents (such as the | |
| // Rust Reference) about whether it is a keyword (e.g. `_`). | |
| // | |
| // If you modify this list, adjust any relevant `Symbol::{is,can_be}_*` | |
| // predicates and `used_keywords`. Also consider adding new keywords to the | |
| // `ui/parser/raw/raw-idents.rs` test. | |
| Keywords { | |
| // Special reserved identifiers used internally for unnamed method | |
| // parameters, crate root module, etc. | |
| // Matching predicates: `is_special`/`is_reserved` | |
| // | |
| // tidy-alphabetical-start | |
| DollarCrate: "$crate", | |
| PathRoot: "{{root}}", | |
| Underscore: "_", | |
| // tidy-alphabetical-end | |
| // Keywords that are used in stable Rust. | |
| // Matching predicates: `is_used_keyword_always`/`is_reserved` | |
| // tidy-alphabetical-start | |
| 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", | |
| // tidy-alphabetical-end | |
| // Keywords that are used in unstable Rust or reserved for future use. | |
| // Matching predicates: `is_unused_keyword_always`/`is_reserved` | |
| // tidy-alphabetical-start | |
| Abstract: "abstract", | |
| Become: "become", | |
| Box: "box", | |
| Do: "do", | |
| Final: "final", | |
| Macro: "macro", | |
| Override: "override", | |
| Priv: "priv", | |
| Typeof: "typeof", | |
| Unsized: "unsized", | |
| Virtual: "virtual", | |
| Yield: "yield", | |
| // tidy-alphabetical-end | |
| // Edition-specific keywords that are used in stable Rust. | |
| // Matching predicates: `is_used_keyword_conditional`/`is_reserved` (if | |
| // the edition suffices) | |
| // tidy-alphabetical-start | |
| Async: "async", // >= 2018 Edition only | |
| Await: "await", // >= 2018 Edition only | |
| Dyn: "dyn", // >= 2018 Edition only | |
| // tidy-alphabetical-end | |
| // Edition-specific keywords that are used in unstable Rust or reserved for future use. | |
| // Matching predicates: `is_unused_keyword_conditional`/`is_reserved` (if | |
| // the edition suffices) | |
| // tidy-alphabetical-start | |
| Gen: "gen", // >= 2024 Edition only | |
| Try: "try", // >= 2018 Edition only | |
| // tidy-alphabetical-end | |
| // "Lifetime keywords": regular keywords with a leading `'`. | |
| // Matching predicates: none | |
| // tidy-alphabetical-start | |
| StaticLifetime: "'static", | |
| UnderscoreLifetime: "'_", | |
| // tidy-alphabetical-end | |
| // Weak keywords, have special meaning only in specific contexts. | |
| // Matching predicates: `is_weak` | |
| // tidy-alphabetical-start | |
| Auto: "auto", | |
| Builtin: "builtin", | |
| Catch: "catch", | |
| ContractEnsures: "contract_ensures", | |
| ContractRequires: "contract_requires", | |
| Default: "default", | |
| MacroRules: "macro_rules", | |
| Raw: "raw", | |
| Reuse: "reuse", | |
| Safe: "safe", | |
| Union: "union", | |
| Yeet: "yeet", | |
| // tidy-alphabetical-end | |
| } | |
| // Pre-interned symbols that can be referred to with `rustc_span::sym::*`. | |
| // | |
| // The symbol is the stringified identifier unless otherwise specified, in | |
| // which case the name should mention the non-identifier punctuation. | |
| // E.g. `sym::proc_dash_macro` represents "proc-macro", and it shouldn't be | |
| // called `sym::proc_macro` because then it's easy to mistakenly think it | |
| // represents "proc_macro". | |
| // | |
| // As well as the symbols listed, there are symbols for the strings | |
| // "0", "1", ..., "9", which are accessible via `sym::integer`. | |
| // | |
| // There is currently no checking that all symbols are used; that would be | |
| // nice to have. | |
| Symbols { | |
| // tidy-alphabetical-start | |
| 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, | |
| Clone, | |
| CoercePointee, | |
| CoercePointeeValidated, | |
| 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, | |
| ExternC, | |
| ExternRust, | |
| Float, | |
| FmtArgumentsNew, | |
| Fn, | |
| FnMut, | |
| FnOnce, | |
| FnPtr, | |
| Formatter, | |
| Forward, | |
| From, | |
| FromIterator, | |
| FromResidual, | |
| GlobalAlloc, | |
| Hash, | |
| HashMap, | |
| HashSet, | |
| Hasher, | |
| InCleanup, | |
| IndexOutput, | |
| Input, | |
| Int, | |
| Into, | |
| IntoFuture, | |
| IntoIterator, | |
| IntoIteratorItem, | |
| IoBufReader, | |
| IrTyKind, | |
| Item, | |
| ItemContext, | |
| Iterator, | |
| IteratorItem, | |
| IteratorMap, | |
| Layout, | |
| Lifetime, | |
| LintPass, | |
| LocalKey, | |
| Mutex, | |
| MutexGuard, | |
| Named, | |
| NonNull, | |
| NonZero, | |
| None, | |
| Normal, | |
| Ok, | |
| Option, | |
| Ord, | |
| Ordering, | |
| Other, | |
| Output, | |
| ParamSet, | |
| PartialEq, | |
| PartialOrd, | |
| Pending, | |
| PinDerefMutHelper, | |
| Pointer, | |
| Poll, | |
| ProcMacro, | |
| 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, | |
| 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, | |
| 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_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_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, | |
| bang, | |
| 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, | |
| 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_attr_trace: "<cfg_attr_trace>", // must not be a valid identifier | |
| cfg_boolean_literals, | |
| cfg_contract_checks, | |
| cfg_doctest, | |
| cfg_emscripten_wasm_eh, | |
| 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_object_format, | |
| cfg_target_thread_local, | |
| cfg_target_vendor, | |
| cfg_trace: "<cfg_trace>", // must not be a valid identifier | |
| cfg_ub_checks, | |
| cfg_version, | |
| cfi, | |
| cfi_encoding, | |
| char, | |
| client, | |
| clippy, | |
| clobber_abi, | |
| clone, | |
| clone_closures, | |
| clone_fn, | |
| clone_from, | |
| 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, | |
| 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, | |
| 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, | |
| 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, | |
| 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_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, | |
| // -------------------------- | |
| // Lang items which are used only for experiments with auto traits with default bounds. | |
| // These lang items are not actually defined in core/std. Experiment is a part of | |
| // `MCP: Low level components for async drop`(https://github.com/rust-lang/compiler-team/issues/727) | |
| 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_unknown, | |
| diagnostic_on_unmatch_args, | |
| dialect, | |
| direct, | |
| 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!>", // use this instead of `sym::empty` for symbols that won't be used | |
| 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_catch_typeinfo, | |
| eh_personality, | |
| eii, | |
| eii_declaration, | |
| eii_internals, | |
| eii_shared_macro, | |
| element_ty, | |
| elf, | |
| // Notes about `sym::empty`: | |
| // - It should only be used when it genuinely means "empty symbol". Use | |
| // `Option<Symbol>` when "no symbol" is a possibility. | |
| // - For dummy symbols that are never used and absolutely must be | |
| // present, it's better to use `sym::dummy` than `sym::empty`, because | |
| // it's clearer that it's intended as a dummy value, and more likely | |
| // to be detected if it accidentally does get used. | |
| empty: "", | |
| empty_braces: "{}", | |
| emscripten_wasm_eh, | |
| enable, | |
| end, | |
| entry_nops, | |
| env, | |
| env_CFG_RELEASE: env!("CFG_RELEASE"), | |
| eq, | |
| ergonomic_clones, | |
| ermsb_target_feature, | |
| exact_div, | |
| except, | |
| exception_handling: "exception-handling", | |
| exclusive_range_pattern, | |
| exhaustive_integer_patterns, | |
| exhaustive_patterns, | |
| existential_type, | |
| exp2f16, | |
| exp2f32, | |
| exp2f64, | |
| exp2f128, | |
| 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, | |
| 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_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_addr, | |
| fn_ptr_trait, | |
| forbid, | |
| force_target_feature, | |
| forget, | |
| format_args, | |
| format_args_capture, | |
| format_args_nl, | |
| format_argument, | |
| format_arguments, | |
| format_macro, | |
| 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_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, | |
| 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, | |
| integer_: "integer", // underscore to avoid clashing with the function `sym::integer` below | |
| integral, | |
| internal, | |
| internal_eq_trait_method_impls, | |
| internal_features, | |
| into_async_iter_into_iter, | |
| into_future, | |
| into_iter, | |
| into_try_type, | |
| intra_doc_pointers, | |
| intrinsics, | |
| irrefutable_let_patterns, | |
| is, | |
| is_auto, | |
| 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, | |
| last, | |
| 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_match, | |
| lr, | |
| lt, | |
| m68k, | |
| m68k_target_feature, | |
| 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, | |
| 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, | |
| 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, | |
| 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, | |
| 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, | |
| 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, | |
| 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_unimplemented, | |
| on_unknown, | |
| on_unmatch_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_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, | |
| 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, | |
| 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_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_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, | |
| 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_eh_catch_typeinfo, | |
| rust_eh_personality, | |
| rust_future, | |
| rust_logo, | |
| rust_out, | |
| rust_preserve_none_cc, | |
| rustc, | |
| rustc_abi, | |
| // FIXME(#82232, #143834): temporary name to mitigate `#[align]` nameres ambiguity | |
| rustc_align, | |
| rustc_align_static, | |
| rustc_allocator, | |
| rustc_allocator_zeroed, | |
| rustc_allocator_zeroed_variant, | |
| rustc_allow_const_fn_unstable, | |
| rustc_allow_incoherent_impl, | |
| rustc_allowed_through_unstable_modules, | |
| rustc_as_ptr, | |
| rustc_attrs, | |
| rustc_autodiff, | |
| rustc_builtin_macro, | |
| rustc_capture_analysis, | |
| rustc_clean, | |
| rustc_coherence_is_core, | |
| rustc_coinductive, | |
| 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_do_not_const_check, | |
| rustc_doc_primitive, | |
| rustc_driver, | |
| rustc_dummy, | |
| rustc_dump_def_parents, | |
| rustc_dump_def_path, | |
| rustc_dump_hidden_type_of_opaques, | |
| rustc_dump_inferred_outlives, | |
| rustc_dump_item_bounds, | |
| rustc_dump_layout, | |
| rustc_dump_object_lifetime_defaults, | |
| rustc_dump_predicates, | |
| 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_never_type_options, | |
| 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_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_reservation_impl, | |
| 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_std_internal_symbol, | |
| rustc_strict_coherence, | |
| rustc_test_marker, | |
| rustc_then_this_would_need, | |
| rustc_trivial_field_reads, | |
| rustc_unsafe_specialization_marker, | |
| rustdoc, | |
| rustdoc_internals, | |
| rustdoc_missing_doc_code_examples, | |
| rustfmt, | |
| rvalue_static_promotion, | |
| rwpi, | |
| s390x, | |
| s390x_target_feature, | |
| s390x_target_feature_vector, | |
| safety, | |
| sanitize, | |
| sanitizer_cfi_generalize_pointers, | |
| sanitizer_cfi_normalize_integers, | |
| sanitizer_runtime, | |
| saturating_add, | |
| saturating_sub, | |
| sdylib, | |
| search_unbox, | |
| select_unpredictable, | |
| self_in_typedefs, | |
| self_struct_ctor, | |
| semiopaque, | |
| 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, | |
| 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_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_case, | |
| test_incomplete_feature, | |
| test_removed_feature, | |
| test_runner, | |
| test_unstable_lint, | |
| thread, | |
| thread_local, | |
| three_way_compare, | |
| thumb2, | |
| thumb_mode: "thumb-mode", | |
| 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_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_vtable, | |
| type_info, | |
| 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, | |
| unit, | |
| universal_impl_trait, | |
| unix, | |
| unlikely, | |
| unmarked_api, | |
| 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, | |
| va_arg, | |
| va_arg_safe, | |
| va_copy, | |
| va_end, | |
| va_list, | |
| va_start, | |
| val, | |
| validity, | |
| value, | |
| values, | |
| var, | |
| variadic, | |
| variant_count, | |
| variants, | |
| vec, | |
| vector, | |
| verbatim, | |
| version, | |
| vfp2, | |
| 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, | |
| 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, | |
| xmm_reg, | |
| xop_target_feature, | |
| xtensa, | |
| yeet_desugar_details, | |
| yeet_expr, | |
| yes, | |
| yield_expr, | |
| ymm_reg, | |
| yreg, | |
| zca, | |
| zfh, | |
| zfhmin, | |
| zmm_reg, | |
| ztso, | |
| // tidy-alphabetical-end | |
| } | |
| } | |
| /// Symbols for crates that are part of the stable standard library: `std`, `core`, `alloc`, and | |
| /// `proc_macro`. | |
| 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 { | |
| /// `name` should never be the empty symbol. If you are considering that, | |
| /// you are probably conflating "empty identifier with "no identifier" and | |
| /// you should use `Option<Ident>` instead. | |
| /// Trying to construct an `Ident` with an empty name will trigger debug assertions. | |
| pub name: Symbol, | |
| pub span: Span, | |
| } | |
| impl Ident { | |
| #[inline] | |
| /// Constructs a new identifier from a symbol and a span. | |
| pub fn new(name: Symbol, span: Span) -> Ident { | |
| debug_assert_ne!(name, sym::empty); | |
| Ident { name, span } | |
| } | |
| /// Constructs a new identifier with a dummy span. | |
| #[inline] | |
| pub fn with_dummy_span(name: Symbol) -> Ident { | |
| Ident::new(name, DUMMY_SP) | |
| } | |
| // For dummy identifiers that are never used and absolutely must be | |
| // present. Note that this does *not* use the empty symbol; `sym::dummy` | |
| // makes it clear that it's intended as a dummy value, and is more likely | |
| // to be detected if it accidentally does get used. | |
| #[inline] | |
| pub fn dummy() -> Ident { | |
| Ident::with_dummy_span(sym::dummy) | |
| } | |
| /// Maps a string to an identifier with a dummy span. | |
| pub fn from_str(string: &str) -> Ident { | |
| Ident::with_dummy_span(Symbol::intern(string)) | |
| } | |
| /// Maps a string and a span to an identifier. | |
| pub fn from_str_and_span(string: &str, span: Span) -> Ident { | |
| Ident::new(Symbol::intern(string), span) | |
| } | |
| /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context. | |
| pub fn with_span_pos(self, span: Span) -> Ident { | |
| Ident::new(self.name, span.with_ctxt(self.span.ctxt())) | |
| } | |
| /// Creates a new ident with the same span and name with leading quote removed, if any. | |
| /// Calling it on a `'` ident will return an empty ident, which triggers debug assertions. | |
| pub fn without_first_quote(self) -> Ident { | |
| self.as_str() | |
| .strip_prefix('\'') | |
| .map_or(self, |name| Ident::new(Symbol::intern(name), self.span)) | |
| } | |
| /// "Normalize" ident for use in comparisons using "item hygiene". | |
| /// Identifiers with same string value become same if they came from the same macro 2.0 macro | |
| /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from | |
| /// different macro 2.0 macros. | |
| /// Technically, this operation strips all non-opaque marks from ident's syntactic context. | |
| pub fn normalize_to_macros_2_0(self) -> Ident { | |
| Ident::new(self.name, self.span.normalize_to_macros_2_0()) | |
| } | |
| /// "Normalize" ident for use in comparisons using "local variable hygiene". | |
| /// Identifiers with same string value become same if they came from the same non-transparent | |
| /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different | |
| /// non-transparent macros. | |
| /// Technically, this operation strips all transparent marks from ident's syntactic context. | |
| #[inline] | |
| pub fn normalize_to_macro_rules(self) -> Ident { | |
| Ident::new(self.name, self.span.normalize_to_macro_rules()) | |
| } | |
| /// Access the underlying string. This is a slowish operation because it | |
| /// requires locking the symbol interner. | |
| /// | |
| /// Note that the lifetime of the return value is a lie. See | |
| /// `Symbol::as_str()` for details. | |
| 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) | |
| } | |
| } | |
| /// This implementation is supposed to be used in error messages, so it's expected to be identical | |
| /// to printing the original identifier token written in source code (`token_to_string`), | |
| /// except that AST identifiers don't keep the rawness flag, so we have to guess it. | |
| 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, | |
| } | |
| /// The most general type to print identifiers. | |
| /// | |
| /// AST pretty-printer is used as a fallback for turning AST structures into token streams for | |
| /// proc macros. Additionally, proc macros may stringify their input and expect it survive the | |
| /// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30). | |
| /// So we need to somehow pretty-print `$crate` in a way preserving at least some of its | |
| /// hygiene data, most importantly name of the crate it refers to. | |
| /// As a result we print `$crate` as `crate` if it refers to the local crate | |
| /// and as `::other_crate_name` if it refers to some other crate. | |
| /// Note, that this is only done if the ident token is printed from inside of AST pretty-printing, | |
| /// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents, | |
| /// so we should not perform this lossy conversion if the top level call to the pretty-printer was | |
| /// done for a token stream or a single token. | |
| pub struct IdentPrinter { | |
| symbol: Symbol, | |
| mode: IdentPrintMode, | |
| /// Span used for retrieving the crate name to which `$crate` refers to, | |
| /// if this field is `None` then the `$crate` conversion doesn't happen. | |
| convert_dollar_crate: Option<Span>, | |
| } | |
| impl IdentPrinter { | |
| /// The most general `IdentPrinter` constructor. Do not use this. | |
| pub fn new( | |
| symbol: Symbol, | |
| mode: IdentPrintMode, | |
| convert_dollar_crate: Option<Span>, | |
| ) -> IdentPrinter { | |
| IdentPrinter { symbol, mode, convert_dollar_crate } | |
| } | |
| /// This implementation is supposed to be used when printing identifiers | |
| /// as a part of pretty-printing for larger AST pieces. | |
| /// Do not use this either. | |
| 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) | |
| } | |
| } | |
| /// A newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on | |
| /// construction for "local variable hygiene" comparisons. | |
| /// | |
| /// Use this type when you need to compare identifiers according to macro_rules hygiene. | |
| /// This ensures compile-time safety and avoids manual normalization calls. | |
| #[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) | |
| } | |
| } | |
| /// An interned UTF-8 string. | |
| /// | |
| /// Internally, a `Symbol` is implemented as an index, and all operations | |
| /// (including hashing, equality, and ordering) operate on that index. The use | |
| /// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes, | |
| /// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes. | |
| /// | |
| /// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it | |
| /// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways. | |
| #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | |
| pub struct Symbol(SymbolIndex); | |
| // Used within both `Symbol` and `ByteSymbol`. | |
| rustc_index::newtype_index! { | |
| #[orderable] | |
| struct SymbolIndex {} | |
| } | |
| impl Symbol { | |
| /// Avoid this except for things like deserialization of previously | |
| /// serialized symbols, and testing. Use `intern` instead. | |
| pub const fn new(n: u32) -> Self { | |
| Symbol(SymbolIndex::from_u32(n)) | |
| } | |
| /// Maps a string to its interned representation. | |
| #[rustc_diagnostic_item = "SymbolIntern"] | |
| pub fn intern(str: &str) -> Self { | |
| with_session_globals(|session_globals| session_globals.symbol_interner.intern_str(str)) | |
| } | |
| /// Access the underlying string. This is a slowish operation because it | |
| /// requires locking the symbol interner. | |
| /// | |
| /// Note that the lifetime of the return value is a lie. It's not the same | |
| /// as `&self`, but actually tied to the lifetime of the underlying | |
| /// interner. Interners are long-lived, and there are very few of them, and | |
| /// this function is typically used for short-lived things, so in practice | |
| /// it works out ok. | |
| pub fn as_str(&self) -> &str { | |
| with_session_globals(|session_globals| unsafe { | |
| std::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 | |
| } | |
| /// This method is supposed to be used in error messages, so it's expected to be | |
| /// identical to printing the original identifier token written in source code | |
| /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag | |
| /// or edition, so we have to guess the rawness using the global edition. | |
| pub fn to_ident_string(self) -> String { | |
| // Avoid creating an empty identifier, because that asserts in debug builds. | |
| if self == sym::empty { String::new() } else { Ident::with_dummy_span(self).to_string() } | |
| } | |
| /// Checks if `self` is similar to any symbol in `candidates`. | |
| /// | |
| /// The returned boolean represents whether the candidate is the same symbol with a different | |
| /// casing. | |
| /// | |
| /// All the candidates are assumed to be lowercase. | |
| 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) -> std::cmp::Ordering { | |
| self.as_str().cmp(other.as_str()) | |
| } | |
| } | |
| /// Like `Symbol`, but for byte strings. `ByteSymbol` is used less widely, so | |
| /// it has fewer operations defined than `Symbol`. | |
| #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | |
| pub struct ByteSymbol(SymbolIndex); | |
| impl ByteSymbol { | |
| /// Avoid this except for things like deserialization of previously | |
| /// serialized symbols, and testing. Use `intern` instead. | |
| pub const fn new(n: u32) -> Self { | |
| ByteSymbol(SymbolIndex::from_u32(n)) | |
| } | |
| /// Maps a string to its interned representation. | |
| pub fn intern(byte_str: &[u8]) -> Self { | |
| with_session_globals(|session_globals| { | |
| session_globals.symbol_interner.intern_byte_str(byte_str) | |
| }) | |
| } | |
| /// Like `Symbol::as_str`. | |
| pub fn as_byte_str(&self) -> &[u8] { | |
| with_session_globals(|session_globals| unsafe { | |
| std::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); | |
| } | |
| } | |
| // Interner used for both `Symbol`s and `ByteSymbol`s. If a string and a byte | |
| // string with identical contents (e.g. "foo" and b"foo") are both interned, | |
| // only one copy will be stored and the resulting `Symbol` and `ByteSymbol` | |
| // will have the same index. | |
| pub(crate) struct Interner(Lock<InternerInner>); | |
| // The `&'static [u8]`s in this type actually point into the arena. | |
| // | |
| // This type is private to prevent accidentally constructing more than one | |
| // `Interner` on the same thread, which makes it easy to mix up `Symbol`s | |
| // between `Interner`s. | |
| struct InternerInner { | |
| arena: DroplessArena, | |
| byte_strs: FxIndexSet<&'static [u8]>, | |
| } | |
| impl Interner { | |
| // These arguments are `&str`, but because of the sharing, we are | |
| // effectively pre-interning all these strings for both `Symbol` and | |
| // `ByteSymbol`. | |
| fn prefill(init: &[&'static str], extra: &[&'static str]) -> Self { | |
| let byte_strs = FxIndexSet::from_iter( | |
| init.iter().copied().chain(extra.iter().copied()).map(|str| str.as_bytes()), | |
| ); | |
| // The order in which duplicates are reported is irrelevant. | |
| #[expect(rustc::potential_query_instability)] | |
| if byte_strs.len() != init.len() + extra.len() { | |
| panic!( | |
| "duplicate symbols in the rustc symbol list and the extra symbols added by the driver: {:?}", | |
| FxHashSet::intersection( | |
| &init.iter().copied().collect(), | |
| &extra.iter().copied().collect(), | |
| ) | |
| .collect::<Vec<_>>() | |
| ) | |
| } | |
| Interner(Lock::new(InternerInner { arena: Default::default(), 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 mut inner = self.0.lock(); | |
| if let Some(idx) = inner.byte_strs.get_index_of(byte_str) { | |
| return idx as u32; | |
| } | |
| let byte_str: &[u8] = inner.arena.alloc_slice(byte_str); | |
| // SAFETY: we can extend the arena allocation to `'static` because we | |
| // only access these while the arena is still alive. | |
| let byte_str: &'static [u8] = unsafe { &*(byte_str as *const [u8]) }; | |
| // This second hash table lookup can be avoided by using `RawEntryMut`, | |
| // but this code path isn't hot enough for it to be worth it. See | |
| // #91445 for details. | |
| let (idx, is_new) = inner.byte_strs.insert_full(byte_str); | |
| debug_assert!(is_new); // due to the get_index_of check above | |
| idx as u32 | |
| } | |
| /// Get the symbol as a string. | |
| /// | |
| /// [`Symbol::as_str()`] should be used in preference to this function. | |
| fn get_str(&self, symbol: Symbol) -> &str { | |
| let byte_str = self.get_inner(symbol.0.as_usize()); | |
| // SAFETY: known to be a UTF8 string because it's a `Symbol`. | |
| unsafe { str::from_utf8_unchecked(byte_str) } | |
| } | |
| /// Get the symbol as a string. | |
| /// | |
| /// [`ByteSymbol::as_byte_str()`] should be used in preference to this function. | |
| fn get_byte_str(&self, symbol: ByteSymbol) -> &[u8] { | |
| self.get_inner(symbol.0.as_usize()) | |
| } | |
| fn get_inner(&self, index: usize) -> &[u8] { | |
| self.0.lock().byte_strs.get_index(index).unwrap() | |
| } | |
| } | |
| // This module has a very short name because it's used a lot. | |
| /// This module contains all the defined keyword `Symbol`s. | |
| /// | |
| /// Given that `kw` is imported, use them like `kw::keyword_name`. | |
| /// For example `kw::Loop` or `kw::Break`. | |
| pub mod kw { | |
| pub use super::kw_generated::*; | |
| } | |
| // This module has a very short name because it's used a lot. | |
| /// This module contains all the defined non-keyword `Symbol`s. | |
| /// | |
| /// Given that `sym` is imported, use them like `sym::symbol_name`. | |
| /// For example `sym::rustfmt` or `sym::u8`. | |
| pub mod sym { | |
| // Used from a macro in `librustc_feature/accepted.rs` | |
| use super::Symbol; | |
| pub use super::kw::MacroRules as macro_rules; | |
| #[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 | |
| /// are fast. | |
| 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 | |
| } | |
| /// A keyword or reserved identifier that can be used as a path segment. | |
| 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 | |
| } | |
| /// Returns `true` if the symbol is `true` or `false`. | |
| pub fn is_bool_lit(self) -> bool { | |
| self == kw::True || self == kw::False | |
| } | |
| /// Returns `true` if this symbol can be a raw identifier. | |
| pub fn can_be_raw(self) -> bool { | |
| self != sym::empty && self != kw::Underscore && !self.is_path_segment_keyword() | |
| } | |
| /// Was this symbol index predefined in the compiler's `symbols!` macro? | |
| /// Note: this applies to both `Symbol`s and `ByteSymbol`s, which is why it | |
| /// takes a `u32` argument instead of a `&self` argument. Use with care. | |
| pub fn is_predefined(index: u32) -> bool { | |
| index < PREDEFINED_SYMBOLS_COUNT | |
| } | |
| } | |
| impl Ident { | |
| /// Returns `true` for reserved identifiers used internally for elided lifetimes, | |
| /// unnamed method parameters, crate root module, error recovery etc. | |
| pub fn is_special(self) -> bool { | |
| self.name.is_special() | |
| } | |
| /// Returns `true` if the token is a keyword used in the language. | |
| pub fn is_used_keyword(self) -> bool { | |
| // Note: `span.edition()` is relatively expensive, don't call it unless necessary. | |
| self.name.is_used_keyword_always() | |
| || self.name.is_used_keyword_conditional(|| self.span.edition()) | |
| } | |
| /// Returns `true` if the token is a keyword reserved for possible future use. | |
| pub fn is_unused_keyword(self) -> bool { | |
| // Note: `span.edition()` is relatively expensive, don't call it unless necessary. | |
| self.name.is_unused_keyword_always() | |
| || self.name.is_unused_keyword_conditional(|| self.span.edition()) | |
| } | |
| /// Returns `true` if the token is either a special identifier or a keyword. | |
| pub fn is_reserved(self) -> bool { | |
| // Note: `span.edition()` is relatively expensive, don't call it unless necessary. | |
| self.name.is_reserved(|| self.span.edition()) | |
| } | |
| /// A keyword or reserved identifier that can be used as a path segment. | |
| pub fn is_path_segment_keyword(self) -> bool { | |
| self.name.is_path_segment_keyword() | |
| } | |
| /// We see this identifier in a normal identifier position, like variable name or a type. | |
| /// How was it written originally? Did it use the raw form? Let's try to guess. | |
| pub fn is_raw_guess(self) -> bool { | |
| self.name.can_be_raw() && self.is_reserved() | |
| } | |
| /// Given the name of a lifetime without the first quote (`'`), | |
| /// returns whether the lifetime name is reserved (therefore invalid) | |
| 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 { | |
| // Check that the name isn't just a single quote. | |
| // `self.without_first_quote()` would return empty ident, which triggers debug assert. | |
| 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 | |
| } | |
| } | |
| /// Whether this would be the identifier for a tuple field like `self.0`, as | |
| /// opposed to a named field like `self.thing`. | |
| pub fn is_numeric(self) -> bool { | |
| self.as_str().bytes().all(|b| b.is_ascii_digit()) | |
| } | |
| } | |
| /// Collect all the keywords in a given edition into a vector. | |
| /// | |
| /// *Note:* Please update this if a new keyword is added beyond the current | |
| /// range. | |
| 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() | |
| } |