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