rustc_span/
symbol.rs

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