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        dialect,
882        direct,
883        discriminant_kind,
884        discriminant_type,
885        discriminant_value,
886        disjoint_bitor,
887        dispatch_from_dyn,
888        div,
889        div_assign,
890        diverging_block_default,
891        dl,
892        do_not_recommend,
893        doc,
894        doc_alias,
895        doc_auto_cfg,
896        doc_cfg,
897        doc_cfg_hide,
898        doc_keyword,
899        doc_masked,
900        doc_notable_trait,
901        doc_primitive,
902        doc_spotlight,
903        doctest,
904        dotdot: "..",
905        dotdot_in_tuple_patterns,
906        dotdoteq_in_patterns,
907        dreg,
908        dreg_low8,
909        dreg_low16,
910        drop,
911        drop_in_place,
912        drop_types_in_const,
913        dropck_eyepatch,
914        dropck_parametricity,
915        dummy: "<!dummy!>", // use this instead of `sym::empty` for symbols that won't be used
916        dummy_cgu_name,
917        dylib,
918        dyn_compatible_for_dispatch,
919        dyn_metadata,
920        dyn_star,
921        dyn_trait,
922        dynamic_no_pic: "dynamic-no-pic",
923        e,
924        edition_panic,
925        effective_target_features,
926        effects,
927        eh_catch_typeinfo,
928        eh_personality,
929        emit,
930        emit_enum,
931        emit_enum_variant,
932        emit_enum_variant_arg,
933        emit_struct,
934        emit_struct_field,
935        // Notes about `sym::empty`:
936        // - It should only be used when it genuinely means "empty symbol". Use
937        //   `Option<Symbol>` when "no symbol" is a possibility.
938        // - For dummy symbols that are never used and absolutely must be
939        //   present, it's better to use `sym::dummy` than `sym::empty`, because
940        //   it's clearer that it's intended as a dummy value, and more likely
941        //   to be detected if it accidentally does get used.
942        empty: "",
943        emscripten_wasm_eh,
944        enable,
945        encode,
946        end,
947        entry_nops,
948        enumerate_method,
949        env,
950        env_CFG_RELEASE: env!("CFG_RELEASE"),
951        eprint_macro,
952        eprintln_macro,
953        eq,
954        ergonomic_clones,
955        ermsb_target_feature,
956        exact_div,
957        except,
958        exception_handling: "exception-handling",
959        exchange_malloc,
960        exclusive_range_pattern,
961        exhaustive_integer_patterns,
962        exhaustive_patterns,
963        existential_type,
964        exp2f16,
965        exp2f32,
966        exp2f64,
967        exp2f128,
968        expect,
969        expected,
970        expf16,
971        expf32,
972        expf64,
973        expf128,
974        explicit_extern_abis,
975        explicit_generic_args_with_impl_trait,
976        explicit_tail_calls,
977        export_name,
978        export_stable,
979        expr,
980        expr_2021,
981        expr_fragment_specifier_2024,
982        extended_key_value_attributes,
983        extended_varargs_abi_support,
984        extern_absolute_paths,
985        extern_crate_item_prelude,
986        extern_crate_self,
987        extern_in_paths,
988        extern_prelude,
989        extern_system_varargs,
990        extern_types,
991        extern_weak,
992        external,
993        external_doc,
994        f,
995        f16,
996        f16_consts_mod,
997        f16_epsilon,
998        f16_nan,
999        f16c_target_feature,
1000        f32,
1001        f32_consts_mod,
1002        f32_epsilon,
1003        f32_legacy_const_digits,
1004        f32_legacy_const_epsilon,
1005        f32_legacy_const_infinity,
1006        f32_legacy_const_mantissa_dig,
1007        f32_legacy_const_max,
1008        f32_legacy_const_max_10_exp,
1009        f32_legacy_const_max_exp,
1010        f32_legacy_const_min,
1011        f32_legacy_const_min_10_exp,
1012        f32_legacy_const_min_exp,
1013        f32_legacy_const_min_positive,
1014        f32_legacy_const_nan,
1015        f32_legacy_const_neg_infinity,
1016        f32_legacy_const_radix,
1017        f32_nan,
1018        f64,
1019        f64_consts_mod,
1020        f64_epsilon,
1021        f64_legacy_const_digits,
1022        f64_legacy_const_epsilon,
1023        f64_legacy_const_infinity,
1024        f64_legacy_const_mantissa_dig,
1025        f64_legacy_const_max,
1026        f64_legacy_const_max_10_exp,
1027        f64_legacy_const_max_exp,
1028        f64_legacy_const_min,
1029        f64_legacy_const_min_10_exp,
1030        f64_legacy_const_min_exp,
1031        f64_legacy_const_min_positive,
1032        f64_legacy_const_nan,
1033        f64_legacy_const_neg_infinity,
1034        f64_legacy_const_radix,
1035        f64_nan,
1036        f128,
1037        f128_consts_mod,
1038        f128_epsilon,
1039        f128_nan,
1040        fabsf16,
1041        fabsf32,
1042        fabsf64,
1043        fabsf128,
1044        fadd_algebraic,
1045        fadd_fast,
1046        fake_variadic,
1047        fallback,
1048        fdiv_algebraic,
1049        fdiv_fast,
1050        feature,
1051        fence,
1052        ferris: "🦀",
1053        fetch_update,
1054        ffi,
1055        ffi_const,
1056        ffi_pure,
1057        ffi_returns_twice,
1058        field,
1059        field_init_shorthand,
1060        file,
1061        file_options,
1062        flags,
1063        float,
1064        float_to_int_unchecked,
1065        floorf16,
1066        floorf32,
1067        floorf64,
1068        floorf128,
1069        fmaf16,
1070        fmaf32,
1071        fmaf64,
1072        fmaf128,
1073        fmt,
1074        fmt_debug,
1075        fmul_algebraic,
1076        fmul_fast,
1077        fmuladdf16,
1078        fmuladdf32,
1079        fmuladdf64,
1080        fmuladdf128,
1081        fn_align,
1082        fn_body,
1083        fn_delegation,
1084        fn_must_use,
1085        fn_mut,
1086        fn_once,
1087        fn_once_output,
1088        fn_ptr_addr,
1089        fn_ptr_trait,
1090        forbid,
1091        force_target_feature,
1092        forget,
1093        format,
1094        format_args,
1095        format_args_capture,
1096        format_args_macro,
1097        format_args_nl,
1098        format_argument,
1099        format_arguments,
1100        format_macro,
1101        framework,
1102        freeze,
1103        freeze_impls,
1104        freg,
1105        frem_algebraic,
1106        frem_fast,
1107        from,
1108        from_desugaring,
1109        from_fn,
1110        from_iter,
1111        from_iter_fn,
1112        from_output,
1113        from_residual,
1114        from_size_align_unchecked,
1115        from_str,
1116        from_str_method,
1117        from_str_nonconst,
1118        from_u16,
1119        from_usize,
1120        from_yeet,
1121        frontmatter,
1122        fs_create_dir,
1123        fsub_algebraic,
1124        fsub_fast,
1125        full,
1126        fundamental,
1127        fused_iterator,
1128        future,
1129        future_drop_poll,
1130        future_output,
1131        future_trait,
1132        fxsr,
1133        gdb_script_file,
1134        ge,
1135        gen_blocks,
1136        gen_future,
1137        generator_clone,
1138        generators,
1139        generic_arg_infer,
1140        generic_assert,
1141        generic_associated_types,
1142        generic_associated_types_extended,
1143        generic_const_exprs,
1144        generic_const_items,
1145        generic_const_parameter_types,
1146        generic_param_attrs,
1147        generic_pattern_types,
1148        get_context,
1149        global_alloc_ty,
1150        global_allocator,
1151        global_asm,
1152        global_registration,
1153        globs,
1154        gt,
1155        guard_patterns,
1156        half_open_range_patterns,
1157        half_open_range_patterns_in_slices,
1158        hash,
1159        hashmap_contains_key,
1160        hashmap_drain_ty,
1161        hashmap_insert,
1162        hashmap_iter_mut_ty,
1163        hashmap_iter_ty,
1164        hashmap_keys_ty,
1165        hashmap_values_mut_ty,
1166        hashmap_values_ty,
1167        hashset_drain_ty,
1168        hashset_iter,
1169        hashset_iter_ty,
1170        hexagon,
1171        hexagon_target_feature,
1172        hidden,
1173        hide,
1174        hint,
1175        homogeneous_aggregate,
1176        host,
1177        html_favicon_url,
1178        html_logo_url,
1179        html_no_source,
1180        html_playground_url,
1181        html_root_url,
1182        hwaddress,
1183        i,
1184        i8,
1185        i8_legacy_const_max,
1186        i8_legacy_const_min,
1187        i8_legacy_fn_max_value,
1188        i8_legacy_fn_min_value,
1189        i8_legacy_mod,
1190        i16,
1191        i16_legacy_const_max,
1192        i16_legacy_const_min,
1193        i16_legacy_fn_max_value,
1194        i16_legacy_fn_min_value,
1195        i16_legacy_mod,
1196        i32,
1197        i32_legacy_const_max,
1198        i32_legacy_const_min,
1199        i32_legacy_fn_max_value,
1200        i32_legacy_fn_min_value,
1201        i32_legacy_mod,
1202        i64,
1203        i64_legacy_const_max,
1204        i64_legacy_const_min,
1205        i64_legacy_fn_max_value,
1206        i64_legacy_fn_min_value,
1207        i64_legacy_mod,
1208        i128,
1209        i128_legacy_const_max,
1210        i128_legacy_const_min,
1211        i128_legacy_fn_max_value,
1212        i128_legacy_fn_min_value,
1213        i128_legacy_mod,
1214        i128_type,
1215        ident,
1216        if_let,
1217        if_let_guard,
1218        if_let_rescope,
1219        if_while_or_patterns,
1220        ignore,
1221        immediate_abort: "immediate-abort",
1222        impl_header_lifetime_elision,
1223        impl_lint_pass,
1224        impl_trait_in_assoc_type,
1225        impl_trait_in_bindings,
1226        impl_trait_in_fn_trait_return,
1227        impl_trait_projections,
1228        implement_via_object,
1229        implied_by,
1230        import,
1231        import_name_type,
1232        import_shadowing,
1233        import_trait_associated_functions,
1234        imported_main,
1235        in_band_lifetimes,
1236        include,
1237        include_bytes,
1238        include_bytes_macro,
1239        include_str,
1240        include_str_macro,
1241        inclusive_range_syntax,
1242        index,
1243        index_mut,
1244        infer_outlives_requirements,
1245        infer_static_outlives_requirements,
1246        inherent_associated_types,
1247        inherit,
1248        initial,
1249        inlateout,
1250        inline,
1251        inline_const,
1252        inline_const_pat,
1253        inout,
1254        instant_now,
1255        instruction_set,
1256        integer_: "integer", // underscore to avoid clashing with the function `sym::integer` below
1257        integral,
1258        internal,
1259        internal_features,
1260        into_async_iter_into_iter,
1261        into_future,
1262        into_iter,
1263        into_try_type,
1264        intra_doc_pointers,
1265        intrinsics,
1266        intrinsics_unaligned_volatile_load,
1267        intrinsics_unaligned_volatile_store,
1268        io_error_new,
1269        io_errorkind,
1270        io_stderr,
1271        io_stdout,
1272        irrefutable_let_patterns,
1273        is,
1274        is_val_statically_known,
1275        isa_attribute,
1276        isize,
1277        isize_legacy_const_max,
1278        isize_legacy_const_min,
1279        isize_legacy_fn_max_value,
1280        isize_legacy_fn_min_value,
1281        isize_legacy_mod,
1282        issue,
1283        issue_5723_bootstrap,
1284        issue_tracker_base_url,
1285        item,
1286        item_like_imports,
1287        iter,
1288        iter_cloned,
1289        iter_copied,
1290        iter_filter,
1291        iter_mut,
1292        iter_repeat,
1293        iterator,
1294        iterator_collect_fn,
1295        kcfi,
1296        kernel_address,
1297        keylocker_x86,
1298        keyword,
1299        kind,
1300        kreg,
1301        kreg0,
1302        label,
1303        label_break_value,
1304        lahfsahf_target_feature,
1305        lang,
1306        lang_items,
1307        large_assignments,
1308        last,
1309        lateout,
1310        lazy_normalization_consts,
1311        lazy_type_alias,
1312        le,
1313        legacy_receiver,
1314        len,
1315        let_chains,
1316        let_else,
1317        lhs,
1318        lib,
1319        libc,
1320        lifetime,
1321        lifetime_capture_rules_2024,
1322        lifetimes,
1323        likely,
1324        line,
1325        link,
1326        link_arg_attribute,
1327        link_args,
1328        link_cfg,
1329        link_dash_arg: "link-arg",
1330        link_llvm_intrinsics,
1331        link_name,
1332        link_ordinal,
1333        link_section,
1334        linkage,
1335        linker,
1336        linker_messages,
1337        linkonce,
1338        linkonce_odr,
1339        lint_reasons,
1340        literal,
1341        load,
1342        loaded_from_disk,
1343        local,
1344        local_inner_macros,
1345        log2f16,
1346        log2f32,
1347        log2f64,
1348        log2f128,
1349        log10f16,
1350        log10f32,
1351        log10f64,
1352        log10f128,
1353        log_syntax,
1354        logf16,
1355        logf32,
1356        logf64,
1357        logf128,
1358        loongarch32,
1359        loongarch64,
1360        loongarch_target_feature,
1361        loop_break_value,
1362        loop_match,
1363        lr,
1364        lt,
1365        m68k,
1366        m68k_target_feature,
1367        macro_at_most_once_rep,
1368        macro_attr,
1369        macro_attributes_in_derive_output,
1370        macro_concat,
1371        macro_derive,
1372        macro_escape,
1373        macro_export,
1374        macro_lifetime_matcher,
1375        macro_literal_matcher,
1376        macro_metavar_expr,
1377        macro_metavar_expr_concat,
1378        macro_reexport,
1379        macro_use,
1380        macro_vis_matcher,
1381        macros_in_extern,
1382        main,
1383        managed_boxes,
1384        manually_drop,
1385        map,
1386        map_err,
1387        marker,
1388        marker_trait_attr,
1389        masked,
1390        match_beginning_vert,
1391        match_default_bindings,
1392        matches_macro,
1393        maximumf16,
1394        maximumf32,
1395        maximumf64,
1396        maximumf128,
1397        maxnumf16,
1398        maxnumf32,
1399        maxnumf64,
1400        maxnumf128,
1401        may_dangle,
1402        may_unwind,
1403        maybe_uninit,
1404        maybe_uninit_uninit,
1405        maybe_uninit_zeroed,
1406        mem_align_const,
1407        mem_align_of,
1408        mem_discriminant,
1409        mem_drop,
1410        mem_forget,
1411        mem_replace,
1412        mem_size_const,
1413        mem_size_of,
1414        mem_size_of_val,
1415        mem_swap,
1416        mem_uninitialized,
1417        mem_variant_count,
1418        mem_zeroed,
1419        member_constraints,
1420        memory,
1421        memtag,
1422        message,
1423        meta,
1424        meta_sized,
1425        metadata_type,
1426        min_const_fn,
1427        min_const_generics,
1428        min_const_unsafe_fn,
1429        min_exhaustive_patterns,
1430        min_generic_const_args,
1431        min_specialization,
1432        min_type_alias_impl_trait,
1433        minimumf16,
1434        minimumf32,
1435        minimumf64,
1436        minimumf128,
1437        minnumf16,
1438        minnumf32,
1439        minnumf64,
1440        minnumf128,
1441        mips,
1442        mips32r6,
1443        mips64,
1444        mips64r6,
1445        mips_target_feature,
1446        mir_assume,
1447        mir_basic_block,
1448        mir_call,
1449        mir_cast_ptr_to_ptr,
1450        mir_cast_transmute,
1451        mir_cast_unsize,
1452        mir_checked,
1453        mir_debuginfo,
1454        mir_deinit,
1455        mir_discriminant,
1456        mir_drop,
1457        mir_field,
1458        mir_goto,
1459        mir_len,
1460        mir_make_place,
1461        mir_move,
1462        mir_offset,
1463        mir_ptr_metadata,
1464        mir_retag,
1465        mir_return,
1466        mir_return_to,
1467        mir_set_discriminant,
1468        mir_static,
1469        mir_static_mut,
1470        mir_storage_dead,
1471        mir_storage_live,
1472        mir_tail_call,
1473        mir_unreachable,
1474        mir_unwind_cleanup,
1475        mir_unwind_continue,
1476        mir_unwind_resume,
1477        mir_unwind_terminate,
1478        mir_unwind_terminate_reason,
1479        mir_unwind_unreachable,
1480        mir_variant,
1481        miri,
1482        mmx_reg,
1483        modifiers,
1484        module,
1485        module_path,
1486        more_maybe_bounds,
1487        more_qualified_paths,
1488        more_struct_aliases,
1489        movbe_target_feature,
1490        move_ref_pattern,
1491        move_size_limit,
1492        movrs_target_feature,
1493        msp430,
1494        mul,
1495        mul_assign,
1496        mul_with_overflow,
1497        multiple_supertrait_upcastable,
1498        must_not_suspend,
1499        must_use,
1500        mut_preserve_binding_mode_2024,
1501        mut_ref,
1502        naked,
1503        naked_asm,
1504        naked_functions,
1505        naked_functions_rustic_abi,
1506        naked_functions_target_feature,
1507        name,
1508        names,
1509        native_link_modifiers,
1510        native_link_modifiers_as_needed,
1511        native_link_modifiers_bundle,
1512        native_link_modifiers_verbatim,
1513        native_link_modifiers_whole_archive,
1514        natvis_file,
1515        ne,
1516        needs_allocator,
1517        needs_drop,
1518        needs_panic_runtime,
1519        neg,
1520        negate_unsigned,
1521        negative_bounds,
1522        negative_impls,
1523        neon,
1524        nested,
1525        never,
1526        never_patterns,
1527        never_type,
1528        never_type_fallback,
1529        new,
1530        new_binary,
1531        new_const,
1532        new_debug,
1533        new_debug_noop,
1534        new_display,
1535        new_lower_exp,
1536        new_lower_hex,
1537        new_octal,
1538        new_pointer,
1539        new_range,
1540        new_unchecked,
1541        new_upper_exp,
1542        new_upper_hex,
1543        new_v1,
1544        new_v1_formatted,
1545        next,
1546        niko,
1547        nll,
1548        no,
1549        no_builtins,
1550        no_core,
1551        no_coverage,
1552        no_crate_inject,
1553        no_debug,
1554        no_default_passes,
1555        no_implicit_prelude,
1556        no_inline,
1557        no_link,
1558        no_main,
1559        no_mangle,
1560        no_sanitize,
1561        no_stack_check,
1562        no_std,
1563        nomem,
1564        non_ascii_idents,
1565        non_exhaustive,
1566        non_exhaustive_omitted_patterns_lint,
1567        non_lifetime_binders,
1568        non_modrs_mods,
1569        nonblocking,
1570        none,
1571        nontemporal_store,
1572        noop_method_borrow,
1573        noop_method_clone,
1574        noop_method_deref,
1575        noprefix,
1576        noreturn,
1577        nostack,
1578        not,
1579        notable_trait,
1580        note,
1581        null,
1582        nvptx64,
1583        nvptx_target_feature,
1584        object_safe_for_dispatch,
1585        of,
1586        off,
1587        offset,
1588        offset_of,
1589        offset_of_enum,
1590        offset_of_nested,
1591        offset_of_slice,
1592        ok_or_else,
1593        old_name,
1594        omit_gdb_pretty_printer_section,
1595        on,
1596        on_unimplemented,
1597        opaque,
1598        opaque_module_name_placeholder: "<opaque>",
1599        open_options_new,
1600        ops,
1601        opt_out_copy,
1602        optimize,
1603        optimize_attribute,
1604        optimized,
1605        optin_builtin_traits,
1606        option,
1607        option_env,
1608        option_expect,
1609        option_unwrap,
1610        options,
1611        or,
1612        or_patterns,
1613        ord_cmp_method,
1614        os_str_to_os_string,
1615        os_string_as_os_str,
1616        other,
1617        out,
1618        overflow_checks,
1619        overlapping_marker_traits,
1620        owned_box,
1621        packed,
1622        packed_bundled_libs,
1623        panic,
1624        panic_2015,
1625        panic_2021,
1626        panic_abort,
1627        panic_any,
1628        panic_bounds_check,
1629        panic_cannot_unwind,
1630        panic_const_add_overflow,
1631        panic_const_async_fn_resumed,
1632        panic_const_async_fn_resumed_drop,
1633        panic_const_async_fn_resumed_panic,
1634        panic_const_async_gen_fn_resumed,
1635        panic_const_async_gen_fn_resumed_drop,
1636        panic_const_async_gen_fn_resumed_panic,
1637        panic_const_coroutine_resumed,
1638        panic_const_coroutine_resumed_drop,
1639        panic_const_coroutine_resumed_panic,
1640        panic_const_div_by_zero,
1641        panic_const_div_overflow,
1642        panic_const_gen_fn_none,
1643        panic_const_gen_fn_none_drop,
1644        panic_const_gen_fn_none_panic,
1645        panic_const_mul_overflow,
1646        panic_const_neg_overflow,
1647        panic_const_rem_by_zero,
1648        panic_const_rem_overflow,
1649        panic_const_shl_overflow,
1650        panic_const_shr_overflow,
1651        panic_const_sub_overflow,
1652        panic_display,
1653        panic_fmt,
1654        panic_handler,
1655        panic_impl,
1656        panic_implementation,
1657        panic_in_cleanup,
1658        panic_info,
1659        panic_invalid_enum_construction,
1660        panic_location,
1661        panic_misaligned_pointer_dereference,
1662        panic_nounwind,
1663        panic_null_pointer_dereference,
1664        panic_runtime,
1665        panic_str_2015,
1666        panic_unwind,
1667        panicking,
1668        param_attrs,
1669        parent_label,
1670        partial_cmp,
1671        partial_ord,
1672        passes,
1673        pat,
1674        pat_param,
1675        patchable_function_entry,
1676        path,
1677        path_main_separator,
1678        path_to_pathbuf,
1679        pathbuf_as_path,
1680        pattern_complexity_limit,
1681        pattern_parentheses,
1682        pattern_type,
1683        pattern_type_range_trait,
1684        pattern_types,
1685        permissions_from_mode,
1686        phantom_data,
1687        phase,
1688        pic,
1689        pie,
1690        pin,
1691        pin_ergonomics,
1692        pin_macro,
1693        pin_v2,
1694        platform_intrinsics,
1695        plugin,
1696        plugin_registrar,
1697        plugins,
1698        pointee,
1699        pointee_sized,
1700        pointee_trait,
1701        pointer,
1702        poll,
1703        poll_next,
1704        position,
1705        post_cleanup: "post-cleanup",
1706        post_dash_lto: "post-lto",
1707        postfix_match,
1708        powerpc,
1709        powerpc64,
1710        powerpc64le,
1711        powerpc_target_feature,
1712        powf16,
1713        powf32,
1714        powf64,
1715        powf128,
1716        powif16,
1717        powif32,
1718        powif64,
1719        powif128,
1720        pre_dash_lto: "pre-lto",
1721        precise_capturing,
1722        precise_capturing_in_traits,
1723        precise_pointer_size_matching,
1724        precision,
1725        pref_align_of,
1726        prefetch_read_data,
1727        prefetch_read_instruction,
1728        prefetch_write_data,
1729        prefetch_write_instruction,
1730        prefix_nops,
1731        preg,
1732        prelude,
1733        prelude_import,
1734        preserves_flags,
1735        prfchw_target_feature,
1736        print_macro,
1737        println_macro,
1738        proc_dash_macro: "proc-macro",
1739        proc_macro,
1740        proc_macro_attribute,
1741        proc_macro_derive,
1742        proc_macro_expr,
1743        proc_macro_gen,
1744        proc_macro_hygiene,
1745        proc_macro_internals,
1746        proc_macro_mod,
1747        proc_macro_non_items,
1748        proc_macro_path_invoc,
1749        process_abort,
1750        process_exit,
1751        profiler_builtins,
1752        profiler_runtime,
1753        ptr,
1754        ptr_cast,
1755        ptr_cast_const,
1756        ptr_cast_mut,
1757        ptr_const_is_null,
1758        ptr_copy,
1759        ptr_copy_nonoverlapping,
1760        ptr_eq,
1761        ptr_from_ref,
1762        ptr_guaranteed_cmp,
1763        ptr_is_null,
1764        ptr_mask,
1765        ptr_metadata,
1766        ptr_null,
1767        ptr_null_mut,
1768        ptr_offset_from,
1769        ptr_offset_from_unsigned,
1770        ptr_read,
1771        ptr_read_unaligned,
1772        ptr_read_volatile,
1773        ptr_replace,
1774        ptr_slice_from_raw_parts,
1775        ptr_slice_from_raw_parts_mut,
1776        ptr_swap,
1777        ptr_swap_nonoverlapping,
1778        ptr_write,
1779        ptr_write_bytes,
1780        ptr_write_unaligned,
1781        ptr_write_volatile,
1782        pub_macro_rules,
1783        pub_restricted,
1784        public,
1785        pure,
1786        pushpop_unsafe,
1787        qreg,
1788        qreg_low4,
1789        qreg_low8,
1790        quad_precision_float,
1791        question_mark,
1792        quote,
1793        range_inclusive_new,
1794        range_step,
1795        raw_dash_dylib: "raw-dylib",
1796        raw_dylib,
1797        raw_dylib_elf,
1798        raw_eq,
1799        raw_identifiers,
1800        raw_ref_op,
1801        re_rebalance_coherence,
1802        read_enum,
1803        read_enum_variant,
1804        read_enum_variant_arg,
1805        read_struct,
1806        read_struct_field,
1807        read_via_copy,
1808        readonly,
1809        realloc,
1810        realtime,
1811        reason,
1812        reborrow,
1813        receiver,
1814        receiver_target,
1815        recursion_limit,
1816        reexport_test_harness_main,
1817        ref_pat_eat_one_layer_2024,
1818        ref_pat_eat_one_layer_2024_structural,
1819        ref_pat_everywhere,
1820        ref_unwind_safe_trait,
1821        reference,
1822        reflect,
1823        reg,
1824        reg16,
1825        reg32,
1826        reg64,
1827        reg_abcd,
1828        reg_addr,
1829        reg_byte,
1830        reg_data,
1831        reg_iw,
1832        reg_nonzero,
1833        reg_pair,
1834        reg_ptr,
1835        reg_upper,
1836        register_attr,
1837        register_tool,
1838        relaxed_adts,
1839        relaxed_struct_unsize,
1840        relocation_model,
1841        rem,
1842        rem_assign,
1843        repr,
1844        repr128,
1845        repr_align,
1846        repr_align_enum,
1847        repr_packed,
1848        repr_simd,
1849        repr_transparent,
1850        require,
1851        reserve_x18: "reserve-x18",
1852        residual,
1853        result,
1854        result_ffi_guarantees,
1855        result_ok_method,
1856        resume,
1857        return_position_impl_trait_in_trait,
1858        return_type_notation,
1859        riscv32,
1860        riscv64,
1861        riscv_target_feature,
1862        rlib,
1863        ropi,
1864        ropi_rwpi: "ropi-rwpi",
1865        rotate_left,
1866        rotate_right,
1867        round_ties_even_f16,
1868        round_ties_even_f32,
1869        round_ties_even_f64,
1870        round_ties_even_f128,
1871        roundf16,
1872        roundf32,
1873        roundf64,
1874        roundf128,
1875        rt,
1876        rtm_target_feature,
1877        runtime,
1878        rust,
1879        rust_2015,
1880        rust_2018,
1881        rust_2018_preview,
1882        rust_2021,
1883        rust_2024,
1884        rust_analyzer,
1885        rust_begin_unwind,
1886        rust_cold_cc,
1887        rust_eh_catch_typeinfo,
1888        rust_eh_personality,
1889        rust_future,
1890        rust_logo,
1891        rust_out,
1892        rustc,
1893        rustc_abi,
1894        // FIXME(#82232, #143834): temporary name to mitigate `#[align]` nameres ambiguity
1895        rustc_align,
1896        rustc_align_static,
1897        rustc_allocator,
1898        rustc_allocator_zeroed,
1899        rustc_allocator_zeroed_variant,
1900        rustc_allow_const_fn_unstable,
1901        rustc_allow_incoherent_impl,
1902        rustc_allowed_through_unstable_modules,
1903        rustc_as_ptr,
1904        rustc_attrs,
1905        rustc_autodiff,
1906        rustc_builtin_macro,
1907        rustc_capture_analysis,
1908        rustc_clean,
1909        rustc_coherence_is_core,
1910        rustc_coinductive,
1911        rustc_confusables,
1912        rustc_const_stable,
1913        rustc_const_stable_indirect,
1914        rustc_const_unstable,
1915        rustc_conversion_suggestion,
1916        rustc_deallocator,
1917        rustc_def_path,
1918        rustc_default_body_unstable,
1919        rustc_delayed_bug_from_inside_query,
1920        rustc_deny_explicit_impl,
1921        rustc_deprecated_safe_2024,
1922        rustc_diagnostic_item,
1923        rustc_diagnostic_macros,
1924        rustc_dirty,
1925        rustc_do_not_const_check,
1926        rustc_do_not_implement_via_object,
1927        rustc_doc_primitive,
1928        rustc_driver,
1929        rustc_dummy,
1930        rustc_dump_def_parents,
1931        rustc_dump_item_bounds,
1932        rustc_dump_predicates,
1933        rustc_dump_user_args,
1934        rustc_dump_vtable,
1935        rustc_effective_visibility,
1936        rustc_evaluate_where_clauses,
1937        rustc_expected_cgu_reuse,
1938        rustc_force_inline,
1939        rustc_has_incoherent_inherent_impls,
1940        rustc_hidden_type_of_opaques,
1941        rustc_if_this_changed,
1942        rustc_inherit_overflow_checks,
1943        rustc_insignificant_dtor,
1944        rustc_intrinsic,
1945        rustc_intrinsic_const_stable_indirect,
1946        rustc_layout,
1947        rustc_layout_scalar_valid_range_end,
1948        rustc_layout_scalar_valid_range_start,
1949        rustc_legacy_const_generics,
1950        rustc_lint_diagnostics,
1951        rustc_lint_opt_deny_field_access,
1952        rustc_lint_opt_ty,
1953        rustc_lint_query_instability,
1954        rustc_lint_untracked_query_information,
1955        rustc_macro_transparency,
1956        rustc_main,
1957        rustc_mir,
1958        rustc_must_implement_one_of,
1959        rustc_never_returns_null_ptr,
1960        rustc_never_type_options,
1961        rustc_no_implicit_autorefs,
1962        rustc_no_implicit_bounds,
1963        rustc_no_mir_inline,
1964        rustc_nonnull_optimization_guaranteed,
1965        rustc_nounwind,
1966        rustc_objc_class,
1967        rustc_objc_selector,
1968        rustc_object_lifetime_default,
1969        rustc_on_unimplemented,
1970        rustc_outlives,
1971        rustc_paren_sugar,
1972        rustc_partition_codegened,
1973        rustc_partition_reused,
1974        rustc_pass_by_value,
1975        rustc_pass_indirectly_in_non_rustic_abis,
1976        rustc_peek,
1977        rustc_peek_liveness,
1978        rustc_peek_maybe_init,
1979        rustc_peek_maybe_uninit,
1980        rustc_preserve_ub_checks,
1981        rustc_private,
1982        rustc_proc_macro_decls,
1983        rustc_promotable,
1984        rustc_pub_transparent,
1985        rustc_reallocator,
1986        rustc_regions,
1987        rustc_reservation_impl,
1988        rustc_serialize,
1989        rustc_should_not_be_called_on_const_items,
1990        rustc_simd_monomorphize_lane_limit,
1991        rustc_skip_during_method_dispatch,
1992        rustc_specialization_trait,
1993        rustc_std_internal_symbol,
1994        rustc_strict_coherence,
1995        rustc_symbol_name,
1996        rustc_test_marker,
1997        rustc_then_this_would_need,
1998        rustc_trivial_field_reads,
1999        rustc_unsafe_specialization_marker,
2000        rustc_variance,
2001        rustc_variance_of_opaques,
2002        rustdoc,
2003        rustdoc_internals,
2004        rustdoc_missing_doc_code_examples,
2005        rustfmt,
2006        rvalue_static_promotion,
2007        rwpi,
2008        s,
2009        s390x,
2010        s390x_target_feature,
2011        s390x_target_feature_vector,
2012        safety,
2013        sanitize,
2014        sanitizer_cfi_generalize_pointers,
2015        sanitizer_cfi_normalize_integers,
2016        sanitizer_runtime,
2017        saturating_add,
2018        saturating_div,
2019        saturating_sub,
2020        sdylib,
2021        search_unbox,
2022        select_unpredictable,
2023        self_in_typedefs,
2024        self_struct_ctor,
2025        semiopaque,
2026        semitransparent,
2027        sha2,
2028        sha3,
2029        sha512_sm_x86,
2030        shadow_call_stack,
2031        shallow,
2032        shl,
2033        shl_assign,
2034        shorter_tail_lifetimes,
2035        should_panic,
2036        show,
2037        shr,
2038        shr_assign,
2039        sig_dfl,
2040        sig_ign,
2041        simd,
2042        simd_add,
2043        simd_and,
2044        simd_arith_offset,
2045        simd_as,
2046        simd_bitmask,
2047        simd_bitreverse,
2048        simd_bswap,
2049        simd_cast,
2050        simd_cast_ptr,
2051        simd_ceil,
2052        simd_ctlz,
2053        simd_ctpop,
2054        simd_cttz,
2055        simd_div,
2056        simd_eq,
2057        simd_expose_provenance,
2058        simd_extract,
2059        simd_extract_dyn,
2060        simd_fabs,
2061        simd_fcos,
2062        simd_fexp,
2063        simd_fexp2,
2064        simd_ffi,
2065        simd_flog,
2066        simd_flog2,
2067        simd_flog10,
2068        simd_floor,
2069        simd_fma,
2070        simd_fmax,
2071        simd_fmin,
2072        simd_fsin,
2073        simd_fsqrt,
2074        simd_funnel_shl,
2075        simd_funnel_shr,
2076        simd_gather,
2077        simd_ge,
2078        simd_gt,
2079        simd_insert,
2080        simd_insert_dyn,
2081        simd_le,
2082        simd_lt,
2083        simd_masked_load,
2084        simd_masked_store,
2085        simd_mul,
2086        simd_ne,
2087        simd_neg,
2088        simd_or,
2089        simd_reduce_add_ordered,
2090        simd_reduce_add_unordered,
2091        simd_reduce_all,
2092        simd_reduce_and,
2093        simd_reduce_any,
2094        simd_reduce_max,
2095        simd_reduce_min,
2096        simd_reduce_mul_ordered,
2097        simd_reduce_mul_unordered,
2098        simd_reduce_or,
2099        simd_reduce_xor,
2100        simd_relaxed_fma,
2101        simd_rem,
2102        simd_round,
2103        simd_round_ties_even,
2104        simd_saturating_add,
2105        simd_saturating_sub,
2106        simd_scatter,
2107        simd_select,
2108        simd_select_bitmask,
2109        simd_shl,
2110        simd_shr,
2111        simd_shuffle,
2112        simd_shuffle_const_generic,
2113        simd_sub,
2114        simd_trunc,
2115        simd_with_exposed_provenance,
2116        simd_xor,
2117        since,
2118        sinf16,
2119        sinf32,
2120        sinf64,
2121        sinf128,
2122        size,
2123        size_of,
2124        size_of_val,
2125        sized,
2126        sized_hierarchy,
2127        skip,
2128        slice,
2129        slice_from_raw_parts,
2130        slice_from_raw_parts_mut,
2131        slice_from_ref,
2132        slice_get_unchecked,
2133        slice_into_vec,
2134        slice_iter,
2135        slice_len_fn,
2136        slice_patterns,
2137        slicing_syntax,
2138        soft,
2139        sparc,
2140        sparc64,
2141        sparc_target_feature,
2142        specialization,
2143        speed,
2144        spirv,
2145        spotlight,
2146        sqrtf16,
2147        sqrtf32,
2148        sqrtf64,
2149        sqrtf128,
2150        sreg,
2151        sreg_low16,
2152        sse,
2153        sse2,
2154        sse4a_target_feature,
2155        stable,
2156        staged_api,
2157        start,
2158        state,
2159        static_align,
2160        static_in_const,
2161        static_nobundle,
2162        static_recursion,
2163        staticlib,
2164        std,
2165        std_lib_injection,
2166        std_panic,
2167        std_panic_2015_macro,
2168        std_panic_macro,
2169        stmt,
2170        stmt_expr_attributes,
2171        stop_after_dataflow,
2172        store,
2173        str,
2174        str_chars,
2175        str_ends_with,
2176        str_from_utf8,
2177        str_from_utf8_mut,
2178        str_from_utf8_unchecked,
2179        str_from_utf8_unchecked_mut,
2180        str_inherent_from_utf8,
2181        str_inherent_from_utf8_mut,
2182        str_inherent_from_utf8_unchecked,
2183        str_inherent_from_utf8_unchecked_mut,
2184        str_len,
2185        str_split_whitespace,
2186        str_starts_with,
2187        str_trim,
2188        str_trim_end,
2189        str_trim_start,
2190        strict_provenance_lints,
2191        string_as_mut_str,
2192        string_as_str,
2193        string_deref_patterns,
2194        string_from_utf8,
2195        string_insert_str,
2196        string_new,
2197        string_push_str,
2198        stringify,
2199        struct_field_attributes,
2200        struct_inherit,
2201        struct_variant,
2202        structural_match,
2203        structural_peq,
2204        sub,
2205        sub_assign,
2206        sub_with_overflow,
2207        suggestion,
2208        super_let,
2209        supertrait_item_shadowing,
2210        sym,
2211        sync,
2212        synthetic,
2213        sys_mutex_lock,
2214        sys_mutex_try_lock,
2215        sys_mutex_unlock,
2216        t32,
2217        target,
2218        target_abi,
2219        target_arch,
2220        target_endian,
2221        target_env,
2222        target_family,
2223        target_feature,
2224        target_feature_11,
2225        target_feature_inline_always,
2226        target_has_atomic,
2227        target_has_atomic_equal_alignment,
2228        target_has_atomic_load_store,
2229        target_has_reliable_f16,
2230        target_has_reliable_f16_math,
2231        target_has_reliable_f128,
2232        target_has_reliable_f128_math,
2233        target_os,
2234        target_pointer_width,
2235        target_thread_local,
2236        target_vendor,
2237        tbm_target_feature,
2238        termination,
2239        termination_trait,
2240        termination_trait_test,
2241        test,
2242        test_2018_feature,
2243        test_accepted_feature,
2244        test_case,
2245        test_removed_feature,
2246        test_runner,
2247        test_unstable_lint,
2248        thread,
2249        thread_local,
2250        thread_local_macro,
2251        three_way_compare,
2252        thumb2,
2253        thumb_mode: "thumb-mode",
2254        tmm_reg,
2255        to_owned_method,
2256        to_string,
2257        to_string_method,
2258        to_vec,
2259        todo_macro,
2260        tool_attributes,
2261        tool_lints,
2262        trace_macros,
2263        track_caller,
2264        trait_alias,
2265        trait_upcasting,
2266        transmute,
2267        transmute_generic_consts,
2268        transmute_opts,
2269        transmute_trait,
2270        transmute_unchecked,
2271        transparent,
2272        transparent_enums,
2273        transparent_unions,
2274        trivial_bounds,
2275        trivial_clone,
2276        truncf16,
2277        truncf32,
2278        truncf64,
2279        truncf128,
2280        try_blocks,
2281        try_capture,
2282        try_from,
2283        try_from_fn,
2284        try_into,
2285        try_trait_v2,
2286        try_trait_v2_residual,
2287        try_update,
2288        tt,
2289        tuple,
2290        tuple_indexing,
2291        tuple_trait,
2292        two_phase,
2293        ty,
2294        type_alias_enum_variants,
2295        type_alias_impl_trait,
2296        type_ascribe,
2297        type_ascription,
2298        type_changing_struct_update,
2299        type_const,
2300        type_id,
2301        type_id_eq,
2302        type_ir,
2303        type_ir_infer_ctxt_like,
2304        type_ir_inherent,
2305        type_ir_interner,
2306        type_length_limit,
2307        type_macros,
2308        type_name,
2309        type_privacy_lints,
2310        typed_swap_nonoverlapping,
2311        u8,
2312        u8_legacy_const_max,
2313        u8_legacy_const_min,
2314        u8_legacy_fn_max_value,
2315        u8_legacy_fn_min_value,
2316        u8_legacy_mod,
2317        u16,
2318        u16_legacy_const_max,
2319        u16_legacy_const_min,
2320        u16_legacy_fn_max_value,
2321        u16_legacy_fn_min_value,
2322        u16_legacy_mod,
2323        u32,
2324        u32_legacy_const_max,
2325        u32_legacy_const_min,
2326        u32_legacy_fn_max_value,
2327        u32_legacy_fn_min_value,
2328        u32_legacy_mod,
2329        u64,
2330        u64_legacy_const_max,
2331        u64_legacy_const_min,
2332        u64_legacy_fn_max_value,
2333        u64_legacy_fn_min_value,
2334        u64_legacy_mod,
2335        u128,
2336        u128_legacy_const_max,
2337        u128_legacy_const_min,
2338        u128_legacy_fn_max_value,
2339        u128_legacy_fn_min_value,
2340        u128_legacy_mod,
2341        ub_checks,
2342        unaligned_volatile_load,
2343        unaligned_volatile_store,
2344        unboxed_closures,
2345        unchecked_add,
2346        unchecked_div,
2347        unchecked_funnel_shl,
2348        unchecked_funnel_shr,
2349        unchecked_mul,
2350        unchecked_rem,
2351        unchecked_shl,
2352        unchecked_shr,
2353        unchecked_sub,
2354        undecorated,
2355        underscore_const_names,
2356        underscore_imports,
2357        underscore_lifetimes,
2358        uniform_paths,
2359        unimplemented_macro,
2360        unit,
2361        universal_impl_trait,
2362        unix,
2363        unlikely,
2364        unmarked_api,
2365        unnamed_fields,
2366        unpin,
2367        unqualified_local_imports,
2368        unreachable,
2369        unreachable_2015,
2370        unreachable_2015_macro,
2371        unreachable_2021,
2372        unreachable_code,
2373        unreachable_display,
2374        unreachable_macro,
2375        unrestricted_attribute_tokens,
2376        unsafe_attributes,
2377        unsafe_binders,
2378        unsafe_block_in_unsafe_fn,
2379        unsafe_cell,
2380        unsafe_cell_raw_get,
2381        unsafe_extern_blocks,
2382        unsafe_fields,
2383        unsafe_no_drop_flag,
2384        unsafe_pinned,
2385        unsafe_unpin,
2386        unsize,
2387        unsized_const_param_ty,
2388        unsized_const_params,
2389        unsized_fn_params,
2390        unsized_locals,
2391        unsized_tuple_coercion,
2392        unstable,
2393        unstable_feature_bound,
2394        unstable_location_reason_default: "this crate is being loaded from the sysroot, an \
2395                          unstable location; did you mean to load this crate \
2396                          from crates.io via `Cargo.toml` instead?",
2397        untagged_unions,
2398        unused_imports,
2399        unwind,
2400        unwind_attributes,
2401        unwind_safe_trait,
2402        unwrap,
2403        unwrap_binder,
2404        unwrap_or,
2405        update,
2406        use_cloned,
2407        use_extern_macros,
2408        use_nested_groups,
2409        used,
2410        used_with_arg,
2411        using,
2412        usize,
2413        usize_legacy_const_max,
2414        usize_legacy_const_min,
2415        usize_legacy_fn_max_value,
2416        usize_legacy_fn_min_value,
2417        usize_legacy_mod,
2418        v1,
2419        v8plus,
2420        va_arg,
2421        va_copy,
2422        va_end,
2423        va_list,
2424        va_start,
2425        val,
2426        validity,
2427        value,
2428        values,
2429        var,
2430        variant_count,
2431        vec,
2432        vec_as_mut_slice,
2433        vec_as_slice,
2434        vec_from_elem,
2435        vec_is_empty,
2436        vec_macro,
2437        vec_new,
2438        vec_pop,
2439        vec_reserve,
2440        vec_with_capacity,
2441        vecdeque_iter,
2442        vecdeque_reserve,
2443        vector,
2444        verbatim,
2445        version,
2446        vfp2,
2447        vis,
2448        visible_private_types,
2449        volatile,
2450        volatile_copy_memory,
2451        volatile_copy_nonoverlapping_memory,
2452        volatile_load,
2453        volatile_set_memory,
2454        volatile_store,
2455        vreg,
2456        vreg_low16,
2457        vsreg,
2458        vsx,
2459        vtable_align,
2460        vtable_size,
2461        warn,
2462        wasip2,
2463        wasm32,
2464        wasm64,
2465        wasm_abi,
2466        wasm_import_module,
2467        wasm_target_feature,
2468        weak,
2469        weak_odr,
2470        where_clause_attrs,
2471        while_let,
2472        whole_dash_archive: "whole-archive",
2473        width,
2474        windows,
2475        windows_subsystem,
2476        with_negative_coherence,
2477        wrap_binder,
2478        wrapping_add,
2479        wrapping_div,
2480        wrapping_mul,
2481        wrapping_rem,
2482        wrapping_rem_euclid,
2483        wrapping_sub,
2484        wreg,
2485        write_bytes,
2486        write_fmt,
2487        write_macro,
2488        write_str,
2489        write_via_move,
2490        writeln_macro,
2491        x86,
2492        x86_64,
2493        x86_amx_intrinsics,
2494        x87_reg,
2495        x87_target_feature,
2496        xer,
2497        xmm_reg,
2498        xop_target_feature,
2499        xtensa,
2500        yeet_desugar_details,
2501        yeet_expr,
2502        yes,
2503        yield_expr,
2504        ymm_reg,
2505        yreg,
2506        zca,
2507        zfh,
2508        zfhmin,
2509        zmm_reg,
2510        ztso,
2511        // tidy-alphabetical-end
2512    }
2513}
2514
2515/// Symbols for crates that are part of the stable standard library: `std`, `core`, `alloc`, and
2516/// `proc_macro`.
2517pub const STDLIB_STABLE_CRATES: &[Symbol] = &[sym::std, sym::core, sym::alloc, sym::proc_macro];
2518
2519#[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
2520pub struct Ident {
2521    /// `name` should never be the empty symbol. If you are considering that,
2522    /// you are probably conflating "empty identifier with "no identifier" and
2523    /// you should use `Option<Ident>` instead.
2524    /// Trying to construct an `Ident` with an empty name will trigger debug assertions.
2525    pub name: Symbol,
2526    pub span: Span,
2527}
2528
2529impl Ident {
2530    #[inline]
2531    /// Constructs a new identifier from a symbol and a span.
2532    pub fn new(name: Symbol, span: Span) -> Ident {
2533        debug_assert_ne!(name, sym::empty);
2534        Ident { name, span }
2535    }
2536
2537    /// Constructs a new identifier with a dummy span.
2538    #[inline]
2539    pub fn with_dummy_span(name: Symbol) -> Ident {
2540        Ident::new(name, DUMMY_SP)
2541    }
2542
2543    // For dummy identifiers that are never used and absolutely must be
2544    // present. Note that this does *not* use the empty symbol; `sym::dummy`
2545    // makes it clear that it's intended as a dummy value, and is more likely
2546    // to be detected if it accidentally does get used.
2547    #[inline]
2548    pub fn dummy() -> Ident {
2549        Ident::with_dummy_span(sym::dummy)
2550    }
2551
2552    /// Maps a string to an identifier with a dummy span.
2553    pub fn from_str(string: &str) -> Ident {
2554        Ident::with_dummy_span(Symbol::intern(string))
2555    }
2556
2557    /// Maps a string and a span to an identifier.
2558    pub fn from_str_and_span(string: &str, span: Span) -> Ident {
2559        Ident::new(Symbol::intern(string), span)
2560    }
2561
2562    /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
2563    pub fn with_span_pos(self, span: Span) -> Ident {
2564        Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
2565    }
2566
2567    /// Creates a new ident with the same span and name with leading quote removed, if any.
2568    /// Calling it on a `'` ident will return an empty ident, which triggers debug assertions.
2569    pub fn without_first_quote(self) -> Ident {
2570        self.as_str()
2571            .strip_prefix('\'')
2572            .map_or(self, |name| Ident::new(Symbol::intern(name), self.span))
2573    }
2574
2575    /// "Normalize" ident for use in comparisons using "item hygiene".
2576    /// Identifiers with same string value become same if they came from the same macro 2.0 macro
2577    /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
2578    /// different macro 2.0 macros.
2579    /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
2580    pub fn normalize_to_macros_2_0(self) -> Ident {
2581        Ident::new(self.name, self.span.normalize_to_macros_2_0())
2582    }
2583
2584    /// "Normalize" ident for use in comparisons using "local variable hygiene".
2585    /// Identifiers with same string value become same if they came from the same non-transparent
2586    /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
2587    /// non-transparent macros.
2588    /// Technically, this operation strips all transparent marks from ident's syntactic context.
2589    #[inline]
2590    pub fn normalize_to_macro_rules(self) -> Ident {
2591        Ident::new(self.name, self.span.normalize_to_macro_rules())
2592    }
2593
2594    /// Access the underlying string. This is a slowish operation because it
2595    /// requires locking the symbol interner.
2596    ///
2597    /// Note that the lifetime of the return value is a lie. See
2598    /// `Symbol::as_str()` for details.
2599    pub fn as_str(&self) -> &str {
2600        self.name.as_str()
2601    }
2602}
2603
2604impl PartialEq for Ident {
2605    #[inline]
2606    fn eq(&self, rhs: &Self) -> bool {
2607        self.name == rhs.name && self.span.eq_ctxt(rhs.span)
2608    }
2609}
2610
2611impl Hash for Ident {
2612    fn hash<H: Hasher>(&self, state: &mut H) {
2613        self.name.hash(state);
2614        self.span.ctxt().hash(state);
2615    }
2616}
2617
2618impl fmt::Debug for Ident {
2619    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2620        fmt::Display::fmt(self, f)?;
2621        fmt::Debug::fmt(&self.span.ctxt(), f)
2622    }
2623}
2624
2625/// This implementation is supposed to be used in error messages, so it's expected to be identical
2626/// to printing the original identifier token written in source code (`token_to_string`),
2627/// except that AST identifiers don't keep the rawness flag, so we have to guess it.
2628impl fmt::Display for Ident {
2629    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2630        fmt::Display::fmt(&IdentPrinter::new(self.name, self.guess_print_mode(), None), f)
2631    }
2632}
2633
2634pub enum IdentPrintMode {
2635    Normal,
2636    RawIdent,
2637    RawLifetime,
2638}
2639
2640/// The most general type to print identifiers.
2641///
2642/// AST pretty-printer is used as a fallback for turning AST structures into token streams for
2643/// proc macros. Additionally, proc macros may stringify their input and expect it survive the
2644/// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
2645/// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
2646/// hygiene data, most importantly name of the crate it refers to.
2647/// As a result we print `$crate` as `crate` if it refers to the local crate
2648/// and as `::other_crate_name` if it refers to some other crate.
2649/// Note, that this is only done if the ident token is printed from inside of AST pretty-printing,
2650/// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
2651/// so we should not perform this lossy conversion if the top level call to the pretty-printer was
2652/// done for a token stream or a single token.
2653pub struct IdentPrinter {
2654    symbol: Symbol,
2655    mode: IdentPrintMode,
2656    /// Span used for retrieving the crate name to which `$crate` refers to,
2657    /// if this field is `None` then the `$crate` conversion doesn't happen.
2658    convert_dollar_crate: Option<Span>,
2659}
2660
2661impl IdentPrinter {
2662    /// The most general `IdentPrinter` constructor. Do not use this.
2663    pub fn new(
2664        symbol: Symbol,
2665        mode: IdentPrintMode,
2666        convert_dollar_crate: Option<Span>,
2667    ) -> IdentPrinter {
2668        IdentPrinter { symbol, mode, convert_dollar_crate }
2669    }
2670
2671    /// This implementation is supposed to be used when printing identifiers
2672    /// as a part of pretty-printing for larger AST pieces.
2673    /// Do not use this either.
2674    pub fn for_ast_ident(ident: Ident, mode: IdentPrintMode) -> IdentPrinter {
2675        IdentPrinter::new(ident.name, mode, Some(ident.span))
2676    }
2677}
2678
2679impl fmt::Display for IdentPrinter {
2680    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2681        let s = match self.mode {
2682            IdentPrintMode::Normal
2683                if self.symbol == kw::DollarCrate
2684                    && let Some(span) = self.convert_dollar_crate =>
2685            {
2686                let converted = span.ctxt().dollar_crate_name();
2687                if !converted.is_path_segment_keyword() {
2688                    f.write_str("::")?;
2689                }
2690                converted
2691            }
2692            IdentPrintMode::Normal => self.symbol,
2693            IdentPrintMode::RawIdent => {
2694                f.write_str("r#")?;
2695                self.symbol
2696            }
2697            IdentPrintMode::RawLifetime => {
2698                f.write_str("'r#")?;
2699                let s = self
2700                    .symbol
2701                    .as_str()
2702                    .strip_prefix("'")
2703                    .expect("only lifetime idents should be passed with RawLifetime mode");
2704                Symbol::intern(s)
2705            }
2706        };
2707        s.fmt(f)
2708    }
2709}
2710
2711/// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
2712/// construction for "local variable hygiene" comparisons.
2713///
2714/// Use this type when you need to compare identifiers according to macro_rules hygiene.
2715/// This ensures compile-time safety and avoids manual normalization calls.
2716#[derive(Copy, Clone, Eq, PartialEq, Hash)]
2717pub struct MacroRulesNormalizedIdent(Ident);
2718
2719impl MacroRulesNormalizedIdent {
2720    #[inline]
2721    pub fn new(ident: Ident) -> Self {
2722        MacroRulesNormalizedIdent(ident.normalize_to_macro_rules())
2723    }
2724}
2725
2726impl fmt::Debug for MacroRulesNormalizedIdent {
2727    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2728        fmt::Debug::fmt(&self.0, f)
2729    }
2730}
2731
2732impl fmt::Display for MacroRulesNormalizedIdent {
2733    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2734        fmt::Display::fmt(&self.0, f)
2735    }
2736}
2737
2738/// An newtype around `Ident` that calls [Ident::normalize_to_macros_2_0] on
2739/// construction for "item hygiene" comparisons.
2740///
2741/// Identifiers with same string value become same if they came from the same macro 2.0 macro
2742/// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
2743/// different macro 2.0 macros.
2744#[derive(Copy, Clone, Eq, PartialEq, Hash)]
2745pub struct Macros20NormalizedIdent(pub Ident);
2746
2747impl Macros20NormalizedIdent {
2748    #[inline]
2749    pub fn new(ident: Ident) -> Self {
2750        Macros20NormalizedIdent(ident.normalize_to_macros_2_0())
2751    }
2752
2753    // dummy_span does not need to be normalized, so we can use `Ident` directly
2754    pub fn with_dummy_span(name: Symbol) -> Self {
2755        Macros20NormalizedIdent(Ident::with_dummy_span(name))
2756    }
2757}
2758
2759impl fmt::Debug for Macros20NormalizedIdent {
2760    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2761        fmt::Debug::fmt(&self.0, f)
2762    }
2763}
2764
2765impl fmt::Display for Macros20NormalizedIdent {
2766    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2767        fmt::Display::fmt(&self.0, f)
2768    }
2769}
2770
2771/// By impl Deref, we can access the wrapped Ident as if it were a normal Ident
2772/// such as `norm_ident.name` instead of `norm_ident.0.name`.
2773impl Deref for Macros20NormalizedIdent {
2774    type Target = Ident;
2775    fn deref(&self) -> &Self::Target {
2776        &self.0
2777    }
2778}
2779
2780/// An interned UTF-8 string.
2781///
2782/// Internally, a `Symbol` is implemented as an index, and all operations
2783/// (including hashing, equality, and ordering) operate on that index. The use
2784/// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
2785/// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
2786///
2787/// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
2788/// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
2789#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
2790pub struct Symbol(SymbolIndex);
2791
2792// Used within both `Symbol` and `ByteSymbol`.
2793rustc_index::newtype_index! {
2794    #[orderable]
2795    struct SymbolIndex {}
2796}
2797
2798impl Symbol {
2799    /// Avoid this except for things like deserialization of previously
2800    /// serialized symbols, and testing. Use `intern` instead.
2801    pub const fn new(n: u32) -> Self {
2802        Symbol(SymbolIndex::from_u32(n))
2803    }
2804
2805    /// Maps a string to its interned representation.
2806    #[rustc_diagnostic_item = "SymbolIntern"]
2807    pub fn intern(str: &str) -> Self {
2808        with_session_globals(|session_globals| session_globals.symbol_interner.intern_str(str))
2809    }
2810
2811    /// Access the underlying string. This is a slowish operation because it
2812    /// requires locking the symbol interner.
2813    ///
2814    /// Note that the lifetime of the return value is a lie. It's not the same
2815    /// as `&self`, but actually tied to the lifetime of the underlying
2816    /// interner. Interners are long-lived, and there are very few of them, and
2817    /// this function is typically used for short-lived things, so in practice
2818    /// it works out ok.
2819    pub fn as_str(&self) -> &str {
2820        with_session_globals(|session_globals| unsafe {
2821            std::mem::transmute::<&str, &str>(session_globals.symbol_interner.get_str(*self))
2822        })
2823    }
2824
2825    pub fn as_u32(self) -> u32 {
2826        self.0.as_u32()
2827    }
2828
2829    pub fn is_empty(self) -> bool {
2830        self == sym::empty
2831    }
2832
2833    /// This method is supposed to be used in error messages, so it's expected to be
2834    /// identical to printing the original identifier token written in source code
2835    /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
2836    /// or edition, so we have to guess the rawness using the global edition.
2837    pub fn to_ident_string(self) -> String {
2838        // Avoid creating an empty identifier, because that asserts in debug builds.
2839        if self == sym::empty { String::new() } else { Ident::with_dummy_span(self).to_string() }
2840    }
2841}
2842
2843impl fmt::Debug for Symbol {
2844    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2845        fmt::Debug::fmt(self.as_str(), f)
2846    }
2847}
2848
2849impl fmt::Display for Symbol {
2850    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2851        fmt::Display::fmt(self.as_str(), f)
2852    }
2853}
2854
2855impl<CTX> HashStable<CTX> for Symbol {
2856    #[inline]
2857    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
2858        self.as_str().hash_stable(hcx, hasher);
2859    }
2860}
2861
2862impl<CTX> ToStableHashKey<CTX> for Symbol {
2863    type KeyType = String;
2864    #[inline]
2865    fn to_stable_hash_key(&self, _: &CTX) -> String {
2866        self.as_str().to_string()
2867    }
2868}
2869
2870impl StableCompare for Symbol {
2871    const CAN_USE_UNSTABLE_SORT: bool = true;
2872
2873    fn stable_cmp(&self, other: &Self) -> std::cmp::Ordering {
2874        self.as_str().cmp(other.as_str())
2875    }
2876}
2877
2878/// Like `Symbol`, but for byte strings. `ByteSymbol` is used less widely, so
2879/// it has fewer operations defined than `Symbol`.
2880#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
2881pub struct ByteSymbol(SymbolIndex);
2882
2883impl ByteSymbol {
2884    /// Avoid this except for things like deserialization of previously
2885    /// serialized symbols, and testing. Use `intern` instead.
2886    pub const fn new(n: u32) -> Self {
2887        ByteSymbol(SymbolIndex::from_u32(n))
2888    }
2889
2890    /// Maps a string to its interned representation.
2891    pub fn intern(byte_str: &[u8]) -> Self {
2892        with_session_globals(|session_globals| {
2893            session_globals.symbol_interner.intern_byte_str(byte_str)
2894        })
2895    }
2896
2897    /// Like `Symbol::as_str`.
2898    pub fn as_byte_str(&self) -> &[u8] {
2899        with_session_globals(|session_globals| unsafe {
2900            std::mem::transmute::<&[u8], &[u8]>(session_globals.symbol_interner.get_byte_str(*self))
2901        })
2902    }
2903
2904    pub fn as_u32(self) -> u32 {
2905        self.0.as_u32()
2906    }
2907}
2908
2909impl fmt::Debug for ByteSymbol {
2910    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2911        fmt::Debug::fmt(self.as_byte_str(), f)
2912    }
2913}
2914
2915impl<CTX> HashStable<CTX> for ByteSymbol {
2916    #[inline]
2917    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
2918        self.as_byte_str().hash_stable(hcx, hasher);
2919    }
2920}
2921
2922// Interner used for both `Symbol`s and `ByteSymbol`s. If a string and a byte
2923// string with identical contents (e.g. "foo" and b"foo") are both interned,
2924// only one copy will be stored and the resulting `Symbol` and `ByteSymbol`
2925// will have the same index.
2926pub(crate) struct Interner(Lock<InternerInner>);
2927
2928// The `&'static [u8]`s in this type actually point into the arena.
2929//
2930// This type is private to prevent accidentally constructing more than one
2931// `Interner` on the same thread, which makes it easy to mix up `Symbol`s
2932// between `Interner`s.
2933struct InternerInner {
2934    arena: DroplessArena,
2935    byte_strs: FxIndexSet<&'static [u8]>,
2936}
2937
2938impl Interner {
2939    // These arguments are `&str`, but because of the sharing, we are
2940    // effectively pre-interning all these strings for both `Symbol` and
2941    // `ByteSymbol`.
2942    fn prefill(init: &[&'static str], extra: &[&'static str]) -> Self {
2943        let byte_strs = FxIndexSet::from_iter(
2944            init.iter().copied().chain(extra.iter().copied()).map(|str| str.as_bytes()),
2945        );
2946
2947        // The order in which duplicates are reported is irrelevant.
2948        #[expect(rustc::potential_query_instability)]
2949        if byte_strs.len() != init.len() + extra.len() {
2950            panic!(
2951                "duplicate symbols in the rustc symbol list and the extra symbols added by the driver: {:?}",
2952                FxHashSet::intersection(
2953                    &init.iter().copied().collect(),
2954                    &extra.iter().copied().collect(),
2955                )
2956                .collect::<Vec<_>>()
2957            )
2958        }
2959
2960        Interner(Lock::new(InternerInner { arena: Default::default(), byte_strs }))
2961    }
2962
2963    fn intern_str(&self, str: &str) -> Symbol {
2964        Symbol::new(self.intern_inner(str.as_bytes()))
2965    }
2966
2967    fn intern_byte_str(&self, byte_str: &[u8]) -> ByteSymbol {
2968        ByteSymbol::new(self.intern_inner(byte_str))
2969    }
2970
2971    #[inline]
2972    fn intern_inner(&self, byte_str: &[u8]) -> u32 {
2973        let mut inner = self.0.lock();
2974        if let Some(idx) = inner.byte_strs.get_index_of(byte_str) {
2975            return idx as u32;
2976        }
2977
2978        let byte_str: &[u8] = inner.arena.alloc_slice(byte_str);
2979
2980        // SAFETY: we can extend the arena allocation to `'static` because we
2981        // only access these while the arena is still alive.
2982        let byte_str: &'static [u8] = unsafe { &*(byte_str as *const [u8]) };
2983
2984        // This second hash table lookup can be avoided by using `RawEntryMut`,
2985        // but this code path isn't hot enough for it to be worth it. See
2986        // #91445 for details.
2987        let (idx, is_new) = inner.byte_strs.insert_full(byte_str);
2988        debug_assert!(is_new); // due to the get_index_of check above
2989
2990        idx as u32
2991    }
2992
2993    /// Get the symbol as a string.
2994    ///
2995    /// [`Symbol::as_str()`] should be used in preference to this function.
2996    fn get_str(&self, symbol: Symbol) -> &str {
2997        let byte_str = self.get_inner(symbol.0.as_usize());
2998        // SAFETY: known to be a UTF8 string because it's a `Symbol`.
2999        unsafe { str::from_utf8_unchecked(byte_str) }
3000    }
3001
3002    /// Get the symbol as a string.
3003    ///
3004    /// [`ByteSymbol::as_byte_str()`] should be used in preference to this function.
3005    fn get_byte_str(&self, symbol: ByteSymbol) -> &[u8] {
3006        self.get_inner(symbol.0.as_usize())
3007    }
3008
3009    fn get_inner(&self, index: usize) -> &[u8] {
3010        self.0.lock().byte_strs.get_index(index).unwrap()
3011    }
3012}
3013
3014// This module has a very short name because it's used a lot.
3015/// This module contains all the defined keyword `Symbol`s.
3016///
3017/// Given that `kw` is imported, use them like `kw::keyword_name`.
3018/// For example `kw::Loop` or `kw::Break`.
3019pub mod kw {
3020    pub use super::kw_generated::*;
3021}
3022
3023// This module has a very short name because it's used a lot.
3024/// This module contains all the defined non-keyword `Symbol`s.
3025///
3026/// Given that `sym` is imported, use them like `sym::symbol_name`.
3027/// For example `sym::rustfmt` or `sym::u8`.
3028pub mod sym {
3029    // Used from a macro in `librustc_feature/accepted.rs`
3030    use super::Symbol;
3031    pub use super::kw::MacroRules as macro_rules;
3032    #[doc(inline)]
3033    pub use super::sym_generated::*;
3034
3035    /// Get the symbol for an integer.
3036    ///
3037    /// The first few non-negative integers each have a static symbol and therefore
3038    /// are fast.
3039    pub fn integer<N: TryInto<usize> + Copy + itoa::Integer>(n: N) -> Symbol {
3040        if let Result::Ok(idx) = n.try_into() {
3041            if idx < 10 {
3042                return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
3043            }
3044        }
3045        let mut buffer = itoa::Buffer::new();
3046        let printed = buffer.format(n);
3047        Symbol::intern(printed)
3048    }
3049}
3050
3051impl Symbol {
3052    fn is_special(self) -> bool {
3053        self <= kw::Underscore
3054    }
3055
3056    fn is_used_keyword_always(self) -> bool {
3057        self >= kw::As && self <= kw::While
3058    }
3059
3060    fn is_unused_keyword_always(self) -> bool {
3061        self >= kw::Abstract && self <= kw::Yield
3062    }
3063
3064    fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
3065        (self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
3066    }
3067
3068    fn is_unused_keyword_conditional(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
3069        self == kw::Gen && edition().at_least_rust_2024()
3070            || self == kw::Try && edition().at_least_rust_2018()
3071    }
3072
3073    pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
3074        self.is_special()
3075            || self.is_used_keyword_always()
3076            || self.is_unused_keyword_always()
3077            || self.is_used_keyword_conditional(edition)
3078            || self.is_unused_keyword_conditional(edition)
3079    }
3080
3081    pub fn is_weak(self) -> bool {
3082        self >= kw::Auto && self <= kw::Yeet
3083    }
3084
3085    /// A keyword or reserved identifier that can be used as a path segment.
3086    pub fn is_path_segment_keyword(self) -> bool {
3087        self == kw::Super
3088            || self == kw::SelfLower
3089            || self == kw::SelfUpper
3090            || self == kw::Crate
3091            || self == kw::PathRoot
3092            || self == kw::DollarCrate
3093    }
3094
3095    /// Returns `true` if the symbol is `true` or `false`.
3096    pub fn is_bool_lit(self) -> bool {
3097        self == kw::True || self == kw::False
3098    }
3099
3100    /// Returns `true` if this symbol can be a raw identifier.
3101    pub fn can_be_raw(self) -> bool {
3102        self != sym::empty && self != kw::Underscore && !self.is_path_segment_keyword()
3103    }
3104
3105    /// Was this symbol index predefined in the compiler's `symbols!` macro?
3106    /// Note: this applies to both `Symbol`s and `ByteSymbol`s, which is why it
3107    /// takes a `u32` argument instead of a `&self` argument. Use with care.
3108    pub fn is_predefined(index: u32) -> bool {
3109        index < PREDEFINED_SYMBOLS_COUNT
3110    }
3111}
3112
3113impl Ident {
3114    /// Returns `true` for reserved identifiers used internally for elided lifetimes,
3115    /// unnamed method parameters, crate root module, error recovery etc.
3116    pub fn is_special(self) -> bool {
3117        self.name.is_special()
3118    }
3119
3120    /// Returns `true` if the token is a keyword used in the language.
3121    pub fn is_used_keyword(self) -> bool {
3122        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
3123        self.name.is_used_keyword_always()
3124            || self.name.is_used_keyword_conditional(|| self.span.edition())
3125    }
3126
3127    /// Returns `true` if the token is a keyword reserved for possible future use.
3128    pub fn is_unused_keyword(self) -> bool {
3129        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
3130        self.name.is_unused_keyword_always()
3131            || self.name.is_unused_keyword_conditional(|| self.span.edition())
3132    }
3133
3134    /// Returns `true` if the token is either a special identifier or a keyword.
3135    pub fn is_reserved(self) -> bool {
3136        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
3137        self.name.is_reserved(|| self.span.edition())
3138    }
3139
3140    /// A keyword or reserved identifier that can be used as a path segment.
3141    pub fn is_path_segment_keyword(self) -> bool {
3142        self.name.is_path_segment_keyword()
3143    }
3144
3145    /// We see this identifier in a normal identifier position, like variable name or a type.
3146    /// How was it written originally? Did it use the raw form? Let's try to guess.
3147    pub fn is_raw_guess(self) -> bool {
3148        self.name.can_be_raw() && self.is_reserved()
3149    }
3150
3151    /// Given the name of a lifetime without the first quote (`'`),
3152    /// returns whether the lifetime name is reserved (therefore invalid)
3153    pub fn is_reserved_lifetime(self) -> bool {
3154        self.is_reserved() && ![kw::Underscore, kw::Static].contains(&self.name)
3155    }
3156
3157    pub fn is_raw_lifetime_guess(self) -> bool {
3158        // Check that the name isn't just a single quote.
3159        // `self.without_first_quote()` would return empty ident, which triggers debug assert.
3160        if self.name.as_str() == "'" {
3161            return false;
3162        }
3163        let ident_without_apostrophe = self.without_first_quote();
3164        ident_without_apostrophe.name != self.name
3165            && ident_without_apostrophe.name.can_be_raw()
3166            && ident_without_apostrophe.is_reserved_lifetime()
3167    }
3168
3169    pub fn guess_print_mode(self) -> IdentPrintMode {
3170        if self.is_raw_lifetime_guess() {
3171            IdentPrintMode::RawLifetime
3172        } else if self.is_raw_guess() {
3173            IdentPrintMode::RawIdent
3174        } else {
3175            IdentPrintMode::Normal
3176        }
3177    }
3178
3179    /// Whether this would be the identifier for a tuple field like `self.0`, as
3180    /// opposed to a named field like `self.thing`.
3181    pub fn is_numeric(self) -> bool {
3182        self.as_str().bytes().all(|b| b.is_ascii_digit())
3183    }
3184}
3185
3186/// Collect all the keywords in a given edition into a vector.
3187///
3188/// *Note:* Please update this if a new keyword is added beyond the current
3189/// range.
3190pub fn used_keywords(edition: impl Copy + FnOnce() -> Edition) -> Vec<Symbol> {
3191    (kw::DollarCrate.as_u32()..kw::Yeet.as_u32())
3192        .filter_map(|kw| {
3193            let kw = Symbol::new(kw);
3194            if kw.is_used_keyword_always() || kw.is_used_keyword_conditional(edition) {
3195                Some(kw)
3196            } else {
3197                None
3198            }
3199        })
3200        .collect()
3201}