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