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