rustc_span/
symbol.rs

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