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