rustc_span/
symbol.rs

1//! An "interner" is a data structure that associates values with usize tags and
2//! allows bidirectional lookup; i.e., given a value, one can easily find the
3//! type, and vice versa.
4
5use std::hash::{Hash, Hasher};
6use std::ops::Deref;
7use std::{fmt, str};
8
9use rustc_arena::DroplessArena;
10use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
11use rustc_data_structures::stable_hasher::{
12    HashStable, StableCompare, StableHasher, ToStableHashKey,
13};
14use rustc_data_structures::sync::Lock;
15use rustc_macros::{Decodable, Encodable, HashStable_Generic, symbols};
16
17use crate::{DUMMY_SP, Edition, Span, with_session_globals};
18
19#[cfg(test)]
20mod tests;
21
22// The proc macro code for this is in `compiler/rustc_macros/src/symbols.rs`.
23symbols! {
24    // This list includes things that are definitely keywords (e.g. `if`), a
25    // few things that are definitely not keywords (e.g. `{{root}}`) and things
26    // where there is disagreement between people and/or documents (such as the
27    // Rust Reference) about whether it is a keyword (e.g. `_`).
28    //
29    // If you modify this list, adjust any relevant `Symbol::{is,can_be}_*`
30    // predicates and `used_keywords`. Also consider adding new keywords to the
31    // `ui/parser/raw/raw-idents.rs` test.
32    Keywords {
33        // Special reserved identifiers used internally for unnamed method
34        // parameters, crate root module, etc.
35        // Matching predicates: `is_special`/`is_reserved`
36        //
37        // tidy-alphabetical-start
38        DollarCrate:        "$crate",
39        PathRoot:           "{{root}}",
40        Underscore:         "_",
41        // tidy-alphabetical-end
42
43        // Keywords that are used in stable Rust.
44        // Matching predicates: `is_used_keyword_always`/`is_reserved`
45        // tidy-alphabetical-start
46        As:                 "as",
47        Break:              "break",
48        Const:              "const",
49        Continue:           "continue",
50        Crate:              "crate",
51        Else:               "else",
52        Enum:               "enum",
53        Extern:             "extern",
54        False:              "false",
55        Fn:                 "fn",
56        For:                "for",
57        If:                 "if",
58        Impl:               "impl",
59        In:                 "in",
60        Let:                "let",
61        Loop:               "loop",
62        Match:              "match",
63        Mod:                "mod",
64        Move:               "move",
65        Mut:                "mut",
66        Pub:                "pub",
67        Ref:                "ref",
68        Return:             "return",
69        SelfLower:          "self",
70        SelfUpper:          "Self",
71        Static:             "static",
72        Struct:             "struct",
73        Super:              "super",
74        Trait:              "trait",
75        True:               "true",
76        Type:               "type",
77        Unsafe:             "unsafe",
78        Use:                "use",
79        Where:              "where",
80        While:              "while",
81        // tidy-alphabetical-end
82
83        // Keywords that are used in unstable Rust or reserved for future use.
84        // Matching predicates: `is_unused_keyword_always`/`is_reserved`
85        // tidy-alphabetical-start
86        Abstract:           "abstract",
87        Become:             "become",
88        Box:                "box",
89        Do:                 "do",
90        Final:              "final",
91        Macro:              "macro",
92        Override:           "override",
93        Priv:               "priv",
94        Typeof:             "typeof",
95        Unsized:            "unsized",
96        Virtual:            "virtual",
97        Yield:              "yield",
98        // tidy-alphabetical-end
99
100        // Edition-specific keywords that are used in stable Rust.
101        // Matching predicates: `is_used_keyword_conditional`/`is_reserved` (if
102        // the edition suffices)
103        // tidy-alphabetical-start
104        Async:              "async", // >= 2018 Edition only
105        Await:              "await", // >= 2018 Edition only
106        Dyn:                "dyn", // >= 2018 Edition only
107        // tidy-alphabetical-end
108
109        // Edition-specific keywords that are used in unstable Rust or reserved for future use.
110        // Matching predicates: `is_unused_keyword_conditional`/`is_reserved` (if
111        // the edition suffices)
112        // tidy-alphabetical-start
113        Gen:                "gen", // >= 2024 Edition only
114        Try:                "try", // >= 2018 Edition only
115        // tidy-alphabetical-end
116
117        // "Lifetime keywords": regular keywords with a leading `'`.
118        // Matching predicates: none
119        // tidy-alphabetical-start
120        StaticLifetime:     "'static",
121        UnderscoreLifetime: "'_",
122        // tidy-alphabetical-end
123
124        // Weak keywords, have special meaning only in specific contexts.
125        // Matching predicates: `is_weak`
126        // tidy-alphabetical-start
127        Auto:               "auto",
128        Builtin:            "builtin",
129        Catch:              "catch",
130        ContractEnsures:    "contract_ensures",
131        ContractRequires:   "contract_requires",
132        Default:            "default",
133        MacroRules:         "macro_rules",
134        Raw:                "raw",
135        Reuse:              "reuse",
136        Safe:               "safe",
137        Union:              "union",
138        Yeet:               "yeet",
139        // tidy-alphabetical-end
140    }
141
142    // Pre-interned symbols that can be referred to with `rustc_span::sym::*`.
143    //
144    // The symbol is the stringified identifier unless otherwise specified, in
145    // which case the name should mention the non-identifier punctuation.
146    // E.g. `sym::proc_dash_macro` represents "proc-macro", and it shouldn't be
147    // called `sym::proc_macro` because then it's easy to mistakenly think it
148    // represents "proc_macro".
149    //
150    // As well as the symbols listed, there are symbols for the strings
151    // "0", "1", ..., "9", which are accessible via `sym::integer`.
152    //
153    // There is currently no checking that all symbols are used; that would be
154    // nice to have.
155    Symbols {
156        // tidy-alphabetical-start
157        Abi,
158        AcqRel,
159        Acquire,
160        Any,
161        Arc,
162        ArcWeak,
163        Argument,
164        ArrayIntoIter,
165        AsMut,
166        AsRef,
167        AssertParamIsClone,
168        AssertParamIsCopy,
169        AssertParamIsEq,
170        AsyncGenFinished,
171        AsyncGenPending,
172        AsyncGenReady,
173        AtomicBool,
174        AtomicI8,
175        AtomicI16,
176        AtomicI32,
177        AtomicI64,
178        AtomicI128,
179        AtomicIsize,
180        AtomicPtr,
181        AtomicU8,
182        AtomicU16,
183        AtomicU32,
184        AtomicU64,
185        AtomicU128,
186        AtomicUsize,
187        BTreeEntry,
188        BTreeMap,
189        BTreeSet,
190        BinaryHeap,
191        Borrow,
192        BorrowMut,
193        Break,
194        BuildHasher,
195        C,
196        CStr,
197        C_dash_unwind: "C-unwind",
198        CallOnceFuture,
199        CallRefFuture,
200        Capture,
201        Cell,
202        Center,
203        Child,
204        Cleanup,
205        Clone,
206        CoercePointee,
207        CoercePointeeValidated,
208        CoerceUnsized,
209        Command,
210        ConstParamTy,
211        ConstParamTy_,
212        Context,
213        Continue,
214        ControlFlow,
215        Copy,
216        Cow,
217        Debug,
218        DebugStruct,
219        Decodable,
220        Decoder,
221        Default,
222        Deref,
223        DiagMessage,
224        Diagnostic,
225        DirBuilder,
226        DispatchFromDyn,
227        Display,
228        DoubleEndedIterator,
229        Duration,
230        Encodable,
231        Encoder,
232        Enumerate,
233        Eq,
234        Equal,
235        Err,
236        Error,
237        File,
238        FileType,
239        FmtArgumentsNew,
240        FmtWrite,
241        Fn,
242        FnMut,
243        FnOnce,
244        Formatter,
245        Forward,
246        From,
247        FromIterator,
248        FromResidual,
249        FsOpenOptions,
250        FsPermissions,
251        FusedIterator,
252        Future,
253        GlobalAlloc,
254        Hash,
255        HashMap,
256        HashMapEntry,
257        HashSet,
258        Hasher,
259        Implied,
260        InCleanup,
261        IndexOutput,
262        Input,
263        Instant,
264        Into,
265        IntoFuture,
266        IntoIterator,
267        IoBufRead,
268        IoLines,
269        IoRead,
270        IoSeek,
271        IoWrite,
272        IpAddr,
273        Ipv4Addr,
274        Ipv6Addr,
275        IrTyKind,
276        Is,
277        Item,
278        ItemContext,
279        IterEmpty,
280        IterOnce,
281        IterPeekable,
282        Iterator,
283        IteratorItem,
284        IteratorMap,
285        Layout,
286        Left,
287        LinkedList,
288        LintDiagnostic,
289        LintPass,
290        LocalKey,
291        Mutex,
292        MutexGuard,
293        N,
294        NonNull,
295        NonZero,
296        None,
297        Normal,
298        Ok,
299        Option,
300        Ord,
301        Ordering,
302        OsStr,
303        OsString,
304        Output,
305        Param,
306        ParamSet,
307        PartialEq,
308        PartialOrd,
309        Path,
310        PathBuf,
311        Pending,
312        PinCoerceUnsized,
313        PinDerefMutHelper,
314        Pointer,
315        Poll,
316        ProcMacro,
317        ProceduralMasqueradeDummyType,
318        Range,
319        RangeBounds,
320        RangeCopy,
321        RangeFrom,
322        RangeFromCopy,
323        RangeFull,
324        RangeInclusive,
325        RangeInclusiveCopy,
326        RangeMax,
327        RangeMin,
328        RangeSub,
329        RangeTo,
330        RangeToInclusive,
331        RangeToInclusiveCopy,
332        Rc,
333        RcWeak,
334        Ready,
335        Receiver,
336        RefCell,
337        RefCellRef,
338        RefCellRefMut,
339        Relaxed,
340        Release,
341        Result,
342        ResumeTy,
343        Return,
344        Reverse,
345        Right,
346        Rust,
347        RustaceansAreAwesome,
348        RwLock,
349        RwLockReadGuard,
350        RwLockWriteGuard,
351        Saturating,
352        SeekFrom,
353        SelfTy,
354        Send,
355        SeqCst,
356        Sized,
357        SliceIndex,
358        SliceIter,
359        Some,
360        SpanCtxt,
361        Stdin,
362        String,
363        StructuralPartialEq,
364        SubdiagMessage,
365        Subdiagnostic,
366        SymbolIntern,
367        Sync,
368        SyncUnsafeCell,
369        T,
370        Target,
371        This,
372        ToOwned,
373        ToString,
374        TokenStream,
375        Trait,
376        TrivialClone,
377        Try,
378        TryCaptureGeneric,
379        TryCapturePrintable,
380        TryFrom,
381        TryInto,
382        Ty,
383        TyCtxt,
384        TyKind,
385        Unknown,
386        Unsize,
387        UnsizedConstParamTy,
388        Upvars,
389        Vec,
390        VecDeque,
391        Waker,
392        Wrapper,
393        Wrapping,
394        Yield,
395        _DECLS,
396        __D,
397        __H,
398        __S,
399        __T,
400        __awaitee,
401        __try_var,
402        _t,
403        _task_context,
404        a32,
405        aarch64,
406        aarch64_target_feature,
407        aarch64_unstable_target_feature,
408        aarch64_ver_target_feature,
409        abi,
410        abi_amdgpu_kernel,
411        abi_avr_interrupt,
412        abi_c_cmse_nonsecure_call,
413        abi_cmse_nonsecure_call,
414        abi_custom,
415        abi_efiapi,
416        abi_gpu_kernel,
417        abi_msp430_interrupt,
418        abi_ptx,
419        abi_riscv_interrupt,
420        abi_sysv64,
421        abi_thiscall,
422        abi_unadjusted,
423        abi_vectorcall,
424        abi_x86_interrupt,
425        abort,
426        add,
427        add_assign,
428        add_with_overflow,
429        address,
430        adt_const_params,
431        advanced_slice_patterns,
432        adx_target_feature,
433        aes,
434        aggregate_raw_ptr,
435        alias,
436        align,
437        align_of,
438        align_of_val,
439        alignment,
440        all,
441        alloc,
442        alloc_error_handler,
443        alloc_layout,
444        alloc_zeroed,
445        allocator,
446        allocator_api,
447        allocator_internals,
448        allow,
449        allow_fail,
450        allow_internal_unsafe,
451        allow_internal_unstable,
452        altivec,
453        alu32,
454        always,
455        amdgpu,
456        analysis,
457        and,
458        and_then,
459        anon,
460        anon_adt,
461        anon_assoc,
462        anonymous_lifetime_in_impl_trait,
463        any,
464        append_const_msg,
465        apx_target_feature,
466        arbitrary_enum_discriminant,
467        arbitrary_self_types,
468        arbitrary_self_types_pointers,
469        areg,
470        args,
471        arith_offset,
472        arm,
473        arm64ec,
474        arm_target_feature,
475        array,
476        as_dash_needed: "as-needed",
477        as_ptr,
478        as_ref,
479        as_str,
480        asm,
481        asm_cfg,
482        asm_const,
483        asm_experimental_arch,
484        asm_experimental_reg,
485        asm_goto,
486        asm_goto_with_outputs,
487        asm_sym,
488        asm_unwind,
489        assert,
490        assert_eq,
491        assert_eq_macro,
492        assert_inhabited,
493        assert_macro,
494        assert_mem_uninitialized_valid,
495        assert_ne_macro,
496        assert_receiver_is_total_eq,
497        assert_zero_valid,
498        asserting,
499        associated_const_equality,
500        associated_consts,
501        associated_type_bounds,
502        associated_type_defaults,
503        associated_types,
504        assume,
505        assume_init,
506        asterisk: "*",
507        async_await,
508        async_call,
509        async_call_mut,
510        async_call_once,
511        async_closure,
512        async_drop,
513        async_drop_in_place,
514        async_fn,
515        async_fn_in_dyn_trait,
516        async_fn_in_trait,
517        async_fn_kind_helper,
518        async_fn_kind_upvars,
519        async_fn_mut,
520        async_fn_once,
521        async_fn_once_output,
522        async_fn_track_caller,
523        async_fn_traits,
524        async_for_loop,
525        async_gen_internals,
526        async_iterator,
527        async_iterator_poll_next,
528        async_trait_bounds,
529        atomic,
530        atomic_and,
531        atomic_cxchg,
532        atomic_cxchgweak,
533        atomic_fence,
534        atomic_load,
535        atomic_max,
536        atomic_min,
537        atomic_mod,
538        atomic_nand,
539        atomic_or,
540        atomic_singlethreadfence,
541        atomic_store,
542        atomic_umax,
543        atomic_umin,
544        atomic_xadd,
545        atomic_xchg,
546        atomic_xor,
547        atomic_xsub,
548        atomics,
549        att_syntax,
550        attr,
551        attr_literals,
552        attribute,
553        attributes,
554        audit_that,
555        augmented_assignments,
556        auto_cfg,
557        auto_traits,
558        autodiff,
559        autodiff_forward,
560        autodiff_reverse,
561        automatically_derived,
562        available_externally,
563        avr,
564        avx,
565        avx10_target_feature,
566        avx512_target_feature,
567        avx512bw,
568        avx512f,
569        await_macro,
570        bang,
571        begin_panic,
572        bench,
573        bevy_ecs,
574        bikeshed_guaranteed_no_drop,
575        bin,
576        binaryheap_iter,
577        bind_by_move_pattern_guards,
578        bindings_after_at,
579        bitand,
580        bitand_assign,
581        bitor,
582        bitor_assign,
583        bitreverse,
584        bitxor,
585        bitxor_assign,
586        black_box,
587        block,
588        blocking,
589        bool,
590        bool_then,
591        borrowck_graphviz_format,
592        borrowck_graphviz_postflow,
593        box_new,
594        box_patterns,
595        box_syntax,
596        boxed_slice,
597        bpf,
598        bpf_target_feature,
599        braced_empty_structs,
600        branch,
601        breakpoint,
602        bridge,
603        bswap,
604        btreemap_contains_key,
605        btreemap_insert,
606        btreeset_iter,
607        built,
608        builtin_syntax,
609        bundle,
610        c,
611        c_dash_variadic,
612        c_str,
613        c_str_literals,
614        c_unwind,
615        c_variadic,
616        c_variadic_naked_functions,
617        c_void,
618        call,
619        call_mut,
620        call_once,
621        call_once_future,
622        call_ref_future,
623        caller,
624        caller_location,
625        capture_disjoint_fields,
626        carrying_mul_add,
627        catch_unwind,
628        cause,
629        cdylib,
630        ceilf16,
631        ceilf32,
632        ceilf64,
633        ceilf128,
634        cfg,
635        cfg_accessible,
636        cfg_attr,
637        cfg_attr_multi,
638        cfg_attr_trace: "<cfg_attr_trace>", // must not be a valid identifier
639        cfg_boolean_literals,
640        cfg_contract_checks,
641        cfg_doctest,
642        cfg_emscripten_wasm_eh,
643        cfg_eval,
644        cfg_fmt_debug,
645        cfg_overflow_checks,
646        cfg_panic,
647        cfg_relocation_model,
648        cfg_sanitize,
649        cfg_sanitizer_cfi,
650        cfg_select,
651        cfg_target_abi,
652        cfg_target_compact,
653        cfg_target_feature,
654        cfg_target_has_atomic,
655        cfg_target_has_atomic_equal_alignment,
656        cfg_target_has_reliable_f16_f128,
657        cfg_target_thread_local,
658        cfg_target_vendor,
659        cfg_trace: "<cfg_trace>", // must not be a valid identifier
660        cfg_ub_checks,
661        cfg_version,
662        cfi,
663        cfi_encoding,
664        char,
665        char_is_ascii,
666        char_to_digit,
667        child_id,
668        child_kill,
669        client,
670        clippy,
671        clobber_abi,
672        clone,
673        clone_closures,
674        clone_fn,
675        clone_from,
676        closure,
677        closure_lifetime_binder,
678        closure_to_fn_coercion,
679        closure_track_caller,
680        cmp,
681        cmp_max,
682        cmp_min,
683        cmp_ord_max,
684        cmp_ord_min,
685        cmp_partialeq_eq,
686        cmp_partialeq_ne,
687        cmp_partialord_cmp,
688        cmp_partialord_ge,
689        cmp_partialord_gt,
690        cmp_partialord_le,
691        cmp_partialord_lt,
692        cmpxchg16b_target_feature,
693        cmse_nonsecure_entry,
694        coerce_pointee_validated,
695        coerce_shared,
696        coerce_unsized,
697        cold,
698        cold_path,
699        collapse_debuginfo,
700        column,
701        common,
702        compare_bytes,
703        compare_exchange,
704        compare_exchange_weak,
705        compile_error,
706        compiler,
707        compiler_builtins,
708        compiler_copy,
709        compiler_fence,
710        compiler_move,
711        concat,
712        concat_bytes,
713        concat_idents,
714        conservative_impl_trait,
715        console,
716        const_allocate,
717        const_async_blocks,
718        const_closures,
719        const_compare_raw_pointers,
720        const_constructor,
721        const_continue,
722        const_deallocate,
723        const_destruct,
724        const_eval_limit,
725        const_eval_select,
726        const_evaluatable_checked,
727        const_extern_fn,
728        const_fn,
729        const_fn_floating_point_arithmetic,
730        const_fn_fn_ptr_basics,
731        const_fn_trait_bound,
732        const_fn_transmute,
733        const_fn_union,
734        const_fn_unsize,
735        const_for,
736        const_format_args,
737        const_generics,
738        const_generics_defaults,
739        const_if_match,
740        const_impl_trait,
741        const_in_array_repeat_expressions,
742        const_indexing,
743        const_let,
744        const_loop,
745        const_make_global,
746        const_mut_refs,
747        const_panic,
748        const_panic_fmt,
749        const_param_ty,
750        const_precise_live_drops,
751        const_ptr_cast,
752        const_raw_ptr_deref,
753        const_raw_ptr_to_usize_cast,
754        const_refs_to_cell,
755        const_refs_to_static,
756        const_trait_bound_opt_out,
757        const_trait_impl,
758        const_try,
759        const_ty_placeholder: "<const_ty>",
760        constant,
761        constructor,
762        contract_build_check_ensures,
763        contract_check_ensures,
764        contract_check_requires,
765        contract_checks,
766        contracts,
767        contracts_ensures,
768        contracts_internals,
769        contracts_requires,
770        convert,
771        convert_identity,
772        copy,
773        copy_closures,
774        copy_nonoverlapping,
775        copysignf16,
776        copysignf32,
777        copysignf64,
778        copysignf128,
779        core,
780        core_panic,
781        core_panic_2015_macro,
782        core_panic_2021_macro,
783        core_panic_macro,
784        coroutine,
785        coroutine_clone,
786        coroutine_resume,
787        coroutine_return,
788        coroutine_state,
789        coroutine_yield,
790        coroutines,
791        cosf16,
792        cosf32,
793        cosf64,
794        cosf128,
795        count,
796        coverage,
797        coverage_attribute,
798        cr,
799        crate_in_paths,
800        crate_local,
801        crate_name,
802        crate_type,
803        crate_visibility_modifier,
804        crt_dash_static: "crt-static",
805        csky,
806        csky_target_feature,
807        cstr_type,
808        cstring_as_c_str,
809        cstring_type,
810        ctlz,
811        ctlz_nonzero,
812        ctpop,
813        ctr,
814        cttz,
815        cttz_nonzero,
816        custom_attribute,
817        custom_code_classes_in_docs,
818        custom_derive,
819        custom_inner_attributes,
820        custom_mir,
821        custom_test_frameworks,
822        d,
823        d32,
824        dbg_macro,
825        dead_code,
826        dealloc,
827        debug,
828        debug_assert_eq_macro,
829        debug_assert_macro,
830        debug_assert_ne_macro,
831        debug_assertions,
832        debug_struct,
833        debug_struct_fields_finish,
834        debug_tuple,
835        debug_tuple_fields_finish,
836        debugger_visualizer,
837        decl_macro,
838        declare_lint_pass,
839        decode,
840        decorated,
841        default_alloc_error_handler,
842        default_field_values,
843        default_fn,
844        default_lib_allocator,
845        default_method_body_is_const,
846        // --------------------------
847        // Lang items which are used only for experiments with auto traits with default bounds.
848        // These lang items are not actually defined in core/std. Experiment is a part of
849        // `MCP: Low level components for async drop`(https://github.com/rust-lang/compiler-team/issues/727)
850        default_trait1,
851        default_trait2,
852        default_trait3,
853        default_trait4,
854        // --------------------------
855        default_type_parameter_fallback,
856        default_type_params,
857        define_opaque,
858        delayed_bug_from_inside_query,
859        deny,
860        deprecated,
861        deprecated_safe,
862        deprecated_suggestion,
863        deref,
864        deref_method,
865        deref_mut,
866        deref_mut_method,
867        deref_patterns,
868        deref_pure,
869        deref_target,
870        derive,
871        derive_coerce_pointee,
872        derive_const,
873        derive_const_issue: "118304",
874        derive_default_enum,
875        derive_from,
876        derive_smart_pointer,
877        destruct,
878        destructuring_assignment,
879        diagnostic,
880        diagnostic_namespace,
881        diagnostic_on_const,
882        dialect,
883        direct,
884        discriminant_kind,
885        discriminant_type,
886        discriminant_value,
887        disjoint_bitor,
888        dispatch_from_dyn,
889        div,
890        div_assign,
891        diverging_block_default,
892        dl,
893        do_not_recommend,
894        doc,
895        doc_alias,
896        doc_auto_cfg,
897        doc_cfg,
898        doc_cfg_hide,
899        doc_keyword,
900        doc_masked,
901        doc_notable_trait,
902        doc_primitive,
903        doc_spotlight,
904        doctest,
905        dotdot: "..",
906        dotdot_in_tuple_patterns,
907        dotdoteq_in_patterns,
908        dreg,
909        dreg_low8,
910        dreg_low16,
911        drop,
912        drop_in_place,
913        drop_types_in_const,
914        dropck_eyepatch,
915        dropck_parametricity,
916        dummy: "<!dummy!>", // use this instead of `sym::empty` for symbols that won't be used
917        dummy_cgu_name,
918        dylib,
919        dyn_compatible_for_dispatch,
920        dyn_metadata,
921        dyn_star,
922        dyn_trait,
923        dynamic_no_pic: "dynamic-no-pic",
924        e,
925        edition_panic,
926        effective_target_features,
927        effects,
928        eh_catch_typeinfo,
929        eh_personality,
930        emit,
931        emit_enum,
932        emit_enum_variant,
933        emit_enum_variant_arg,
934        emit_struct,
935        emit_struct_field,
936        // Notes about `sym::empty`:
937        // - It should only be used when it genuinely means "empty symbol". Use
938        //   `Option<Symbol>` when "no symbol" is a possibility.
939        // - For dummy symbols that are never used and absolutely must be
940        //   present, it's better to use `sym::dummy` than `sym::empty`, because
941        //   it's clearer that it's intended as a dummy value, and more likely
942        //   to be detected if it accidentally does get used.
943        empty: "",
944        emscripten_wasm_eh,
945        enable,
946        encode,
947        end,
948        entry_nops,
949        enumerate_method,
950        env,
951        env_CFG_RELEASE: env!("CFG_RELEASE"),
952        eprint_macro,
953        eprintln_macro,
954        eq,
955        ergonomic_clones,
956        ermsb_target_feature,
957        exact_div,
958        except,
959        exception_handling: "exception-handling",
960        exchange_malloc,
961        exclusive_range_pattern,
962        exhaustive_integer_patterns,
963        exhaustive_patterns,
964        existential_type,
965        exp2f16,
966        exp2f32,
967        exp2f64,
968        exp2f128,
969        expect,
970        expected,
971        expf16,
972        expf32,
973        expf64,
974        expf128,
975        explicit_extern_abis,
976        explicit_generic_args_with_impl_trait,
977        explicit_tail_calls,
978        export_name,
979        export_stable,
980        expr,
981        expr_2021,
982        expr_fragment_specifier_2024,
983        extended_key_value_attributes,
984        extended_varargs_abi_support,
985        extern_absolute_paths,
986        extern_crate_item_prelude,
987        extern_crate_self,
988        extern_in_paths,
989        extern_prelude,
990        extern_system_varargs,
991        extern_types,
992        extern_weak,
993        external,
994        external_doc,
995        f,
996        f16,
997        f16_consts_mod,
998        f16_epsilon,
999        f16_nan,
1000        f16c_target_feature,
1001        f32,
1002        f32_consts_mod,
1003        f32_epsilon,
1004        f32_legacy_const_digits,
1005        f32_legacy_const_epsilon,
1006        f32_legacy_const_infinity,
1007        f32_legacy_const_mantissa_dig,
1008        f32_legacy_const_max,
1009        f32_legacy_const_max_10_exp,
1010        f32_legacy_const_max_exp,
1011        f32_legacy_const_min,
1012        f32_legacy_const_min_10_exp,
1013        f32_legacy_const_min_exp,
1014        f32_legacy_const_min_positive,
1015        f32_legacy_const_nan,
1016        f32_legacy_const_neg_infinity,
1017        f32_legacy_const_radix,
1018        f32_nan,
1019        f64,
1020        f64_consts_mod,
1021        f64_epsilon,
1022        f64_legacy_const_digits,
1023        f64_legacy_const_epsilon,
1024        f64_legacy_const_infinity,
1025        f64_legacy_const_mantissa_dig,
1026        f64_legacy_const_max,
1027        f64_legacy_const_max_10_exp,
1028        f64_legacy_const_max_exp,
1029        f64_legacy_const_min,
1030        f64_legacy_const_min_10_exp,
1031        f64_legacy_const_min_exp,
1032        f64_legacy_const_min_positive,
1033        f64_legacy_const_nan,
1034        f64_legacy_const_neg_infinity,
1035        f64_legacy_const_radix,
1036        f64_nan,
1037        f128,
1038        f128_consts_mod,
1039        f128_epsilon,
1040        f128_nan,
1041        fabsf16,
1042        fabsf32,
1043        fabsf64,
1044        fabsf128,
1045        fadd_algebraic,
1046        fadd_fast,
1047        fake_variadic,
1048        fallback,
1049        fdiv_algebraic,
1050        fdiv_fast,
1051        feature,
1052        fence,
1053        ferris: "🦀",
1054        fetch_update,
1055        ffi,
1056        ffi_const,
1057        ffi_pure,
1058        ffi_returns_twice,
1059        field,
1060        field_init_shorthand,
1061        file,
1062        file_options,
1063        flags,
1064        float,
1065        float_to_int_unchecked,
1066        floorf16,
1067        floorf32,
1068        floorf64,
1069        floorf128,
1070        fmaf16,
1071        fmaf32,
1072        fmaf64,
1073        fmaf128,
1074        fmt,
1075        fmt_debug,
1076        fmul_algebraic,
1077        fmul_fast,
1078        fmuladdf16,
1079        fmuladdf32,
1080        fmuladdf64,
1081        fmuladdf128,
1082        fn_align,
1083        fn_body,
1084        fn_delegation,
1085        fn_must_use,
1086        fn_mut,
1087        fn_once,
1088        fn_once_output,
1089        fn_ptr_addr,
1090        fn_ptr_trait,
1091        forbid,
1092        force_target_feature,
1093        forget,
1094        format,
1095        format_args,
1096        format_args_capture,
1097        format_args_macro,
1098        format_args_nl,
1099        format_argument,
1100        format_arguments,
1101        format_macro,
1102        framework,
1103        freeze,
1104        freeze_impls,
1105        freg,
1106        frem_algebraic,
1107        frem_fast,
1108        from,
1109        from_desugaring,
1110        from_fn,
1111        from_iter,
1112        from_iter_fn,
1113        from_output,
1114        from_residual,
1115        from_size_align_unchecked,
1116        from_str,
1117        from_str_method,
1118        from_str_nonconst,
1119        from_u16,
1120        from_usize,
1121        from_yeet,
1122        frontmatter,
1123        fs_create_dir,
1124        fsub_algebraic,
1125        fsub_fast,
1126        full,
1127        fundamental,
1128        fused_iterator,
1129        future,
1130        future_drop_poll,
1131        future_output,
1132        future_trait,
1133        fxsr,
1134        gdb_script_file,
1135        ge,
1136        gen_blocks,
1137        gen_future,
1138        generator_clone,
1139        generators,
1140        generic_arg_infer,
1141        generic_assert,
1142        generic_associated_types,
1143        generic_associated_types_extended,
1144        generic_const_exprs,
1145        generic_const_items,
1146        generic_const_parameter_types,
1147        generic_param_attrs,
1148        generic_pattern_types,
1149        get_context,
1150        global_alloc_ty,
1151        global_allocator,
1152        global_asm,
1153        global_registration,
1154        globs,
1155        gt,
1156        guard_patterns,
1157        half_open_range_patterns,
1158        half_open_range_patterns_in_slices,
1159        hash,
1160        hashmap_contains_key,
1161        hashmap_drain_ty,
1162        hashmap_insert,
1163        hashmap_iter_mut_ty,
1164        hashmap_iter_ty,
1165        hashmap_keys_ty,
1166        hashmap_values_mut_ty,
1167        hashmap_values_ty,
1168        hashset_drain_ty,
1169        hashset_iter,
1170        hashset_iter_ty,
1171        hexagon,
1172        hexagon_target_feature,
1173        hidden,
1174        hide,
1175        hint,
1176        homogeneous_aggregate,
1177        host,
1178        html_favicon_url,
1179        html_logo_url,
1180        html_no_source,
1181        html_playground_url,
1182        html_root_url,
1183        hwaddress,
1184        i,
1185        i8,
1186        i8_legacy_const_max,
1187        i8_legacy_const_min,
1188        i8_legacy_fn_max_value,
1189        i8_legacy_fn_min_value,
1190        i8_legacy_mod,
1191        i16,
1192        i16_legacy_const_max,
1193        i16_legacy_const_min,
1194        i16_legacy_fn_max_value,
1195        i16_legacy_fn_min_value,
1196        i16_legacy_mod,
1197        i32,
1198        i32_legacy_const_max,
1199        i32_legacy_const_min,
1200        i32_legacy_fn_max_value,
1201        i32_legacy_fn_min_value,
1202        i32_legacy_mod,
1203        i64,
1204        i64_legacy_const_max,
1205        i64_legacy_const_min,
1206        i64_legacy_fn_max_value,
1207        i64_legacy_fn_min_value,
1208        i64_legacy_mod,
1209        i128,
1210        i128_legacy_const_max,
1211        i128_legacy_const_min,
1212        i128_legacy_fn_max_value,
1213        i128_legacy_fn_min_value,
1214        i128_legacy_mod,
1215        i128_type,
1216        ident,
1217        if_let,
1218        if_let_guard,
1219        if_let_rescope,
1220        if_while_or_patterns,
1221        ignore,
1222        immediate_abort: "immediate-abort",
1223        impl_header_lifetime_elision,
1224        impl_lint_pass,
1225        impl_trait_in_assoc_type,
1226        impl_trait_in_bindings,
1227        impl_trait_in_fn_trait_return,
1228        impl_trait_projections,
1229        implement_via_object,
1230        implied_by,
1231        import,
1232        import_name_type,
1233        import_shadowing,
1234        import_trait_associated_functions,
1235        imported_main,
1236        in_band_lifetimes,
1237        include,
1238        include_bytes,
1239        include_bytes_macro,
1240        include_str,
1241        include_str_macro,
1242        inclusive_range_syntax,
1243        index,
1244        index_mut,
1245        infer_outlives_requirements,
1246        infer_static_outlives_requirements,
1247        inherent_associated_types,
1248        inherit,
1249        initial,
1250        inlateout,
1251        inline,
1252        inline_const,
1253        inline_const_pat,
1254        inout,
1255        instant_now,
1256        instruction_set,
1257        integer_: "integer", // underscore to avoid clashing with the function `sym::integer` below
1258        integral,
1259        internal,
1260        internal_features,
1261        into_async_iter_into_iter,
1262        into_future,
1263        into_iter,
1264        into_try_type,
1265        intra_doc_pointers,
1266        intrinsics,
1267        intrinsics_unaligned_volatile_load,
1268        intrinsics_unaligned_volatile_store,
1269        io_error_new,
1270        io_errorkind,
1271        io_stderr,
1272        io_stdout,
1273        irrefutable_let_patterns,
1274        is,
1275        is_val_statically_known,
1276        isa_attribute,
1277        isize,
1278        isize_legacy_const_max,
1279        isize_legacy_const_min,
1280        isize_legacy_fn_max_value,
1281        isize_legacy_fn_min_value,
1282        isize_legacy_mod,
1283        issue,
1284        issue_5723_bootstrap,
1285        issue_tracker_base_url,
1286        item,
1287        item_like_imports,
1288        iter,
1289        iter_cloned,
1290        iter_copied,
1291        iter_filter,
1292        iter_mut,
1293        iter_repeat,
1294        iterator,
1295        iterator_collect_fn,
1296        kcfi,
1297        kernel_address,
1298        keylocker_x86,
1299        keyword,
1300        kind,
1301        kreg,
1302        kreg0,
1303        label,
1304        label_break_value,
1305        lahfsahf_target_feature,
1306        lang,
1307        lang_items,
1308        large_assignments,
1309        last,
1310        lateout,
1311        lazy_normalization_consts,
1312        lazy_type_alias,
1313        le,
1314        legacy_receiver,
1315        len,
1316        let_chains,
1317        let_else,
1318        lhs,
1319        lib,
1320        libc,
1321        lifetime,
1322        lifetime_capture_rules_2024,
1323        lifetimes,
1324        likely,
1325        line,
1326        link,
1327        link_arg_attribute,
1328        link_args,
1329        link_cfg,
1330        link_dash_arg: "link-arg",
1331        link_llvm_intrinsics,
1332        link_name,
1333        link_ordinal,
1334        link_section,
1335        linkage,
1336        linker,
1337        linker_messages,
1338        linkonce,
1339        linkonce_odr,
1340        lint_reasons,
1341        literal,
1342        load,
1343        loaded_from_disk,
1344        local,
1345        local_inner_macros,
1346        log2f16,
1347        log2f32,
1348        log2f64,
1349        log2f128,
1350        log10f16,
1351        log10f32,
1352        log10f64,
1353        log10f128,
1354        log_syntax,
1355        logf16,
1356        logf32,
1357        logf64,
1358        logf128,
1359        loongarch32,
1360        loongarch64,
1361        loongarch_target_feature,
1362        loop_break_value,
1363        loop_match,
1364        lr,
1365        lt,
1366        m68k,
1367        m68k_target_feature,
1368        macro_at_most_once_rep,
1369        macro_attr,
1370        macro_attributes_in_derive_output,
1371        macro_concat,
1372        macro_derive,
1373        macro_escape,
1374        macro_export,
1375        macro_lifetime_matcher,
1376        macro_literal_matcher,
1377        macro_metavar_expr,
1378        macro_metavar_expr_concat,
1379        macro_reexport,
1380        macro_use,
1381        macro_vis_matcher,
1382        macros_in_extern,
1383        main,
1384        managed_boxes,
1385        manually_drop,
1386        map,
1387        map_err,
1388        marker,
1389        marker_trait_attr,
1390        masked,
1391        match_beginning_vert,
1392        match_default_bindings,
1393        matches_macro,
1394        maximumf16,
1395        maximumf32,
1396        maximumf64,
1397        maximumf128,
1398        maxnumf16,
1399        maxnumf32,
1400        maxnumf64,
1401        maxnumf128,
1402        may_dangle,
1403        may_unwind,
1404        maybe_uninit,
1405        maybe_uninit_uninit,
1406        maybe_uninit_zeroed,
1407        mem_align_const,
1408        mem_align_of,
1409        mem_discriminant,
1410        mem_drop,
1411        mem_forget,
1412        mem_replace,
1413        mem_size_const,
1414        mem_size_of,
1415        mem_size_of_val,
1416        mem_swap,
1417        mem_uninitialized,
1418        mem_variant_count,
1419        mem_zeroed,
1420        member_constraints,
1421        memory,
1422        memtag,
1423        message,
1424        meta,
1425        meta_sized,
1426        metadata_type,
1427        min_const_fn,
1428        min_const_generics,
1429        min_const_unsafe_fn,
1430        min_exhaustive_patterns,
1431        min_generic_const_args,
1432        min_specialization,
1433        min_type_alias_impl_trait,
1434        minimumf16,
1435        minimumf32,
1436        minimumf64,
1437        minimumf128,
1438        minnumf16,
1439        minnumf32,
1440        minnumf64,
1441        minnumf128,
1442        mips,
1443        mips32r6,
1444        mips64,
1445        mips64r6,
1446        mips_target_feature,
1447        mir_assume,
1448        mir_basic_block,
1449        mir_call,
1450        mir_cast_ptr_to_ptr,
1451        mir_cast_transmute,
1452        mir_cast_unsize,
1453        mir_checked,
1454        mir_debuginfo,
1455        mir_deinit,
1456        mir_discriminant,
1457        mir_drop,
1458        mir_field,
1459        mir_goto,
1460        mir_len,
1461        mir_make_place,
1462        mir_move,
1463        mir_offset,
1464        mir_ptr_metadata,
1465        mir_retag,
1466        mir_return,
1467        mir_return_to,
1468        mir_set_discriminant,
1469        mir_static,
1470        mir_static_mut,
1471        mir_storage_dead,
1472        mir_storage_live,
1473        mir_tail_call,
1474        mir_unreachable,
1475        mir_unwind_cleanup,
1476        mir_unwind_continue,
1477        mir_unwind_resume,
1478        mir_unwind_terminate,
1479        mir_unwind_terminate_reason,
1480        mir_unwind_unreachable,
1481        mir_variant,
1482        miri,
1483        mmx_reg,
1484        modifiers,
1485        module,
1486        module_path,
1487        more_maybe_bounds,
1488        more_qualified_paths,
1489        more_struct_aliases,
1490        movbe_target_feature,
1491        move_ref_pattern,
1492        move_size_limit,
1493        movrs_target_feature,
1494        msp430,
1495        mul,
1496        mul_assign,
1497        mul_with_overflow,
1498        multiple_supertrait_upcastable,
1499        must_not_suspend,
1500        must_use,
1501        mut_preserve_binding_mode_2024,
1502        mut_ref,
1503        naked,
1504        naked_asm,
1505        naked_functions,
1506        naked_functions_rustic_abi,
1507        naked_functions_target_feature,
1508        name,
1509        names,
1510        native_link_modifiers,
1511        native_link_modifiers_as_needed,
1512        native_link_modifiers_bundle,
1513        native_link_modifiers_verbatim,
1514        native_link_modifiers_whole_archive,
1515        natvis_file,
1516        ne,
1517        needs_allocator,
1518        needs_drop,
1519        needs_panic_runtime,
1520        neg,
1521        negate_unsigned,
1522        negative_bounds,
1523        negative_impls,
1524        neon,
1525        nested,
1526        never,
1527        never_patterns,
1528        never_type,
1529        never_type_fallback,
1530        new,
1531        new_binary,
1532        new_const,
1533        new_debug,
1534        new_debug_noop,
1535        new_display,
1536        new_lower_exp,
1537        new_lower_hex,
1538        new_octal,
1539        new_pointer,
1540        new_range,
1541        new_unchecked,
1542        new_upper_exp,
1543        new_upper_hex,
1544        new_v1,
1545        new_v1_formatted,
1546        next,
1547        niko,
1548        nll,
1549        no,
1550        no_builtins,
1551        no_core,
1552        no_coverage,
1553        no_crate_inject,
1554        no_debug,
1555        no_default_passes,
1556        no_implicit_prelude,
1557        no_inline,
1558        no_link,
1559        no_main,
1560        no_mangle,
1561        no_sanitize,
1562        no_stack_check,
1563        no_std,
1564        nomem,
1565        non_ascii_idents,
1566        non_exhaustive,
1567        non_exhaustive_omitted_patterns_lint,
1568        non_lifetime_binders,
1569        non_modrs_mods,
1570        nonblocking,
1571        none,
1572        nontemporal_store,
1573        noop_method_borrow,
1574        noop_method_clone,
1575        noop_method_deref,
1576        noprefix,
1577        noreturn,
1578        nostack,
1579        not,
1580        notable_trait,
1581        note,
1582        null,
1583        nvptx64,
1584        nvptx_target_feature,
1585        object_safe_for_dispatch,
1586        of,
1587        off,
1588        offload,
1589        offset,
1590        offset_of,
1591        offset_of_enum,
1592        offset_of_nested,
1593        offset_of_slice,
1594        ok_or_else,
1595        old_name,
1596        omit_gdb_pretty_printer_section,
1597        on,
1598        on_const,
1599        on_unimplemented,
1600        opaque,
1601        opaque_module_name_placeholder: "<opaque>",
1602        open_options_new,
1603        ops,
1604        opt_out_copy,
1605        optimize,
1606        optimize_attribute,
1607        optimized,
1608        optin_builtin_traits,
1609        option,
1610        option_env,
1611        option_expect,
1612        option_unwrap,
1613        options,
1614        or,
1615        or_patterns,
1616        ord_cmp_method,
1617        os_str_to_os_string,
1618        os_string_as_os_str,
1619        other,
1620        out,
1621        overflow_checks,
1622        overlapping_marker_traits,
1623        owned_box,
1624        packed,
1625        packed_bundled_libs,
1626        panic,
1627        panic_2015,
1628        panic_2021,
1629        panic_abort,
1630        panic_any,
1631        panic_bounds_check,
1632        panic_cannot_unwind,
1633        panic_const_add_overflow,
1634        panic_const_async_fn_resumed,
1635        panic_const_async_fn_resumed_drop,
1636        panic_const_async_fn_resumed_panic,
1637        panic_const_async_gen_fn_resumed,
1638        panic_const_async_gen_fn_resumed_drop,
1639        panic_const_async_gen_fn_resumed_panic,
1640        panic_const_coroutine_resumed,
1641        panic_const_coroutine_resumed_drop,
1642        panic_const_coroutine_resumed_panic,
1643        panic_const_div_by_zero,
1644        panic_const_div_overflow,
1645        panic_const_gen_fn_none,
1646        panic_const_gen_fn_none_drop,
1647        panic_const_gen_fn_none_panic,
1648        panic_const_mul_overflow,
1649        panic_const_neg_overflow,
1650        panic_const_rem_by_zero,
1651        panic_const_rem_overflow,
1652        panic_const_shl_overflow,
1653        panic_const_shr_overflow,
1654        panic_const_sub_overflow,
1655        panic_display,
1656        panic_fmt,
1657        panic_handler,
1658        panic_impl,
1659        panic_implementation,
1660        panic_in_cleanup,
1661        panic_info,
1662        panic_invalid_enum_construction,
1663        panic_location,
1664        panic_misaligned_pointer_dereference,
1665        panic_nounwind,
1666        panic_null_pointer_dereference,
1667        panic_runtime,
1668        panic_str_2015,
1669        panic_unwind,
1670        panicking,
1671        param_attrs,
1672        parent_label,
1673        partial_cmp,
1674        partial_ord,
1675        passes,
1676        pat,
1677        pat_param,
1678        patchable_function_entry,
1679        path,
1680        path_main_separator,
1681        path_to_pathbuf,
1682        pathbuf_as_path,
1683        pattern_complexity_limit,
1684        pattern_parentheses,
1685        pattern_type,
1686        pattern_type_range_trait,
1687        pattern_types,
1688        permissions_from_mode,
1689        phantom_data,
1690        phase,
1691        pic,
1692        pie,
1693        pin,
1694        pin_ergonomics,
1695        pin_macro,
1696        pin_v2,
1697        platform_intrinsics,
1698        plugin,
1699        plugin_registrar,
1700        plugins,
1701        pointee,
1702        pointee_sized,
1703        pointee_trait,
1704        pointer,
1705        poll,
1706        poll_next,
1707        position,
1708        post_cleanup: "post-cleanup",
1709        post_dash_lto: "post-lto",
1710        postfix_match,
1711        powerpc,
1712        powerpc64,
1713        powerpc64le,
1714        powerpc_target_feature,
1715        powf16,
1716        powf32,
1717        powf64,
1718        powf128,
1719        powif16,
1720        powif32,
1721        powif64,
1722        powif128,
1723        pre_dash_lto: "pre-lto",
1724        precise_capturing,
1725        precise_capturing_in_traits,
1726        precise_pointer_size_matching,
1727        precision,
1728        pref_align_of,
1729        prefetch_read_data,
1730        prefetch_read_instruction,
1731        prefetch_write_data,
1732        prefetch_write_instruction,
1733        prefix_nops,
1734        preg,
1735        prelude,
1736        prelude_import,
1737        preserves_flags,
1738        prfchw_target_feature,
1739        print_macro,
1740        println_macro,
1741        proc_dash_macro: "proc-macro",
1742        proc_macro,
1743        proc_macro_attribute,
1744        proc_macro_derive,
1745        proc_macro_expr,
1746        proc_macro_gen,
1747        proc_macro_hygiene,
1748        proc_macro_internals,
1749        proc_macro_mod,
1750        proc_macro_non_items,
1751        proc_macro_path_invoc,
1752        process_abort,
1753        process_exit,
1754        profiler_builtins,
1755        profiler_runtime,
1756        ptr,
1757        ptr_cast,
1758        ptr_cast_const,
1759        ptr_cast_mut,
1760        ptr_const_is_null,
1761        ptr_copy,
1762        ptr_copy_nonoverlapping,
1763        ptr_eq,
1764        ptr_from_ref,
1765        ptr_guaranteed_cmp,
1766        ptr_is_null,
1767        ptr_mask,
1768        ptr_metadata,
1769        ptr_null,
1770        ptr_null_mut,
1771        ptr_offset_from,
1772        ptr_offset_from_unsigned,
1773        ptr_read,
1774        ptr_read_unaligned,
1775        ptr_read_volatile,
1776        ptr_replace,
1777        ptr_slice_from_raw_parts,
1778        ptr_slice_from_raw_parts_mut,
1779        ptr_swap,
1780        ptr_swap_nonoverlapping,
1781        ptr_write,
1782        ptr_write_bytes,
1783        ptr_write_unaligned,
1784        ptr_write_volatile,
1785        pub_macro_rules,
1786        pub_restricted,
1787        public,
1788        pure,
1789        pushpop_unsafe,
1790        qreg,
1791        qreg_low4,
1792        qreg_low8,
1793        quad_precision_float,
1794        question_mark,
1795        quote,
1796        range_inclusive_new,
1797        range_step,
1798        raw_dash_dylib: "raw-dylib",
1799        raw_dylib,
1800        raw_dylib_elf,
1801        raw_eq,
1802        raw_identifiers,
1803        raw_ref_op,
1804        re_rebalance_coherence,
1805        read_enum,
1806        read_enum_variant,
1807        read_enum_variant_arg,
1808        read_struct,
1809        read_struct_field,
1810        read_via_copy,
1811        readonly,
1812        realloc,
1813        realtime,
1814        reason,
1815        reborrow,
1816        receiver,
1817        receiver_target,
1818        recursion_limit,
1819        reexport_test_harness_main,
1820        ref_pat_eat_one_layer_2024,
1821        ref_pat_eat_one_layer_2024_structural,
1822        ref_pat_everywhere,
1823        ref_unwind_safe_trait,
1824        reference,
1825        reflect,
1826        reg,
1827        reg16,
1828        reg32,
1829        reg64,
1830        reg_abcd,
1831        reg_addr,
1832        reg_byte,
1833        reg_data,
1834        reg_iw,
1835        reg_nonzero,
1836        reg_pair,
1837        reg_ptr,
1838        reg_upper,
1839        register_attr,
1840        register_tool,
1841        relaxed_adts,
1842        relaxed_struct_unsize,
1843        relocation_model,
1844        rem,
1845        rem_assign,
1846        repr,
1847        repr128,
1848        repr_align,
1849        repr_align_enum,
1850        repr_packed,
1851        repr_simd,
1852        repr_transparent,
1853        require,
1854        reserve_x18: "reserve-x18",
1855        residual,
1856        result,
1857        result_ffi_guarantees,
1858        result_ok_method,
1859        resume,
1860        return_position_impl_trait_in_trait,
1861        return_type_notation,
1862        riscv32,
1863        riscv64,
1864        riscv_target_feature,
1865        rlib,
1866        ropi,
1867        ropi_rwpi: "ropi-rwpi",
1868        rotate_left,
1869        rotate_right,
1870        round_ties_even_f16,
1871        round_ties_even_f32,
1872        round_ties_even_f64,
1873        round_ties_even_f128,
1874        roundf16,
1875        roundf32,
1876        roundf64,
1877        roundf128,
1878        rt,
1879        rtm_target_feature,
1880        runtime,
1881        rust,
1882        rust_2015,
1883        rust_2018,
1884        rust_2018_preview,
1885        rust_2021,
1886        rust_2024,
1887        rust_analyzer,
1888        rust_begin_unwind,
1889        rust_cold_cc,
1890        rust_eh_catch_typeinfo,
1891        rust_eh_personality,
1892        rust_future,
1893        rust_logo,
1894        rust_out,
1895        rustc,
1896        rustc_abi,
1897        // FIXME(#82232, #143834): temporary name to mitigate `#[align]` nameres ambiguity
1898        rustc_align,
1899        rustc_align_static,
1900        rustc_allocator,
1901        rustc_allocator_zeroed,
1902        rustc_allocator_zeroed_variant,
1903        rustc_allow_const_fn_unstable,
1904        rustc_allow_incoherent_impl,
1905        rustc_allowed_through_unstable_modules,
1906        rustc_as_ptr,
1907        rustc_attrs,
1908        rustc_autodiff,
1909        rustc_builtin_macro,
1910        rustc_capture_analysis,
1911        rustc_clean,
1912        rustc_coherence_is_core,
1913        rustc_coinductive,
1914        rustc_confusables,
1915        rustc_const_stable,
1916        rustc_const_stable_indirect,
1917        rustc_const_unstable,
1918        rustc_conversion_suggestion,
1919        rustc_deallocator,
1920        rustc_def_path,
1921        rustc_default_body_unstable,
1922        rustc_delayed_bug_from_inside_query,
1923        rustc_deny_explicit_impl,
1924        rustc_deprecated_safe_2024,
1925        rustc_diagnostic_item,
1926        rustc_diagnostic_macros,
1927        rustc_dirty,
1928        rustc_do_not_const_check,
1929        rustc_do_not_implement_via_object,
1930        rustc_doc_primitive,
1931        rustc_driver,
1932        rustc_dummy,
1933        rustc_dump_def_parents,
1934        rustc_dump_item_bounds,
1935        rustc_dump_predicates,
1936        rustc_dump_user_args,
1937        rustc_dump_vtable,
1938        rustc_effective_visibility,
1939        rustc_evaluate_where_clauses,
1940        rustc_expected_cgu_reuse,
1941        rustc_force_inline,
1942        rustc_has_incoherent_inherent_impls,
1943        rustc_hidden_type_of_opaques,
1944        rustc_if_this_changed,
1945        rustc_inherit_overflow_checks,
1946        rustc_insignificant_dtor,
1947        rustc_intrinsic,
1948        rustc_intrinsic_const_stable_indirect,
1949        rustc_layout,
1950        rustc_layout_scalar_valid_range_end,
1951        rustc_layout_scalar_valid_range_start,
1952        rustc_legacy_const_generics,
1953        rustc_lint_diagnostics,
1954        rustc_lint_opt_deny_field_access,
1955        rustc_lint_opt_ty,
1956        rustc_lint_query_instability,
1957        rustc_lint_untracked_query_information,
1958        rustc_macro_transparency,
1959        rustc_main,
1960        rustc_mir,
1961        rustc_must_implement_one_of,
1962        rustc_never_returns_null_ptr,
1963        rustc_never_type_options,
1964        rustc_no_implicit_autorefs,
1965        rustc_no_implicit_bounds,
1966        rustc_no_mir_inline,
1967        rustc_nonnull_optimization_guaranteed,
1968        rustc_nounwind,
1969        rustc_objc_class,
1970        rustc_objc_selector,
1971        rustc_object_lifetime_default,
1972        rustc_offload_kernel,
1973        rustc_on_unimplemented,
1974        rustc_outlives,
1975        rustc_paren_sugar,
1976        rustc_partition_codegened,
1977        rustc_partition_reused,
1978        rustc_pass_by_value,
1979        rustc_pass_indirectly_in_non_rustic_abis,
1980        rustc_peek,
1981        rustc_peek_liveness,
1982        rustc_peek_maybe_init,
1983        rustc_peek_maybe_uninit,
1984        rustc_preserve_ub_checks,
1985        rustc_private,
1986        rustc_proc_macro_decls,
1987        rustc_promotable,
1988        rustc_pub_transparent,
1989        rustc_reallocator,
1990        rustc_regions,
1991        rustc_reservation_impl,
1992        rustc_serialize,
1993        rustc_should_not_be_called_on_const_items,
1994        rustc_simd_monomorphize_lane_limit,
1995        rustc_skip_during_method_dispatch,
1996        rustc_specialization_trait,
1997        rustc_std_internal_symbol,
1998        rustc_strict_coherence,
1999        rustc_symbol_name,
2000        rustc_test_marker,
2001        rustc_then_this_would_need,
2002        rustc_trivial_field_reads,
2003        rustc_unsafe_specialization_marker,
2004        rustc_variance,
2005        rustc_variance_of_opaques,
2006        rustdoc,
2007        rustdoc_internals,
2008        rustdoc_missing_doc_code_examples,
2009        rustfmt,
2010        rvalue_static_promotion,
2011        rwpi,
2012        s,
2013        s390x,
2014        s390x_target_feature,
2015        s390x_target_feature_vector,
2016        safety,
2017        sanitize,
2018        sanitizer_cfi_generalize_pointers,
2019        sanitizer_cfi_normalize_integers,
2020        sanitizer_runtime,
2021        saturating_add,
2022        saturating_div,
2023        saturating_sub,
2024        sdylib,
2025        search_unbox,
2026        select_unpredictable,
2027        self_in_typedefs,
2028        self_struct_ctor,
2029        semiopaque,
2030        semitransparent,
2031        sha2,
2032        sha3,
2033        sha512_sm_x86,
2034        shadow_call_stack,
2035        shallow,
2036        shl,
2037        shl_assign,
2038        shorter_tail_lifetimes,
2039        should_panic,
2040        show,
2041        shr,
2042        shr_assign,
2043        sig_dfl,
2044        sig_ign,
2045        simd,
2046        simd_add,
2047        simd_and,
2048        simd_arith_offset,
2049        simd_as,
2050        simd_bitmask,
2051        simd_bitreverse,
2052        simd_bswap,
2053        simd_cast,
2054        simd_cast_ptr,
2055        simd_ceil,
2056        simd_ctlz,
2057        simd_ctpop,
2058        simd_cttz,
2059        simd_div,
2060        simd_eq,
2061        simd_expose_provenance,
2062        simd_extract,
2063        simd_extract_dyn,
2064        simd_fabs,
2065        simd_fcos,
2066        simd_fexp,
2067        simd_fexp2,
2068        simd_ffi,
2069        simd_flog,
2070        simd_flog2,
2071        simd_flog10,
2072        simd_floor,
2073        simd_fma,
2074        simd_fmax,
2075        simd_fmin,
2076        simd_fsin,
2077        simd_fsqrt,
2078        simd_funnel_shl,
2079        simd_funnel_shr,
2080        simd_gather,
2081        simd_ge,
2082        simd_gt,
2083        simd_insert,
2084        simd_insert_dyn,
2085        simd_le,
2086        simd_lt,
2087        simd_masked_load,
2088        simd_masked_store,
2089        simd_mul,
2090        simd_ne,
2091        simd_neg,
2092        simd_or,
2093        simd_reduce_add_ordered,
2094        simd_reduce_add_unordered,
2095        simd_reduce_all,
2096        simd_reduce_and,
2097        simd_reduce_any,
2098        simd_reduce_max,
2099        simd_reduce_min,
2100        simd_reduce_mul_ordered,
2101        simd_reduce_mul_unordered,
2102        simd_reduce_or,
2103        simd_reduce_xor,
2104        simd_relaxed_fma,
2105        simd_rem,
2106        simd_round,
2107        simd_round_ties_even,
2108        simd_saturating_add,
2109        simd_saturating_sub,
2110        simd_scatter,
2111        simd_select,
2112        simd_select_bitmask,
2113        simd_shl,
2114        simd_shr,
2115        simd_shuffle,
2116        simd_shuffle_const_generic,
2117        simd_sub,
2118        simd_trunc,
2119        simd_with_exposed_provenance,
2120        simd_xor,
2121        since,
2122        sinf16,
2123        sinf32,
2124        sinf64,
2125        sinf128,
2126        size,
2127        size_of,
2128        size_of_val,
2129        sized,
2130        sized_hierarchy,
2131        skip,
2132        slice,
2133        slice_from_raw_parts,
2134        slice_from_raw_parts_mut,
2135        slice_from_ref,
2136        slice_get_unchecked,
2137        slice_into_vec,
2138        slice_iter,
2139        slice_len_fn,
2140        slice_patterns,
2141        slicing_syntax,
2142        soft,
2143        sparc,
2144        sparc64,
2145        sparc_target_feature,
2146        specialization,
2147        speed,
2148        spirv,
2149        spotlight,
2150        sqrtf16,
2151        sqrtf32,
2152        sqrtf64,
2153        sqrtf128,
2154        sreg,
2155        sreg_low16,
2156        sse,
2157        sse2,
2158        sse4a_target_feature,
2159        stable,
2160        staged_api,
2161        start,
2162        state,
2163        static_align,
2164        static_in_const,
2165        static_nobundle,
2166        static_recursion,
2167        staticlib,
2168        std,
2169        std_lib_injection,
2170        std_panic,
2171        std_panic_2015_macro,
2172        std_panic_macro,
2173        stmt,
2174        stmt_expr_attributes,
2175        stop_after_dataflow,
2176        store,
2177        str,
2178        str_chars,
2179        str_ends_with,
2180        str_from_utf8,
2181        str_from_utf8_mut,
2182        str_from_utf8_unchecked,
2183        str_from_utf8_unchecked_mut,
2184        str_inherent_from_utf8,
2185        str_inherent_from_utf8_mut,
2186        str_inherent_from_utf8_unchecked,
2187        str_inherent_from_utf8_unchecked_mut,
2188        str_len,
2189        str_split_whitespace,
2190        str_starts_with,
2191        str_trim,
2192        str_trim_end,
2193        str_trim_start,
2194        strict_provenance_lints,
2195        string_as_mut_str,
2196        string_as_str,
2197        string_deref_patterns,
2198        string_from_utf8,
2199        string_insert_str,
2200        string_new,
2201        string_push_str,
2202        stringify,
2203        struct_field_attributes,
2204        struct_inherit,
2205        struct_variant,
2206        structural_match,
2207        structural_peq,
2208        sub,
2209        sub_assign,
2210        sub_with_overflow,
2211        suggestion,
2212        super_let,
2213        supertrait_item_shadowing,
2214        sym,
2215        sync,
2216        synthetic,
2217        sys_mutex_lock,
2218        sys_mutex_try_lock,
2219        sys_mutex_unlock,
2220        t32,
2221        target,
2222        target_abi,
2223        target_arch,
2224        target_endian,
2225        target_env,
2226        target_family,
2227        target_feature,
2228        target_feature_11,
2229        target_feature_inline_always,
2230        target_has_atomic,
2231        target_has_atomic_equal_alignment,
2232        target_has_atomic_load_store,
2233        target_has_reliable_f16,
2234        target_has_reliable_f16_math,
2235        target_has_reliable_f128,
2236        target_has_reliable_f128_math,
2237        target_os,
2238        target_pointer_width,
2239        target_thread_local,
2240        target_vendor,
2241        tbm_target_feature,
2242        termination,
2243        termination_trait,
2244        termination_trait_test,
2245        test,
2246        test_2018_feature,
2247        test_accepted_feature,
2248        test_case,
2249        test_removed_feature,
2250        test_runner,
2251        test_unstable_lint,
2252        thread,
2253        thread_local,
2254        thread_local_macro,
2255        three_way_compare,
2256        thumb2,
2257        thumb_mode: "thumb-mode",
2258        tmm_reg,
2259        to_owned_method,
2260        to_string,
2261        to_string_method,
2262        to_vec,
2263        todo_macro,
2264        tool_attributes,
2265        tool_lints,
2266        trace_macros,
2267        track_caller,
2268        trait_alias,
2269        trait_upcasting,
2270        transmute,
2271        transmute_generic_consts,
2272        transmute_opts,
2273        transmute_trait,
2274        transmute_unchecked,
2275        transparent,
2276        transparent_enums,
2277        transparent_unions,
2278        trivial_bounds,
2279        trivial_clone,
2280        truncf16,
2281        truncf32,
2282        truncf64,
2283        truncf128,
2284        try_blocks,
2285        try_capture,
2286        try_from,
2287        try_from_fn,
2288        try_into,
2289        try_trait_v2,
2290        try_trait_v2_residual,
2291        try_update,
2292        tt,
2293        tuple,
2294        tuple_indexing,
2295        tuple_trait,
2296        two_phase,
2297        ty,
2298        type_alias_enum_variants,
2299        type_alias_impl_trait,
2300        type_ascribe,
2301        type_ascription,
2302        type_changing_struct_update,
2303        type_const,
2304        type_id,
2305        type_id_eq,
2306        type_ir,
2307        type_ir_infer_ctxt_like,
2308        type_ir_inherent,
2309        type_ir_interner,
2310        type_length_limit,
2311        type_macros,
2312        type_name,
2313        type_privacy_lints,
2314        typed_swap_nonoverlapping,
2315        u8,
2316        u8_legacy_const_max,
2317        u8_legacy_const_min,
2318        u8_legacy_fn_max_value,
2319        u8_legacy_fn_min_value,
2320        u8_legacy_mod,
2321        u16,
2322        u16_legacy_const_max,
2323        u16_legacy_const_min,
2324        u16_legacy_fn_max_value,
2325        u16_legacy_fn_min_value,
2326        u16_legacy_mod,
2327        u32,
2328        u32_legacy_const_max,
2329        u32_legacy_const_min,
2330        u32_legacy_fn_max_value,
2331        u32_legacy_fn_min_value,
2332        u32_legacy_mod,
2333        u64,
2334        u64_legacy_const_max,
2335        u64_legacy_const_min,
2336        u64_legacy_fn_max_value,
2337        u64_legacy_fn_min_value,
2338        u64_legacy_mod,
2339        u128,
2340        u128_legacy_const_max,
2341        u128_legacy_const_min,
2342        u128_legacy_fn_max_value,
2343        u128_legacy_fn_min_value,
2344        u128_legacy_mod,
2345        ub_checks,
2346        unaligned_volatile_load,
2347        unaligned_volatile_store,
2348        unboxed_closures,
2349        unchecked_add,
2350        unchecked_div,
2351        unchecked_funnel_shl,
2352        unchecked_funnel_shr,
2353        unchecked_mul,
2354        unchecked_rem,
2355        unchecked_shl,
2356        unchecked_shr,
2357        unchecked_sub,
2358        undecorated,
2359        underscore_const_names,
2360        underscore_imports,
2361        underscore_lifetimes,
2362        uniform_paths,
2363        unimplemented_macro,
2364        unit,
2365        universal_impl_trait,
2366        unix,
2367        unlikely,
2368        unmarked_api,
2369        unnamed_fields,
2370        unpin,
2371        unqualified_local_imports,
2372        unreachable,
2373        unreachable_2015,
2374        unreachable_2015_macro,
2375        unreachable_2021,
2376        unreachable_code,
2377        unreachable_display,
2378        unreachable_macro,
2379        unrestricted_attribute_tokens,
2380        unsafe_attributes,
2381        unsafe_binders,
2382        unsafe_block_in_unsafe_fn,
2383        unsafe_cell,
2384        unsafe_cell_raw_get,
2385        unsafe_extern_blocks,
2386        unsafe_fields,
2387        unsafe_no_drop_flag,
2388        unsafe_pinned,
2389        unsafe_unpin,
2390        unsize,
2391        unsized_const_param_ty,
2392        unsized_const_params,
2393        unsized_fn_params,
2394        unsized_locals,
2395        unsized_tuple_coercion,
2396        unstable,
2397        unstable_feature_bound,
2398        unstable_location_reason_default: "this crate is being loaded from the sysroot, an \
2399                          unstable location; did you mean to load this crate \
2400                          from crates.io via `Cargo.toml` instead?",
2401        untagged_unions,
2402        unused_imports,
2403        unwind,
2404        unwind_attributes,
2405        unwind_safe_trait,
2406        unwrap,
2407        unwrap_binder,
2408        unwrap_or,
2409        update,
2410        use_cloned,
2411        use_extern_macros,
2412        use_nested_groups,
2413        used,
2414        used_with_arg,
2415        using,
2416        usize,
2417        usize_legacy_const_max,
2418        usize_legacy_const_min,
2419        usize_legacy_fn_max_value,
2420        usize_legacy_fn_min_value,
2421        usize_legacy_mod,
2422        v1,
2423        v8plus,
2424        va_arg,
2425        va_copy,
2426        va_end,
2427        va_list,
2428        va_start,
2429        val,
2430        validity,
2431        value,
2432        values,
2433        var,
2434        variant_count,
2435        vec,
2436        vec_as_mut_slice,
2437        vec_as_slice,
2438        vec_from_elem,
2439        vec_is_empty,
2440        vec_macro,
2441        vec_new,
2442        vec_pop,
2443        vec_reserve,
2444        vec_with_capacity,
2445        vecdeque_iter,
2446        vecdeque_reserve,
2447        vector,
2448        verbatim,
2449        version,
2450        vfp2,
2451        vis,
2452        visible_private_types,
2453        volatile,
2454        volatile_copy_memory,
2455        volatile_copy_nonoverlapping_memory,
2456        volatile_load,
2457        volatile_set_memory,
2458        volatile_store,
2459        vreg,
2460        vreg_low16,
2461        vsreg,
2462        vsx,
2463        vtable_align,
2464        vtable_size,
2465        warn,
2466        wasip2,
2467        wasm32,
2468        wasm64,
2469        wasm_abi,
2470        wasm_import_module,
2471        wasm_target_feature,
2472        weak,
2473        weak_odr,
2474        where_clause_attrs,
2475        while_let,
2476        whole_dash_archive: "whole-archive",
2477        width,
2478        windows,
2479        windows_subsystem,
2480        with_negative_coherence,
2481        wrap_binder,
2482        wrapping_add,
2483        wrapping_div,
2484        wrapping_mul,
2485        wrapping_rem,
2486        wrapping_rem_euclid,
2487        wrapping_sub,
2488        wreg,
2489        write_bytes,
2490        write_fmt,
2491        write_macro,
2492        write_str,
2493        write_via_move,
2494        writeln_macro,
2495        x86,
2496        x86_64,
2497        x86_amx_intrinsics,
2498        x87_reg,
2499        x87_target_feature,
2500        xer,
2501        xmm_reg,
2502        xop_target_feature,
2503        xtensa,
2504        yeet_desugar_details,
2505        yeet_expr,
2506        yes,
2507        yield_expr,
2508        ymm_reg,
2509        yreg,
2510        zca,
2511        zfh,
2512        zfhmin,
2513        zmm_reg,
2514        ztso,
2515        // tidy-alphabetical-end
2516    }
2517}
2518
2519/// Symbols for crates that are part of the stable standard library: `std`, `core`, `alloc`, and
2520/// `proc_macro`.
2521pub const STDLIB_STABLE_CRATES: &[Symbol] = &[sym::std, sym::core, sym::alloc, sym::proc_macro];
2522
2523#[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
2524pub struct Ident {
2525    /// `name` should never be the empty symbol. If you are considering that,
2526    /// you are probably conflating "empty identifier with "no identifier" and
2527    /// you should use `Option<Ident>` instead.
2528    /// Trying to construct an `Ident` with an empty name will trigger debug assertions.
2529    pub name: Symbol,
2530    pub span: Span,
2531}
2532
2533impl Ident {
2534    #[inline]
2535    /// Constructs a new identifier from a symbol and a span.
2536    pub fn new(name: Symbol, span: Span) -> Ident {
2537        debug_assert_ne!(name, sym::empty);
2538        Ident { name, span }
2539    }
2540
2541    /// Constructs a new identifier with a dummy span.
2542    #[inline]
2543    pub fn with_dummy_span(name: Symbol) -> Ident {
2544        Ident::new(name, DUMMY_SP)
2545    }
2546
2547    // For dummy identifiers that are never used and absolutely must be
2548    // present. Note that this does *not* use the empty symbol; `sym::dummy`
2549    // makes it clear that it's intended as a dummy value, and is more likely
2550    // to be detected if it accidentally does get used.
2551    #[inline]
2552    pub fn dummy() -> Ident {
2553        Ident::with_dummy_span(sym::dummy)
2554    }
2555
2556    /// Maps a string to an identifier with a dummy span.
2557    pub fn from_str(string: &str) -> Ident {
2558        Ident::with_dummy_span(Symbol::intern(string))
2559    }
2560
2561    /// Maps a string and a span to an identifier.
2562    pub fn from_str_and_span(string: &str, span: Span) -> Ident {
2563        Ident::new(Symbol::intern(string), span)
2564    }
2565
2566    /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
2567    pub fn with_span_pos(self, span: Span) -> Ident {
2568        Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
2569    }
2570
2571    /// Creates a new ident with the same span and name with leading quote removed, if any.
2572    /// Calling it on a `'` ident will return an empty ident, which triggers debug assertions.
2573    pub fn without_first_quote(self) -> Ident {
2574        self.as_str()
2575            .strip_prefix('\'')
2576            .map_or(self, |name| Ident::new(Symbol::intern(name), self.span))
2577    }
2578
2579    /// "Normalize" ident for use in comparisons using "item hygiene".
2580    /// Identifiers with same string value become same if they came from the same macro 2.0 macro
2581    /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
2582    /// different macro 2.0 macros.
2583    /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
2584    pub fn normalize_to_macros_2_0(self) -> Ident {
2585        Ident::new(self.name, self.span.normalize_to_macros_2_0())
2586    }
2587
2588    /// "Normalize" ident for use in comparisons using "local variable hygiene".
2589    /// Identifiers with same string value become same if they came from the same non-transparent
2590    /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
2591    /// non-transparent macros.
2592    /// Technically, this operation strips all transparent marks from ident's syntactic context.
2593    #[inline]
2594    pub fn normalize_to_macro_rules(self) -> Ident {
2595        Ident::new(self.name, self.span.normalize_to_macro_rules())
2596    }
2597
2598    /// Access the underlying string. This is a slowish operation because it
2599    /// requires locking the symbol interner.
2600    ///
2601    /// Note that the lifetime of the return value is a lie. See
2602    /// `Symbol::as_str()` for details.
2603    pub fn as_str(&self) -> &str {
2604        self.name.as_str()
2605    }
2606}
2607
2608impl PartialEq for Ident {
2609    #[inline]
2610    fn eq(&self, rhs: &Self) -> bool {
2611        self.name == rhs.name && self.span.eq_ctxt(rhs.span)
2612    }
2613}
2614
2615impl Hash for Ident {
2616    fn hash<H: Hasher>(&self, state: &mut H) {
2617        self.name.hash(state);
2618        self.span.ctxt().hash(state);
2619    }
2620}
2621
2622impl fmt::Debug for Ident {
2623    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2624        fmt::Display::fmt(self, f)?;
2625        fmt::Debug::fmt(&self.span.ctxt(), f)
2626    }
2627}
2628
2629/// This implementation is supposed to be used in error messages, so it's expected to be identical
2630/// to printing the original identifier token written in source code (`token_to_string`),
2631/// except that AST identifiers don't keep the rawness flag, so we have to guess it.
2632impl fmt::Display for Ident {
2633    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2634        fmt::Display::fmt(&IdentPrinter::new(self.name, self.guess_print_mode(), None), f)
2635    }
2636}
2637
2638pub enum IdentPrintMode {
2639    Normal,
2640    RawIdent,
2641    RawLifetime,
2642}
2643
2644/// The most general type to print identifiers.
2645///
2646/// AST pretty-printer is used as a fallback for turning AST structures into token streams for
2647/// proc macros. Additionally, proc macros may stringify their input and expect it survive the
2648/// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
2649/// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
2650/// hygiene data, most importantly name of the crate it refers to.
2651/// As a result we print `$crate` as `crate` if it refers to the local crate
2652/// and as `::other_crate_name` if it refers to some other crate.
2653/// Note, that this is only done if the ident token is printed from inside of AST pretty-printing,
2654/// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
2655/// so we should not perform this lossy conversion if the top level call to the pretty-printer was
2656/// done for a token stream or a single token.
2657pub struct IdentPrinter {
2658    symbol: Symbol,
2659    mode: IdentPrintMode,
2660    /// Span used for retrieving the crate name to which `$crate` refers to,
2661    /// if this field is `None` then the `$crate` conversion doesn't happen.
2662    convert_dollar_crate: Option<Span>,
2663}
2664
2665impl IdentPrinter {
2666    /// The most general `IdentPrinter` constructor. Do not use this.
2667    pub fn new(
2668        symbol: Symbol,
2669        mode: IdentPrintMode,
2670        convert_dollar_crate: Option<Span>,
2671    ) -> IdentPrinter {
2672        IdentPrinter { symbol, mode, convert_dollar_crate }
2673    }
2674
2675    /// This implementation is supposed to be used when printing identifiers
2676    /// as a part of pretty-printing for larger AST pieces.
2677    /// Do not use this either.
2678    pub fn for_ast_ident(ident: Ident, mode: IdentPrintMode) -> IdentPrinter {
2679        IdentPrinter::new(ident.name, mode, Some(ident.span))
2680    }
2681}
2682
2683impl fmt::Display for IdentPrinter {
2684    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2685        let s = match self.mode {
2686            IdentPrintMode::Normal
2687                if self.symbol == kw::DollarCrate
2688                    && let Some(span) = self.convert_dollar_crate =>
2689            {
2690                let converted = span.ctxt().dollar_crate_name();
2691                if !converted.is_path_segment_keyword() {
2692                    f.write_str("::")?;
2693                }
2694                converted
2695            }
2696            IdentPrintMode::Normal => self.symbol,
2697            IdentPrintMode::RawIdent => {
2698                f.write_str("r#")?;
2699                self.symbol
2700            }
2701            IdentPrintMode::RawLifetime => {
2702                f.write_str("'r#")?;
2703                let s = self
2704                    .symbol
2705                    .as_str()
2706                    .strip_prefix("'")
2707                    .expect("only lifetime idents should be passed with RawLifetime mode");
2708                Symbol::intern(s)
2709            }
2710        };
2711        s.fmt(f)
2712    }
2713}
2714
2715/// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
2716/// construction for "local variable hygiene" comparisons.
2717///
2718/// Use this type when you need to compare identifiers according to macro_rules hygiene.
2719/// This ensures compile-time safety and avoids manual normalization calls.
2720#[derive(Copy, Clone, Eq, PartialEq, Hash)]
2721pub struct MacroRulesNormalizedIdent(Ident);
2722
2723impl MacroRulesNormalizedIdent {
2724    #[inline]
2725    pub fn new(ident: Ident) -> Self {
2726        MacroRulesNormalizedIdent(ident.normalize_to_macro_rules())
2727    }
2728}
2729
2730impl fmt::Debug for MacroRulesNormalizedIdent {
2731    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2732        fmt::Debug::fmt(&self.0, f)
2733    }
2734}
2735
2736impl fmt::Display for MacroRulesNormalizedIdent {
2737    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2738        fmt::Display::fmt(&self.0, f)
2739    }
2740}
2741
2742/// An newtype around `Ident` that calls [Ident::normalize_to_macros_2_0] on
2743/// construction for "item hygiene" comparisons.
2744///
2745/// Identifiers with same string value become same if they came from the same macro 2.0 macro
2746/// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
2747/// different macro 2.0 macros.
2748#[derive(Copy, Clone, Eq, PartialEq, Hash)]
2749pub struct Macros20NormalizedIdent(pub Ident);
2750
2751impl Macros20NormalizedIdent {
2752    #[inline]
2753    pub fn new(ident: Ident) -> Self {
2754        Macros20NormalizedIdent(ident.normalize_to_macros_2_0())
2755    }
2756
2757    // dummy_span does not need to be normalized, so we can use `Ident` directly
2758    pub fn with_dummy_span(name: Symbol) -> Self {
2759        Macros20NormalizedIdent(Ident::with_dummy_span(name))
2760    }
2761}
2762
2763impl fmt::Debug for Macros20NormalizedIdent {
2764    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2765        fmt::Debug::fmt(&self.0, f)
2766    }
2767}
2768
2769impl fmt::Display for Macros20NormalizedIdent {
2770    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2771        fmt::Display::fmt(&self.0, f)
2772    }
2773}
2774
2775/// By impl Deref, we can access the wrapped Ident as if it were a normal Ident
2776/// such as `norm_ident.name` instead of `norm_ident.0.name`.
2777impl Deref for Macros20NormalizedIdent {
2778    type Target = Ident;
2779    fn deref(&self) -> &Self::Target {
2780        &self.0
2781    }
2782}
2783
2784/// An interned UTF-8 string.
2785///
2786/// Internally, a `Symbol` is implemented as an index, and all operations
2787/// (including hashing, equality, and ordering) operate on that index. The use
2788/// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
2789/// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
2790///
2791/// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
2792/// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
2793#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
2794pub struct Symbol(SymbolIndex);
2795
2796// Used within both `Symbol` and `ByteSymbol`.
2797rustc_index::newtype_index! {
2798    #[orderable]
2799    struct SymbolIndex {}
2800}
2801
2802impl Symbol {
2803    /// Avoid this except for things like deserialization of previously
2804    /// serialized symbols, and testing. Use `intern` instead.
2805    pub const fn new(n: u32) -> Self {
2806        Symbol(SymbolIndex::from_u32(n))
2807    }
2808
2809    /// Maps a string to its interned representation.
2810    #[rustc_diagnostic_item = "SymbolIntern"]
2811    pub fn intern(str: &str) -> Self {
2812        with_session_globals(|session_globals| session_globals.symbol_interner.intern_str(str))
2813    }
2814
2815    /// Access the underlying string. This is a slowish operation because it
2816    /// requires locking the symbol interner.
2817    ///
2818    /// Note that the lifetime of the return value is a lie. It's not the same
2819    /// as `&self`, but actually tied to the lifetime of the underlying
2820    /// interner. Interners are long-lived, and there are very few of them, and
2821    /// this function is typically used for short-lived things, so in practice
2822    /// it works out ok.
2823    pub fn as_str(&self) -> &str {
2824        with_session_globals(|session_globals| unsafe {
2825            std::mem::transmute::<&str, &str>(session_globals.symbol_interner.get_str(*self))
2826        })
2827    }
2828
2829    pub fn as_u32(self) -> u32 {
2830        self.0.as_u32()
2831    }
2832
2833    pub fn is_empty(self) -> bool {
2834        self == sym::empty
2835    }
2836
2837    /// This method is supposed to be used in error messages, so it's expected to be
2838    /// identical to printing the original identifier token written in source code
2839    /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
2840    /// or edition, so we have to guess the rawness using the global edition.
2841    pub fn to_ident_string(self) -> String {
2842        // Avoid creating an empty identifier, because that asserts in debug builds.
2843        if self == sym::empty { String::new() } else { Ident::with_dummy_span(self).to_string() }
2844    }
2845}
2846
2847impl fmt::Debug for Symbol {
2848    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2849        fmt::Debug::fmt(self.as_str(), f)
2850    }
2851}
2852
2853impl fmt::Display for Symbol {
2854    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2855        fmt::Display::fmt(self.as_str(), f)
2856    }
2857}
2858
2859impl<CTX> HashStable<CTX> for Symbol {
2860    #[inline]
2861    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
2862        self.as_str().hash_stable(hcx, hasher);
2863    }
2864}
2865
2866impl<CTX> ToStableHashKey<CTX> for Symbol {
2867    type KeyType = String;
2868    #[inline]
2869    fn to_stable_hash_key(&self, _: &CTX) -> String {
2870        self.as_str().to_string()
2871    }
2872}
2873
2874impl StableCompare for Symbol {
2875    const CAN_USE_UNSTABLE_SORT: bool = true;
2876
2877    fn stable_cmp(&self, other: &Self) -> std::cmp::Ordering {
2878        self.as_str().cmp(other.as_str())
2879    }
2880}
2881
2882/// Like `Symbol`, but for byte strings. `ByteSymbol` is used less widely, so
2883/// it has fewer operations defined than `Symbol`.
2884#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
2885pub struct ByteSymbol(SymbolIndex);
2886
2887impl ByteSymbol {
2888    /// Avoid this except for things like deserialization of previously
2889    /// serialized symbols, and testing. Use `intern` instead.
2890    pub const fn new(n: u32) -> Self {
2891        ByteSymbol(SymbolIndex::from_u32(n))
2892    }
2893
2894    /// Maps a string to its interned representation.
2895    pub fn intern(byte_str: &[u8]) -> Self {
2896        with_session_globals(|session_globals| {
2897            session_globals.symbol_interner.intern_byte_str(byte_str)
2898        })
2899    }
2900
2901    /// Like `Symbol::as_str`.
2902    pub fn as_byte_str(&self) -> &[u8] {
2903        with_session_globals(|session_globals| unsafe {
2904            std::mem::transmute::<&[u8], &[u8]>(session_globals.symbol_interner.get_byte_str(*self))
2905        })
2906    }
2907
2908    pub fn as_u32(self) -> u32 {
2909        self.0.as_u32()
2910    }
2911}
2912
2913impl fmt::Debug for ByteSymbol {
2914    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2915        fmt::Debug::fmt(self.as_byte_str(), f)
2916    }
2917}
2918
2919impl<CTX> HashStable<CTX> for ByteSymbol {
2920    #[inline]
2921    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
2922        self.as_byte_str().hash_stable(hcx, hasher);
2923    }
2924}
2925
2926// Interner used for both `Symbol`s and `ByteSymbol`s. If a string and a byte
2927// string with identical contents (e.g. "foo" and b"foo") are both interned,
2928// only one copy will be stored and the resulting `Symbol` and `ByteSymbol`
2929// will have the same index.
2930pub(crate) struct Interner(Lock<InternerInner>);
2931
2932// The `&'static [u8]`s in this type actually point into the arena.
2933//
2934// This type is private to prevent accidentally constructing more than one
2935// `Interner` on the same thread, which makes it easy to mix up `Symbol`s
2936// between `Interner`s.
2937struct InternerInner {
2938    arena: DroplessArena,
2939    byte_strs: FxIndexSet<&'static [u8]>,
2940}
2941
2942impl Interner {
2943    // These arguments are `&str`, but because of the sharing, we are
2944    // effectively pre-interning all these strings for both `Symbol` and
2945    // `ByteSymbol`.
2946    fn prefill(init: &[&'static str], extra: &[&'static str]) -> Self {
2947        let byte_strs = FxIndexSet::from_iter(
2948            init.iter().copied().chain(extra.iter().copied()).map(|str| str.as_bytes()),
2949        );
2950
2951        // The order in which duplicates are reported is irrelevant.
2952        #[expect(rustc::potential_query_instability)]
2953        if byte_strs.len() != init.len() + extra.len() {
2954            panic!(
2955                "duplicate symbols in the rustc symbol list and the extra symbols added by the driver: {:?}",
2956                FxHashSet::intersection(
2957                    &init.iter().copied().collect(),
2958                    &extra.iter().copied().collect(),
2959                )
2960                .collect::<Vec<_>>()
2961            )
2962        }
2963
2964        Interner(Lock::new(InternerInner { arena: Default::default(), byte_strs }))
2965    }
2966
2967    fn intern_str(&self, str: &str) -> Symbol {
2968        Symbol::new(self.intern_inner(str.as_bytes()))
2969    }
2970
2971    fn intern_byte_str(&self, byte_str: &[u8]) -> ByteSymbol {
2972        ByteSymbol::new(self.intern_inner(byte_str))
2973    }
2974
2975    #[inline]
2976    fn intern_inner(&self, byte_str: &[u8]) -> u32 {
2977        let mut inner = self.0.lock();
2978        if let Some(idx) = inner.byte_strs.get_index_of(byte_str) {
2979            return idx as u32;
2980        }
2981
2982        let byte_str: &[u8] = inner.arena.alloc_slice(byte_str);
2983
2984        // SAFETY: we can extend the arena allocation to `'static` because we
2985        // only access these while the arena is still alive.
2986        let byte_str: &'static [u8] = unsafe { &*(byte_str as *const [u8]) };
2987
2988        // This second hash table lookup can be avoided by using `RawEntryMut`,
2989        // but this code path isn't hot enough for it to be worth it. See
2990        // #91445 for details.
2991        let (idx, is_new) = inner.byte_strs.insert_full(byte_str);
2992        debug_assert!(is_new); // due to the get_index_of check above
2993
2994        idx as u32
2995    }
2996
2997    /// Get the symbol as a string.
2998    ///
2999    /// [`Symbol::as_str()`] should be used in preference to this function.
3000    fn get_str(&self, symbol: Symbol) -> &str {
3001        let byte_str = self.get_inner(symbol.0.as_usize());
3002        // SAFETY: known to be a UTF8 string because it's a `Symbol`.
3003        unsafe { str::from_utf8_unchecked(byte_str) }
3004    }
3005
3006    /// Get the symbol as a string.
3007    ///
3008    /// [`ByteSymbol::as_byte_str()`] should be used in preference to this function.
3009    fn get_byte_str(&self, symbol: ByteSymbol) -> &[u8] {
3010        self.get_inner(symbol.0.as_usize())
3011    }
3012
3013    fn get_inner(&self, index: usize) -> &[u8] {
3014        self.0.lock().byte_strs.get_index(index).unwrap()
3015    }
3016}
3017
3018// This module has a very short name because it's used a lot.
3019/// This module contains all the defined keyword `Symbol`s.
3020///
3021/// Given that `kw` is imported, use them like `kw::keyword_name`.
3022/// For example `kw::Loop` or `kw::Break`.
3023pub mod kw {
3024    pub use super::kw_generated::*;
3025}
3026
3027// This module has a very short name because it's used a lot.
3028/// This module contains all the defined non-keyword `Symbol`s.
3029///
3030/// Given that `sym` is imported, use them like `sym::symbol_name`.
3031/// For example `sym::rustfmt` or `sym::u8`.
3032pub mod sym {
3033    // Used from a macro in `librustc_feature/accepted.rs`
3034    use super::Symbol;
3035    pub use super::kw::MacroRules as macro_rules;
3036    #[doc(inline)]
3037    pub use super::sym_generated::*;
3038
3039    /// Get the symbol for an integer.
3040    ///
3041    /// The first few non-negative integers each have a static symbol and therefore
3042    /// are fast.
3043    pub fn integer<N: TryInto<usize> + Copy + itoa::Integer>(n: N) -> Symbol {
3044        if let Result::Ok(idx) = n.try_into() {
3045            if idx < 10 {
3046                return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
3047            }
3048        }
3049        let mut buffer = itoa::Buffer::new();
3050        let printed = buffer.format(n);
3051        Symbol::intern(printed)
3052    }
3053}
3054
3055impl Symbol {
3056    fn is_special(self) -> bool {
3057        self <= kw::Underscore
3058    }
3059
3060    fn is_used_keyword_always(self) -> bool {
3061        self >= kw::As && self <= kw::While
3062    }
3063
3064    fn is_unused_keyword_always(self) -> bool {
3065        self >= kw::Abstract && self <= kw::Yield
3066    }
3067
3068    fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
3069        (self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
3070    }
3071
3072    fn is_unused_keyword_conditional(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
3073        self == kw::Gen && edition().at_least_rust_2024()
3074            || self == kw::Try && edition().at_least_rust_2018()
3075    }
3076
3077    pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
3078        self.is_special()
3079            || self.is_used_keyword_always()
3080            || self.is_unused_keyword_always()
3081            || self.is_used_keyword_conditional(edition)
3082            || self.is_unused_keyword_conditional(edition)
3083    }
3084
3085    pub fn is_weak(self) -> bool {
3086        self >= kw::Auto && self <= kw::Yeet
3087    }
3088
3089    /// A keyword or reserved identifier that can be used as a path segment.
3090    pub fn is_path_segment_keyword(self) -> bool {
3091        self == kw::Super
3092            || self == kw::SelfLower
3093            || self == kw::SelfUpper
3094            || self == kw::Crate
3095            || self == kw::PathRoot
3096            || self == kw::DollarCrate
3097    }
3098
3099    /// Returns `true` if the symbol is `true` or `false`.
3100    pub fn is_bool_lit(self) -> bool {
3101        self == kw::True || self == kw::False
3102    }
3103
3104    /// Returns `true` if this symbol can be a raw identifier.
3105    pub fn can_be_raw(self) -> bool {
3106        self != sym::empty && self != kw::Underscore && !self.is_path_segment_keyword()
3107    }
3108
3109    /// Was this symbol index predefined in the compiler's `symbols!` macro?
3110    /// Note: this applies to both `Symbol`s and `ByteSymbol`s, which is why it
3111    /// takes a `u32` argument instead of a `&self` argument. Use with care.
3112    pub fn is_predefined(index: u32) -> bool {
3113        index < PREDEFINED_SYMBOLS_COUNT
3114    }
3115}
3116
3117impl Ident {
3118    /// Returns `true` for reserved identifiers used internally for elided lifetimes,
3119    /// unnamed method parameters, crate root module, error recovery etc.
3120    pub fn is_special(self) -> bool {
3121        self.name.is_special()
3122    }
3123
3124    /// Returns `true` if the token is a keyword used in the language.
3125    pub fn is_used_keyword(self) -> bool {
3126        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
3127        self.name.is_used_keyword_always()
3128            || self.name.is_used_keyword_conditional(|| self.span.edition())
3129    }
3130
3131    /// Returns `true` if the token is a keyword reserved for possible future use.
3132    pub fn is_unused_keyword(self) -> bool {
3133        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
3134        self.name.is_unused_keyword_always()
3135            || self.name.is_unused_keyword_conditional(|| self.span.edition())
3136    }
3137
3138    /// Returns `true` if the token is either a special identifier or a keyword.
3139    pub fn is_reserved(self) -> bool {
3140        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
3141        self.name.is_reserved(|| self.span.edition())
3142    }
3143
3144    /// A keyword or reserved identifier that can be used as a path segment.
3145    pub fn is_path_segment_keyword(self) -> bool {
3146        self.name.is_path_segment_keyword()
3147    }
3148
3149    /// We see this identifier in a normal identifier position, like variable name or a type.
3150    /// How was it written originally? Did it use the raw form? Let's try to guess.
3151    pub fn is_raw_guess(self) -> bool {
3152        self.name.can_be_raw() && self.is_reserved()
3153    }
3154
3155    /// Given the name of a lifetime without the first quote (`'`),
3156    /// returns whether the lifetime name is reserved (therefore invalid)
3157    pub fn is_reserved_lifetime(self) -> bool {
3158        self.is_reserved() && ![kw::Underscore, kw::Static].contains(&self.name)
3159    }
3160
3161    pub fn is_raw_lifetime_guess(self) -> bool {
3162        // Check that the name isn't just a single quote.
3163        // `self.without_first_quote()` would return empty ident, which triggers debug assert.
3164        if self.name.as_str() == "'" {
3165            return false;
3166        }
3167        let ident_without_apostrophe = self.without_first_quote();
3168        ident_without_apostrophe.name != self.name
3169            && ident_without_apostrophe.name.can_be_raw()
3170            && ident_without_apostrophe.is_reserved_lifetime()
3171    }
3172
3173    pub fn guess_print_mode(self) -> IdentPrintMode {
3174        if self.is_raw_lifetime_guess() {
3175            IdentPrintMode::RawLifetime
3176        } else if self.is_raw_guess() {
3177            IdentPrintMode::RawIdent
3178        } else {
3179            IdentPrintMode::Normal
3180        }
3181    }
3182
3183    /// Whether this would be the identifier for a tuple field like `self.0`, as
3184    /// opposed to a named field like `self.thing`.
3185    pub fn is_numeric(self) -> bool {
3186        self.as_str().bytes().all(|b| b.is_ascii_digit())
3187    }
3188}
3189
3190/// Collect all the keywords in a given edition into a vector.
3191///
3192/// *Note:* Please update this if a new keyword is added beyond the current
3193/// range.
3194pub fn used_keywords(edition: impl Copy + FnOnce() -> Edition) -> Vec<Symbol> {
3195    (kw::DollarCrate.as_u32()..kw::Yeet.as_u32())
3196        .filter_map(|kw| {
3197            let kw = Symbol::new(kw);
3198            if kw.is_used_keyword_always() || kw.is_used_keyword_conditional(edition) {
3199                Some(kw)
3200            } else {
3201                None
3202            }
3203        })
3204        .collect()
3205}