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