rustc_span/
symbol.rs

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