rustc_span/
symbol.rs

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