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