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