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