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