rustc_span/
symbol.rs

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