rustc_span/
symbol.rs

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