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