rustc_span/
symbol.rs

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