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