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_consts_mod,
985        f16_epsilon,
986        f16_nan,
987        f16c_target_feature,
988        f32,
989        f32_consts_mod,
990        f32_epsilon,
991        f32_legacy_const_digits,
992        f32_legacy_const_epsilon,
993        f32_legacy_const_infinity,
994        f32_legacy_const_mantissa_dig,
995        f32_legacy_const_max,
996        f32_legacy_const_max_10_exp,
997        f32_legacy_const_max_exp,
998        f32_legacy_const_min,
999        f32_legacy_const_min_10_exp,
1000        f32_legacy_const_min_exp,
1001        f32_legacy_const_min_positive,
1002        f32_legacy_const_nan,
1003        f32_legacy_const_neg_infinity,
1004        f32_legacy_const_radix,
1005        f32_nan,
1006        f64,
1007        f64_consts_mod,
1008        f64_epsilon,
1009        f64_legacy_const_digits,
1010        f64_legacy_const_epsilon,
1011        f64_legacy_const_infinity,
1012        f64_legacy_const_mantissa_dig,
1013        f64_legacy_const_max,
1014        f64_legacy_const_max_10_exp,
1015        f64_legacy_const_max_exp,
1016        f64_legacy_const_min,
1017        f64_legacy_const_min_10_exp,
1018        f64_legacy_const_min_exp,
1019        f64_legacy_const_min_positive,
1020        f64_legacy_const_nan,
1021        f64_legacy_const_neg_infinity,
1022        f64_legacy_const_radix,
1023        f64_nan,
1024        f128,
1025        f128_consts_mod,
1026        f128_epsilon,
1027        f128_nan,
1028        fabsf16,
1029        fabsf32,
1030        fabsf64,
1031        fabsf128,
1032        fadd_algebraic,
1033        fadd_fast,
1034        fake_variadic,
1035        fallback,
1036        fdiv_algebraic,
1037        fdiv_fast,
1038        feature,
1039        fence,
1040        ferris: "🦀",
1041        fetch_update,
1042        ffi,
1043        ffi_const,
1044        ffi_pure,
1045        ffi_returns_twice,
1046        field,
1047        field_init_shorthand,
1048        file,
1049        file_options,
1050        flags,
1051        float,
1052        float_to_int_unchecked,
1053        floorf16,
1054        floorf32,
1055        floorf64,
1056        floorf128,
1057        fmaf16,
1058        fmaf32,
1059        fmaf64,
1060        fmaf128,
1061        fmt,
1062        fmt_debug,
1063        fmul_algebraic,
1064        fmul_fast,
1065        fmuladdf16,
1066        fmuladdf32,
1067        fmuladdf64,
1068        fmuladdf128,
1069        fn_align,
1070        fn_body,
1071        fn_delegation,
1072        fn_must_use,
1073        fn_mut,
1074        fn_once,
1075        fn_once_output,
1076        fn_ptr_addr,
1077        fn_ptr_trait,
1078        forbid,
1079        force_target_feature,
1080        forget,
1081        format,
1082        format_args,
1083        format_args_capture,
1084        format_args_macro,
1085        format_args_nl,
1086        format_argument,
1087        format_arguments,
1088        format_count,
1089        format_macro,
1090        format_placeholder,
1091        format_unsafe_arg,
1092        framework,
1093        freeze,
1094        freeze_impls,
1095        freg,
1096        frem_algebraic,
1097        frem_fast,
1098        from,
1099        from_desugaring,
1100        from_fn,
1101        from_iter,
1102        from_iter_fn,
1103        from_output,
1104        from_residual,
1105        from_size_align_unchecked,
1106        from_str_method,
1107        from_u16,
1108        from_usize,
1109        from_yeet,
1110        frontmatter,
1111        fs_create_dir,
1112        fsub_algebraic,
1113        fsub_fast,
1114        full,
1115        fundamental,
1116        fused_iterator,
1117        future,
1118        future_drop_poll,
1119        future_output,
1120        future_trait,
1121        fxsr,
1122        gdb_script_file,
1123        ge,
1124        gen_blocks,
1125        gen_future,
1126        generator_clone,
1127        generators,
1128        generic_arg_infer,
1129        generic_assert,
1130        generic_associated_types,
1131        generic_associated_types_extended,
1132        generic_const_exprs,
1133        generic_const_items,
1134        generic_const_parameter_types,
1135        generic_param_attrs,
1136        generic_pattern_types,
1137        get_context,
1138        global_alloc_ty,
1139        global_allocator,
1140        global_asm,
1141        global_registration,
1142        globs,
1143        gt,
1144        guard_patterns,
1145        half_open_range_patterns,
1146        half_open_range_patterns_in_slices,
1147        hash,
1148        hashmap_contains_key,
1149        hashmap_drain_ty,
1150        hashmap_insert,
1151        hashmap_iter_mut_ty,
1152        hashmap_iter_ty,
1153        hashmap_keys_ty,
1154        hashmap_values_mut_ty,
1155        hashmap_values_ty,
1156        hashset_drain_ty,
1157        hashset_iter,
1158        hashset_iter_ty,
1159        hexagon_target_feature,
1160        hidden,
1161        hide,
1162        hint,
1163        homogeneous_aggregate,
1164        host,
1165        html_favicon_url,
1166        html_logo_url,
1167        html_no_source,
1168        html_playground_url,
1169        html_root_url,
1170        hwaddress,
1171        i,
1172        i8,
1173        i8_legacy_const_max,
1174        i8_legacy_const_min,
1175        i8_legacy_fn_max_value,
1176        i8_legacy_fn_min_value,
1177        i8_legacy_mod,
1178        i16,
1179        i16_legacy_const_max,
1180        i16_legacy_const_min,
1181        i16_legacy_fn_max_value,
1182        i16_legacy_fn_min_value,
1183        i16_legacy_mod,
1184        i32,
1185        i32_legacy_const_max,
1186        i32_legacy_const_min,
1187        i32_legacy_fn_max_value,
1188        i32_legacy_fn_min_value,
1189        i32_legacy_mod,
1190        i64,
1191        i64_legacy_const_max,
1192        i64_legacy_const_min,
1193        i64_legacy_fn_max_value,
1194        i64_legacy_fn_min_value,
1195        i64_legacy_mod,
1196        i128,
1197        i128_legacy_const_max,
1198        i128_legacy_const_min,
1199        i128_legacy_fn_max_value,
1200        i128_legacy_fn_min_value,
1201        i128_legacy_mod,
1202        i128_type,
1203        ident,
1204        if_let,
1205        if_let_guard,
1206        if_let_rescope,
1207        if_while_or_patterns,
1208        ignore,
1209        immediate_abort: "immediate-abort",
1210        impl_header_lifetime_elision,
1211        impl_lint_pass,
1212        impl_trait_in_assoc_type,
1213        impl_trait_in_bindings,
1214        impl_trait_in_fn_trait_return,
1215        impl_trait_projections,
1216        implement_via_object,
1217        implied_by,
1218        import,
1219        import_name_type,
1220        import_shadowing,
1221        import_trait_associated_functions,
1222        imported_main,
1223        in_band_lifetimes,
1224        include,
1225        include_bytes,
1226        include_bytes_macro,
1227        include_str,
1228        include_str_macro,
1229        inclusive_range_syntax,
1230        index,
1231        index_mut,
1232        infer_outlives_requirements,
1233        infer_static_outlives_requirements,
1234        inherent_associated_types,
1235        inherit,
1236        initial,
1237        inlateout,
1238        inline,
1239        inline_const,
1240        inline_const_pat,
1241        inout,
1242        instant_now,
1243        instruction_set,
1244        integer_: "integer", // underscore to avoid clashing with the function `sym::integer` below
1245        integral,
1246        internal,
1247        internal_features,
1248        into_async_iter_into_iter,
1249        into_future,
1250        into_iter,
1251        intra_doc_pointers,
1252        intrinsics,
1253        intrinsics_unaligned_volatile_load,
1254        intrinsics_unaligned_volatile_store,
1255        io_error_new,
1256        io_errorkind,
1257        io_stderr,
1258        io_stdout,
1259        irrefutable_let_patterns,
1260        is,
1261        is_val_statically_known,
1262        isa_attribute,
1263        isize,
1264        isize_legacy_const_max,
1265        isize_legacy_const_min,
1266        isize_legacy_fn_max_value,
1267        isize_legacy_fn_min_value,
1268        isize_legacy_mod,
1269        issue,
1270        issue_5723_bootstrap,
1271        issue_tracker_base_url,
1272        item,
1273        item_like_imports,
1274        iter,
1275        iter_cloned,
1276        iter_copied,
1277        iter_filter,
1278        iter_mut,
1279        iter_repeat,
1280        iterator,
1281        iterator_collect_fn,
1282        kcfi,
1283        kernel_address,
1284        keylocker_x86,
1285        keyword,
1286        kind,
1287        kreg,
1288        kreg0,
1289        label,
1290        label_break_value,
1291        lahfsahf_target_feature,
1292        lang,
1293        lang_items,
1294        large_assignments,
1295        last,
1296        lateout,
1297        lazy_normalization_consts,
1298        lazy_type_alias,
1299        le,
1300        legacy_receiver,
1301        len,
1302        let_chains,
1303        let_else,
1304        lhs,
1305        lib,
1306        libc,
1307        lifetime,
1308        lifetime_capture_rules_2024,
1309        lifetimes,
1310        likely,
1311        line,
1312        link,
1313        link_arg_attribute,
1314        link_args,
1315        link_cfg,
1316        link_dash_arg: "link-arg",
1317        link_llvm_intrinsics,
1318        link_name,
1319        link_ordinal,
1320        link_section,
1321        linkage,
1322        linker,
1323        linker_messages,
1324        linkonce,
1325        linkonce_odr,
1326        lint_reasons,
1327        literal,
1328        load,
1329        loaded_from_disk,
1330        local,
1331        local_inner_macros,
1332        log2f16,
1333        log2f32,
1334        log2f64,
1335        log2f128,
1336        log10f16,
1337        log10f32,
1338        log10f64,
1339        log10f128,
1340        log_syntax,
1341        logf16,
1342        logf32,
1343        logf64,
1344        logf128,
1345        loongarch_target_feature,
1346        loop_break_value,
1347        loop_match,
1348        lr,
1349        lt,
1350        m68k_target_feature,
1351        macro_at_most_once_rep,
1352        macro_attr,
1353        macro_attributes_in_derive_output,
1354        macro_concat,
1355        macro_derive,
1356        macro_escape,
1357        macro_export,
1358        macro_lifetime_matcher,
1359        macro_literal_matcher,
1360        macro_metavar_expr,
1361        macro_metavar_expr_concat,
1362        macro_reexport,
1363        macro_use,
1364        macro_vis_matcher,
1365        macros_in_extern,
1366        main,
1367        managed_boxes,
1368        manually_drop,
1369        map,
1370        map_err,
1371        marker,
1372        marker_trait_attr,
1373        masked,
1374        match_beginning_vert,
1375        match_default_bindings,
1376        matches_macro,
1377        maximumf16,
1378        maximumf32,
1379        maximumf64,
1380        maximumf128,
1381        maxnumf16,
1382        maxnumf32,
1383        maxnumf64,
1384        maxnumf128,
1385        may_dangle,
1386        may_unwind,
1387        maybe_uninit,
1388        maybe_uninit_uninit,
1389        maybe_uninit_zeroed,
1390        mem_align_of,
1391        mem_discriminant,
1392        mem_drop,
1393        mem_forget,
1394        mem_replace,
1395        mem_size_of,
1396        mem_size_of_val,
1397        mem_swap,
1398        mem_uninitialized,
1399        mem_variant_count,
1400        mem_zeroed,
1401        member_constraints,
1402        memory,
1403        memtag,
1404        message,
1405        meta,
1406        meta_sized,
1407        metadata_type,
1408        min_const_fn,
1409        min_const_generics,
1410        min_const_unsafe_fn,
1411        min_exhaustive_patterns,
1412        min_generic_const_args,
1413        min_specialization,
1414        min_type_alias_impl_trait,
1415        minimumf16,
1416        minimumf32,
1417        minimumf64,
1418        minimumf128,
1419        minnumf16,
1420        minnumf32,
1421        minnumf64,
1422        minnumf128,
1423        mips_target_feature,
1424        mir_assume,
1425        mir_basic_block,
1426        mir_call,
1427        mir_cast_ptr_to_ptr,
1428        mir_cast_transmute,
1429        mir_cast_unsize,
1430        mir_checked,
1431        mir_debuginfo,
1432        mir_deinit,
1433        mir_discriminant,
1434        mir_drop,
1435        mir_field,
1436        mir_goto,
1437        mir_len,
1438        mir_make_place,
1439        mir_move,
1440        mir_offset,
1441        mir_ptr_metadata,
1442        mir_retag,
1443        mir_return,
1444        mir_return_to,
1445        mir_set_discriminant,
1446        mir_static,
1447        mir_static_mut,
1448        mir_storage_dead,
1449        mir_storage_live,
1450        mir_tail_call,
1451        mir_unreachable,
1452        mir_unwind_cleanup,
1453        mir_unwind_continue,
1454        mir_unwind_resume,
1455        mir_unwind_terminate,
1456        mir_unwind_terminate_reason,
1457        mir_unwind_unreachable,
1458        mir_variant,
1459        miri,
1460        mmx_reg,
1461        modifiers,
1462        module,
1463        module_path,
1464        more_maybe_bounds,
1465        more_qualified_paths,
1466        more_struct_aliases,
1467        movbe_target_feature,
1468        move_ref_pattern,
1469        move_size_limit,
1470        movrs_target_feature,
1471        mul,
1472        mul_assign,
1473        mul_with_overflow,
1474        multiple_supertrait_upcastable,
1475        must_not_suspend,
1476        must_use,
1477        mut_preserve_binding_mode_2024,
1478        mut_ref,
1479        naked,
1480        naked_asm,
1481        naked_functions,
1482        naked_functions_rustic_abi,
1483        naked_functions_target_feature,
1484        name,
1485        names,
1486        native_link_modifiers,
1487        native_link_modifiers_as_needed,
1488        native_link_modifiers_bundle,
1489        native_link_modifiers_verbatim,
1490        native_link_modifiers_whole_archive,
1491        natvis_file,
1492        ne,
1493        needs_allocator,
1494        needs_drop,
1495        needs_panic_runtime,
1496        neg,
1497        negate_unsigned,
1498        negative_bounds,
1499        negative_impls,
1500        neon,
1501        nested,
1502        never,
1503        never_patterns,
1504        never_type,
1505        never_type_fallback,
1506        new,
1507        new_binary,
1508        new_const,
1509        new_debug,
1510        new_debug_noop,
1511        new_display,
1512        new_lower_exp,
1513        new_lower_hex,
1514        new_octal,
1515        new_pointer,
1516        new_range,
1517        new_unchecked,
1518        new_upper_exp,
1519        new_upper_hex,
1520        new_v1,
1521        new_v1_formatted,
1522        next,
1523        niko,
1524        nll,
1525        no,
1526        no_builtins,
1527        no_core,
1528        no_coverage,
1529        no_crate_inject,
1530        no_debug,
1531        no_default_passes,
1532        no_implicit_prelude,
1533        no_inline,
1534        no_link,
1535        no_main,
1536        no_mangle,
1537        no_sanitize,
1538        no_stack_check,
1539        no_std,
1540        nomem,
1541        non_ascii_idents,
1542        non_exhaustive,
1543        non_exhaustive_omitted_patterns_lint,
1544        non_lifetime_binders,
1545        non_modrs_mods,
1546        none,
1547        nontemporal_store,
1548        noop_method_borrow,
1549        noop_method_clone,
1550        noop_method_deref,
1551        noprefix,
1552        noreturn,
1553        nostack,
1554        not,
1555        notable_trait,
1556        note,
1557        null,
1558        nvptx_target_feature,
1559        object_safe_for_dispatch,
1560        of,
1561        off,
1562        offset,
1563        offset_of,
1564        offset_of_enum,
1565        offset_of_nested,
1566        offset_of_slice,
1567        ok_or_else,
1568        old_name,
1569        omit_gdb_pretty_printer_section,
1570        on,
1571        on_unimplemented,
1572        opaque,
1573        opaque_module_name_placeholder: "<opaque>",
1574        open_options_new,
1575        ops,
1576        opt_out_copy,
1577        optimize,
1578        optimize_attribute,
1579        optimized,
1580        optin_builtin_traits,
1581        option,
1582        option_env,
1583        option_expect,
1584        option_unwrap,
1585        options,
1586        or,
1587        or_patterns,
1588        ord_cmp_method,
1589        os_str_to_os_string,
1590        os_string_as_os_str,
1591        other,
1592        out,
1593        overflow_checks,
1594        overlapping_marker_traits,
1595        owned_box,
1596        packed,
1597        packed_bundled_libs,
1598        panic,
1599        panic_2015,
1600        panic_2021,
1601        panic_abort,
1602        panic_any,
1603        panic_bounds_check,
1604        panic_cannot_unwind,
1605        panic_const_add_overflow,
1606        panic_const_async_fn_resumed,
1607        panic_const_async_fn_resumed_drop,
1608        panic_const_async_fn_resumed_panic,
1609        panic_const_async_gen_fn_resumed,
1610        panic_const_async_gen_fn_resumed_drop,
1611        panic_const_async_gen_fn_resumed_panic,
1612        panic_const_coroutine_resumed,
1613        panic_const_coroutine_resumed_drop,
1614        panic_const_coroutine_resumed_panic,
1615        panic_const_div_by_zero,
1616        panic_const_div_overflow,
1617        panic_const_gen_fn_none,
1618        panic_const_gen_fn_none_drop,
1619        panic_const_gen_fn_none_panic,
1620        panic_const_mul_overflow,
1621        panic_const_neg_overflow,
1622        panic_const_rem_by_zero,
1623        panic_const_rem_overflow,
1624        panic_const_shl_overflow,
1625        panic_const_shr_overflow,
1626        panic_const_sub_overflow,
1627        panic_display,
1628        panic_fmt,
1629        panic_handler,
1630        panic_impl,
1631        panic_implementation,
1632        panic_in_cleanup,
1633        panic_info,
1634        panic_invalid_enum_construction,
1635        panic_location,
1636        panic_misaligned_pointer_dereference,
1637        panic_nounwind,
1638        panic_null_pointer_dereference,
1639        panic_runtime,
1640        panic_str_2015,
1641        panic_unwind,
1642        panicking,
1643        param_attrs,
1644        parent_label,
1645        partial_cmp,
1646        partial_ord,
1647        passes,
1648        pat,
1649        pat_param,
1650        patchable_function_entry,
1651        path,
1652        path_main_separator,
1653        path_to_pathbuf,
1654        pathbuf_as_path,
1655        pattern_complexity_limit,
1656        pattern_parentheses,
1657        pattern_type,
1658        pattern_type_range_trait,
1659        pattern_types,
1660        permissions_from_mode,
1661        phantom_data,
1662        phase,
1663        pic,
1664        pie,
1665        pin,
1666        pin_ergonomics,
1667        pin_macro,
1668        platform_intrinsics,
1669        plugin,
1670        plugin_registrar,
1671        plugins,
1672        pointee,
1673        pointee_sized,
1674        pointee_trait,
1675        pointer,
1676        poll,
1677        poll_next,
1678        position,
1679        post_cleanup: "post-cleanup",
1680        post_dash_lto: "post-lto",
1681        postfix_match,
1682        powerpc_target_feature,
1683        powf16,
1684        powf32,
1685        powf64,
1686        powf128,
1687        powif16,
1688        powif32,
1689        powif64,
1690        powif128,
1691        pre_dash_lto: "pre-lto",
1692        precise_capturing,
1693        precise_capturing_in_traits,
1694        precise_pointer_size_matching,
1695        precision,
1696        pref_align_of,
1697        prefetch_read_data,
1698        prefetch_read_instruction,
1699        prefetch_write_data,
1700        prefetch_write_instruction,
1701        prefix_nops,
1702        preg,
1703        prelude,
1704        prelude_import,
1705        preserves_flags,
1706        prfchw_target_feature,
1707        print_macro,
1708        println_macro,
1709        proc_dash_macro: "proc-macro",
1710        proc_macro,
1711        proc_macro_attribute,
1712        proc_macro_derive,
1713        proc_macro_expr,
1714        proc_macro_gen,
1715        proc_macro_hygiene,
1716        proc_macro_internals,
1717        proc_macro_mod,
1718        proc_macro_non_items,
1719        proc_macro_path_invoc,
1720        process_abort,
1721        process_exit,
1722        profiler_builtins,
1723        profiler_runtime,
1724        ptr,
1725        ptr_cast,
1726        ptr_cast_const,
1727        ptr_cast_mut,
1728        ptr_const_is_null,
1729        ptr_copy,
1730        ptr_copy_nonoverlapping,
1731        ptr_eq,
1732        ptr_from_ref,
1733        ptr_guaranteed_cmp,
1734        ptr_is_null,
1735        ptr_mask,
1736        ptr_metadata,
1737        ptr_null,
1738        ptr_null_mut,
1739        ptr_offset_from,
1740        ptr_offset_from_unsigned,
1741        ptr_read,
1742        ptr_read_unaligned,
1743        ptr_read_volatile,
1744        ptr_replace,
1745        ptr_slice_from_raw_parts,
1746        ptr_slice_from_raw_parts_mut,
1747        ptr_swap,
1748        ptr_swap_nonoverlapping,
1749        ptr_write,
1750        ptr_write_bytes,
1751        ptr_write_unaligned,
1752        ptr_write_volatile,
1753        pub_macro_rules,
1754        pub_restricted,
1755        public,
1756        pure,
1757        pushpop_unsafe,
1758        qreg,
1759        qreg_low4,
1760        qreg_low8,
1761        quad_precision_float,
1762        question_mark,
1763        quote,
1764        range_inclusive_new,
1765        range_step,
1766        raw_dash_dylib: "raw-dylib",
1767        raw_dylib,
1768        raw_dylib_elf,
1769        raw_eq,
1770        raw_identifiers,
1771        raw_ref_op,
1772        re_rebalance_coherence,
1773        read_enum,
1774        read_enum_variant,
1775        read_enum_variant_arg,
1776        read_struct,
1777        read_struct_field,
1778        read_via_copy,
1779        readonly,
1780        realloc,
1781        reason,
1782        reborrow,
1783        receiver,
1784        receiver_target,
1785        recursion_limit,
1786        reexport_test_harness_main,
1787        ref_pat_eat_one_layer_2024,
1788        ref_pat_eat_one_layer_2024_structural,
1789        ref_pat_everywhere,
1790        ref_unwind_safe_trait,
1791        reference,
1792        reflect,
1793        reg,
1794        reg16,
1795        reg32,
1796        reg64,
1797        reg_abcd,
1798        reg_addr,
1799        reg_byte,
1800        reg_data,
1801        reg_iw,
1802        reg_nonzero,
1803        reg_pair,
1804        reg_ptr,
1805        reg_upper,
1806        register_attr,
1807        register_tool,
1808        relaxed_adts,
1809        relaxed_struct_unsize,
1810        relocation_model,
1811        rem,
1812        rem_assign,
1813        repr,
1814        repr128,
1815        repr_align,
1816        repr_align_enum,
1817        repr_packed,
1818        repr_simd,
1819        repr_transparent,
1820        require,
1821        reserve_x18: "reserve-x18",
1822        residual,
1823        result,
1824        result_ffi_guarantees,
1825        result_ok_method,
1826        resume,
1827        return_position_impl_trait_in_trait,
1828        return_type_notation,
1829        riscv_target_feature,
1830        rlib,
1831        ropi,
1832        ropi_rwpi: "ropi-rwpi",
1833        rotate_left,
1834        rotate_right,
1835        round_ties_even_f16,
1836        round_ties_even_f32,
1837        round_ties_even_f64,
1838        round_ties_even_f128,
1839        roundf16,
1840        roundf32,
1841        roundf64,
1842        roundf128,
1843        rt,
1844        rtm_target_feature,
1845        runtime,
1846        rust,
1847        rust_2015,
1848        rust_2018,
1849        rust_2018_preview,
1850        rust_2021,
1851        rust_2024,
1852        rust_analyzer,
1853        rust_begin_unwind,
1854        rust_cold_cc,
1855        rust_eh_catch_typeinfo,
1856        rust_eh_personality,
1857        rust_future,
1858        rust_logo,
1859        rust_out,
1860        rustc,
1861        rustc_abi,
1862        // FIXME(#82232, #143834): temporary name to mitigate `#[align]` nameres ambiguity
1863        rustc_align,
1864        rustc_align_static,
1865        rustc_allocator,
1866        rustc_allocator_zeroed,
1867        rustc_allocator_zeroed_variant,
1868        rustc_allow_const_fn_unstable,
1869        rustc_allow_incoherent_impl,
1870        rustc_allowed_through_unstable_modules,
1871        rustc_as_ptr,
1872        rustc_attrs,
1873        rustc_autodiff,
1874        rustc_builtin_macro,
1875        rustc_capture_analysis,
1876        rustc_clean,
1877        rustc_coherence_is_core,
1878        rustc_coinductive,
1879        rustc_confusables,
1880        rustc_const_stable,
1881        rustc_const_stable_indirect,
1882        rustc_const_unstable,
1883        rustc_conversion_suggestion,
1884        rustc_deallocator,
1885        rustc_def_path,
1886        rustc_default_body_unstable,
1887        rustc_delayed_bug_from_inside_query,
1888        rustc_deny_explicit_impl,
1889        rustc_deprecated_safe_2024,
1890        rustc_diagnostic_item,
1891        rustc_diagnostic_macros,
1892        rustc_dirty,
1893        rustc_do_not_const_check,
1894        rustc_do_not_implement_via_object,
1895        rustc_doc_primitive,
1896        rustc_driver,
1897        rustc_dummy,
1898        rustc_dump_def_parents,
1899        rustc_dump_item_bounds,
1900        rustc_dump_predicates,
1901        rustc_dump_user_args,
1902        rustc_dump_vtable,
1903        rustc_effective_visibility,
1904        rustc_evaluate_where_clauses,
1905        rustc_expected_cgu_reuse,
1906        rustc_force_inline,
1907        rustc_has_incoherent_inherent_impls,
1908        rustc_hidden_type_of_opaques,
1909        rustc_if_this_changed,
1910        rustc_inherit_overflow_checks,
1911        rustc_insignificant_dtor,
1912        rustc_intrinsic,
1913        rustc_intrinsic_const_stable_indirect,
1914        rustc_layout,
1915        rustc_layout_scalar_valid_range_end,
1916        rustc_layout_scalar_valid_range_start,
1917        rustc_legacy_const_generics,
1918        rustc_lint_diagnostics,
1919        rustc_lint_opt_deny_field_access,
1920        rustc_lint_opt_ty,
1921        rustc_lint_query_instability,
1922        rustc_lint_untracked_query_information,
1923        rustc_macro_transparency,
1924        rustc_main,
1925        rustc_mir,
1926        rustc_must_implement_one_of,
1927        rustc_never_returns_null_ptr,
1928        rustc_never_type_options,
1929        rustc_no_implicit_autorefs,
1930        rustc_no_implicit_bounds,
1931        rustc_no_mir_inline,
1932        rustc_nonnull_optimization_guaranteed,
1933        rustc_nounwind,
1934        rustc_objc_class,
1935        rustc_objc_selector,
1936        rustc_object_lifetime_default,
1937        rustc_on_unimplemented,
1938        rustc_outlives,
1939        rustc_paren_sugar,
1940        rustc_partition_codegened,
1941        rustc_partition_reused,
1942        rustc_pass_by_value,
1943        rustc_peek,
1944        rustc_peek_liveness,
1945        rustc_peek_maybe_init,
1946        rustc_peek_maybe_uninit,
1947        rustc_preserve_ub_checks,
1948        rustc_private,
1949        rustc_proc_macro_decls,
1950        rustc_promotable,
1951        rustc_pub_transparent,
1952        rustc_reallocator,
1953        rustc_regions,
1954        rustc_reservation_impl,
1955        rustc_serialize,
1956        rustc_simd_monomorphize_lane_limit,
1957        rustc_skip_during_method_dispatch,
1958        rustc_specialization_trait,
1959        rustc_std_internal_symbol,
1960        rustc_strict_coherence,
1961        rustc_symbol_name,
1962        rustc_test_marker,
1963        rustc_then_this_would_need,
1964        rustc_trivial_field_reads,
1965        rustc_unsafe_specialization_marker,
1966        rustc_variance,
1967        rustc_variance_of_opaques,
1968        rustdoc,
1969        rustdoc_internals,
1970        rustdoc_missing_doc_code_examples,
1971        rustfmt,
1972        rvalue_static_promotion,
1973        rwpi,
1974        s,
1975        s390x_target_feature,
1976        safety,
1977        sanitize,
1978        sanitizer_cfi_generalize_pointers,
1979        sanitizer_cfi_normalize_integers,
1980        sanitizer_runtime,
1981        saturating_add,
1982        saturating_div,
1983        saturating_sub,
1984        sdylib,
1985        search_unbox,
1986        select_unpredictable,
1987        self_in_typedefs,
1988        self_struct_ctor,
1989        semiopaque,
1990        semitransparent,
1991        sha2,
1992        sha3,
1993        sha512_sm_x86,
1994        shadow_call_stack,
1995        shallow,
1996        shl,
1997        shl_assign,
1998        shorter_tail_lifetimes,
1999        should_panic,
2000        show,
2001        shr,
2002        shr_assign,
2003        sig_dfl,
2004        sig_ign,
2005        simd,
2006        simd_add,
2007        simd_and,
2008        simd_arith_offset,
2009        simd_as,
2010        simd_bitmask,
2011        simd_bitreverse,
2012        simd_bswap,
2013        simd_cast,
2014        simd_cast_ptr,
2015        simd_ceil,
2016        simd_ctlz,
2017        simd_ctpop,
2018        simd_cttz,
2019        simd_div,
2020        simd_eq,
2021        simd_expose_provenance,
2022        simd_extract,
2023        simd_extract_dyn,
2024        simd_fabs,
2025        simd_fcos,
2026        simd_fexp,
2027        simd_fexp2,
2028        simd_ffi,
2029        simd_flog,
2030        simd_flog2,
2031        simd_flog10,
2032        simd_floor,
2033        simd_fma,
2034        simd_fmax,
2035        simd_fmin,
2036        simd_fsin,
2037        simd_fsqrt,
2038        simd_funnel_shl,
2039        simd_funnel_shr,
2040        simd_gather,
2041        simd_ge,
2042        simd_gt,
2043        simd_insert,
2044        simd_insert_dyn,
2045        simd_le,
2046        simd_lt,
2047        simd_masked_load,
2048        simd_masked_store,
2049        simd_mul,
2050        simd_ne,
2051        simd_neg,
2052        simd_or,
2053        simd_reduce_add_ordered,
2054        simd_reduce_add_unordered,
2055        simd_reduce_all,
2056        simd_reduce_and,
2057        simd_reduce_any,
2058        simd_reduce_max,
2059        simd_reduce_min,
2060        simd_reduce_mul_ordered,
2061        simd_reduce_mul_unordered,
2062        simd_reduce_or,
2063        simd_reduce_xor,
2064        simd_relaxed_fma,
2065        simd_rem,
2066        simd_round,
2067        simd_round_ties_even,
2068        simd_saturating_add,
2069        simd_saturating_sub,
2070        simd_scatter,
2071        simd_select,
2072        simd_select_bitmask,
2073        simd_shl,
2074        simd_shr,
2075        simd_shuffle,
2076        simd_shuffle_const_generic,
2077        simd_sub,
2078        simd_trunc,
2079        simd_with_exposed_provenance,
2080        simd_xor,
2081        since,
2082        sinf16,
2083        sinf32,
2084        sinf64,
2085        sinf128,
2086        size,
2087        size_of,
2088        size_of_val,
2089        sized,
2090        sized_hierarchy,
2091        skip,
2092        slice,
2093        slice_from_raw_parts,
2094        slice_from_raw_parts_mut,
2095        slice_from_ref,
2096        slice_get_unchecked,
2097        slice_into_vec,
2098        slice_iter,
2099        slice_len_fn,
2100        slice_patterns,
2101        slicing_syntax,
2102        soft,
2103        sparc_target_feature,
2104        specialization,
2105        speed,
2106        spotlight,
2107        sqrtf16,
2108        sqrtf32,
2109        sqrtf64,
2110        sqrtf128,
2111        sreg,
2112        sreg_low16,
2113        sse,
2114        sse2,
2115        sse4a_target_feature,
2116        stable,
2117        staged_api,
2118        start,
2119        state,
2120        static_align,
2121        static_in_const,
2122        static_nobundle,
2123        static_recursion,
2124        staticlib,
2125        std,
2126        std_lib_injection,
2127        std_panic,
2128        std_panic_2015_macro,
2129        std_panic_macro,
2130        stmt,
2131        stmt_expr_attributes,
2132        stop_after_dataflow,
2133        store,
2134        str,
2135        str_chars,
2136        str_ends_with,
2137        str_from_utf8,
2138        str_from_utf8_mut,
2139        str_from_utf8_unchecked,
2140        str_from_utf8_unchecked_mut,
2141        str_inherent_from_utf8,
2142        str_inherent_from_utf8_mut,
2143        str_inherent_from_utf8_unchecked,
2144        str_inherent_from_utf8_unchecked_mut,
2145        str_len,
2146        str_split_whitespace,
2147        str_starts_with,
2148        str_trim,
2149        str_trim_end,
2150        str_trim_start,
2151        strict_provenance_lints,
2152        string_as_mut_str,
2153        string_as_str,
2154        string_deref_patterns,
2155        string_from_utf8,
2156        string_insert_str,
2157        string_new,
2158        string_push_str,
2159        stringify,
2160        struct_field_attributes,
2161        struct_inherit,
2162        struct_variant,
2163        structural_match,
2164        structural_peq,
2165        sub,
2166        sub_assign,
2167        sub_with_overflow,
2168        suggestion,
2169        super_let,
2170        supertrait_item_shadowing,
2171        sym,
2172        sync,
2173        synthetic,
2174        sys_mutex_lock,
2175        sys_mutex_try_lock,
2176        sys_mutex_unlock,
2177        t32,
2178        target,
2179        target_abi,
2180        target_arch,
2181        target_endian,
2182        target_env,
2183        target_family,
2184        target_feature,
2185        target_feature_11,
2186        target_feature_inline_always,
2187        target_has_atomic,
2188        target_has_atomic_equal_alignment,
2189        target_has_atomic_load_store,
2190        target_has_reliable_f16,
2191        target_has_reliable_f16_math,
2192        target_has_reliable_f128,
2193        target_has_reliable_f128_math,
2194        target_os,
2195        target_pointer_width,
2196        target_thread_local,
2197        target_vendor,
2198        tbm_target_feature,
2199        termination,
2200        termination_trait,
2201        termination_trait_test,
2202        test,
2203        test_2018_feature,
2204        test_accepted_feature,
2205        test_case,
2206        test_removed_feature,
2207        test_runner,
2208        test_unstable_lint,
2209        thread,
2210        thread_local,
2211        thread_local_macro,
2212        three_way_compare,
2213        thumb2,
2214        thumb_mode: "thumb-mode",
2215        tmm_reg,
2216        to_owned_method,
2217        to_string,
2218        to_string_method,
2219        to_vec,
2220        todo_macro,
2221        tool_attributes,
2222        tool_lints,
2223        trace_macros,
2224        track_caller,
2225        trait_alias,
2226        trait_upcasting,
2227        transmute,
2228        transmute_generic_consts,
2229        transmute_opts,
2230        transmute_trait,
2231        transmute_unchecked,
2232        transparent,
2233        transparent_enums,
2234        transparent_unions,
2235        trivial_bounds,
2236        truncf16,
2237        truncf32,
2238        truncf64,
2239        truncf128,
2240        try_blocks,
2241        try_capture,
2242        try_from,
2243        try_from_fn,
2244        try_into,
2245        try_trait_v2,
2246        tt,
2247        tuple,
2248        tuple_indexing,
2249        tuple_trait,
2250        two_phase,
2251        ty,
2252        type_alias_enum_variants,
2253        type_alias_impl_trait,
2254        type_ascribe,
2255        type_ascription,
2256        type_changing_struct_update,
2257        type_const,
2258        type_id,
2259        type_id_eq,
2260        type_ir,
2261        type_ir_infer_ctxt_like,
2262        type_ir_inherent,
2263        type_ir_interner,
2264        type_length_limit,
2265        type_macros,
2266        type_name,
2267        type_privacy_lints,
2268        typed_swap_nonoverlapping,
2269        u8,
2270        u8_legacy_const_max,
2271        u8_legacy_const_min,
2272        u8_legacy_fn_max_value,
2273        u8_legacy_fn_min_value,
2274        u8_legacy_mod,
2275        u16,
2276        u16_legacy_const_max,
2277        u16_legacy_const_min,
2278        u16_legacy_fn_max_value,
2279        u16_legacy_fn_min_value,
2280        u16_legacy_mod,
2281        u32,
2282        u32_legacy_const_max,
2283        u32_legacy_const_min,
2284        u32_legacy_fn_max_value,
2285        u32_legacy_fn_min_value,
2286        u32_legacy_mod,
2287        u64,
2288        u64_legacy_const_max,
2289        u64_legacy_const_min,
2290        u64_legacy_fn_max_value,
2291        u64_legacy_fn_min_value,
2292        u64_legacy_mod,
2293        u128,
2294        u128_legacy_const_max,
2295        u128_legacy_const_min,
2296        u128_legacy_fn_max_value,
2297        u128_legacy_fn_min_value,
2298        u128_legacy_mod,
2299        ub_checks,
2300        unaligned_volatile_load,
2301        unaligned_volatile_store,
2302        unboxed_closures,
2303        unchecked_add,
2304        unchecked_div,
2305        unchecked_funnel_shl,
2306        unchecked_funnel_shr,
2307        unchecked_mul,
2308        unchecked_rem,
2309        unchecked_shl,
2310        unchecked_shr,
2311        unchecked_sub,
2312        undecorated,
2313        underscore_const_names,
2314        underscore_imports,
2315        underscore_lifetimes,
2316        uniform_paths,
2317        unimplemented_macro,
2318        unit,
2319        universal_impl_trait,
2320        unix,
2321        unlikely,
2322        unmarked_api,
2323        unnamed_fields,
2324        unpin,
2325        unqualified_local_imports,
2326        unreachable,
2327        unreachable_2015,
2328        unreachable_2015_macro,
2329        unreachable_2021,
2330        unreachable_code,
2331        unreachable_display,
2332        unreachable_macro,
2333        unrestricted_attribute_tokens,
2334        unsafe_attributes,
2335        unsafe_binders,
2336        unsafe_block_in_unsafe_fn,
2337        unsafe_cell,
2338        unsafe_cell_raw_get,
2339        unsafe_extern_blocks,
2340        unsafe_fields,
2341        unsafe_no_drop_flag,
2342        unsafe_pinned,
2343        unsafe_unpin,
2344        unsize,
2345        unsized_const_param_ty,
2346        unsized_const_params,
2347        unsized_fn_params,
2348        unsized_locals,
2349        unsized_tuple_coercion,
2350        unstable,
2351        unstable_feature_bound,
2352        unstable_location_reason_default: "this crate is being loaded from the sysroot, an \
2353                          unstable location; did you mean to load this crate \
2354                          from crates.io via `Cargo.toml` instead?",
2355        untagged_unions,
2356        unused_imports,
2357        unwind,
2358        unwind_attributes,
2359        unwind_safe_trait,
2360        unwrap,
2361        unwrap_binder,
2362        unwrap_or,
2363        use_cloned,
2364        use_extern_macros,
2365        use_nested_groups,
2366        used,
2367        used_with_arg,
2368        using,
2369        usize,
2370        usize_legacy_const_max,
2371        usize_legacy_const_min,
2372        usize_legacy_fn_max_value,
2373        usize_legacy_fn_min_value,
2374        usize_legacy_mod,
2375        v1,
2376        v8plus,
2377        va_arg,
2378        va_copy,
2379        va_end,
2380        va_list,
2381        va_start,
2382        val,
2383        validity,
2384        value,
2385        values,
2386        var,
2387        variant_count,
2388        vec,
2389        vec_as_mut_slice,
2390        vec_as_slice,
2391        vec_from_elem,
2392        vec_is_empty,
2393        vec_macro,
2394        vec_new,
2395        vec_pop,
2396        vec_reserve,
2397        vec_with_capacity,
2398        vecdeque_iter,
2399        vecdeque_reserve,
2400        vector,
2401        verbatim,
2402        version,
2403        vfp2,
2404        vis,
2405        visible_private_types,
2406        volatile,
2407        volatile_copy_memory,
2408        volatile_copy_nonoverlapping_memory,
2409        volatile_load,
2410        volatile_set_memory,
2411        volatile_store,
2412        vreg,
2413        vreg_low16,
2414        vsreg,
2415        vsx,
2416        vtable_align,
2417        vtable_size,
2418        warn,
2419        wasip2,
2420        wasm_abi,
2421        wasm_import_module,
2422        wasm_target_feature,
2423        weak,
2424        weak_odr,
2425        where_clause_attrs,
2426        while_let,
2427        whole_dash_archive: "whole-archive",
2428        width,
2429        windows,
2430        windows_subsystem,
2431        with_negative_coherence,
2432        wrap_binder,
2433        wrapping_add,
2434        wrapping_div,
2435        wrapping_mul,
2436        wrapping_rem,
2437        wrapping_rem_euclid,
2438        wrapping_sub,
2439        wreg,
2440        write_bytes,
2441        write_fmt,
2442        write_macro,
2443        write_str,
2444        write_via_move,
2445        writeln_macro,
2446        x86_amx_intrinsics,
2447        x87_reg,
2448        x87_target_feature,
2449        xer,
2450        xmm_reg,
2451        xop_target_feature,
2452        yeet_desugar_details,
2453        yeet_expr,
2454        yes,
2455        yield_expr,
2456        ymm_reg,
2457        yreg,
2458        zca,
2459        zfh,
2460        zfhmin,
2461        zmm_reg,
2462        ztso,
2463        // tidy-alphabetical-end
2464    }
2465}
2466
2467/// Symbols for crates that are part of the stable standard library: `std`, `core`, `alloc`, and
2468/// `proc_macro`.
2469pub const STDLIB_STABLE_CRATES: &[Symbol] = &[sym::std, sym::core, sym::alloc, sym::proc_macro];
2470
2471#[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
2472pub struct Ident {
2473    /// `name` should never be the empty symbol. If you are considering that,
2474    /// you are probably conflating "empty identifier with "no identifier" and
2475    /// you should use `Option<Ident>` instead.
2476    /// Trying to construct an `Ident` with an empty name will trigger debug assertions.
2477    pub name: Symbol,
2478    pub span: Span,
2479}
2480
2481impl Ident {
2482    #[inline]
2483    /// Constructs a new identifier from a symbol and a span.
2484    pub fn new(name: Symbol, span: Span) -> Ident {
2485        debug_assert_ne!(name, sym::empty);
2486        Ident { name, span }
2487    }
2488
2489    /// Constructs a new identifier with a dummy span.
2490    #[inline]
2491    pub fn with_dummy_span(name: Symbol) -> Ident {
2492        Ident::new(name, DUMMY_SP)
2493    }
2494
2495    // For dummy identifiers that are never used and absolutely must be
2496    // present. Note that this does *not* use the empty symbol; `sym::dummy`
2497    // makes it clear that it's intended as a dummy value, and is more likely
2498    // to be detected if it accidentally does get used.
2499    #[inline]
2500    pub fn dummy() -> Ident {
2501        Ident::with_dummy_span(sym::dummy)
2502    }
2503
2504    /// Maps a string to an identifier with a dummy span.
2505    pub fn from_str(string: &str) -> Ident {
2506        Ident::with_dummy_span(Symbol::intern(string))
2507    }
2508
2509    /// Maps a string and a span to an identifier.
2510    pub fn from_str_and_span(string: &str, span: Span) -> Ident {
2511        Ident::new(Symbol::intern(string), span)
2512    }
2513
2514    /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
2515    pub fn with_span_pos(self, span: Span) -> Ident {
2516        Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
2517    }
2518
2519    /// Creates a new ident with the same span and name with leading quote removed, if any.
2520    /// Calling it on a `'` ident will return an empty ident, which triggers debug assertions.
2521    pub fn without_first_quote(self) -> Ident {
2522        self.as_str()
2523            .strip_prefix('\'')
2524            .map_or(self, |name| Ident::new(Symbol::intern(name), self.span))
2525    }
2526
2527    /// "Normalize" ident for use in comparisons using "item hygiene".
2528    /// Identifiers with same string value become same if they came from the same macro 2.0 macro
2529    /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
2530    /// different macro 2.0 macros.
2531    /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
2532    pub fn normalize_to_macros_2_0(self) -> Ident {
2533        Ident::new(self.name, self.span.normalize_to_macros_2_0())
2534    }
2535
2536    /// "Normalize" ident for use in comparisons using "local variable hygiene".
2537    /// Identifiers with same string value become same if they came from the same non-transparent
2538    /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
2539    /// non-transparent macros.
2540    /// Technically, this operation strips all transparent marks from ident's syntactic context.
2541    #[inline]
2542    pub fn normalize_to_macro_rules(self) -> Ident {
2543        Ident::new(self.name, self.span.normalize_to_macro_rules())
2544    }
2545
2546    /// Access the underlying string. This is a slowish operation because it
2547    /// requires locking the symbol interner.
2548    ///
2549    /// Note that the lifetime of the return value is a lie. See
2550    /// `Symbol::as_str()` for details.
2551    pub fn as_str(&self) -> &str {
2552        self.name.as_str()
2553    }
2554}
2555
2556impl PartialEq for Ident {
2557    #[inline]
2558    fn eq(&self, rhs: &Self) -> bool {
2559        self.name == rhs.name && self.span.eq_ctxt(rhs.span)
2560    }
2561}
2562
2563impl Hash for Ident {
2564    fn hash<H: Hasher>(&self, state: &mut H) {
2565        self.name.hash(state);
2566        self.span.ctxt().hash(state);
2567    }
2568}
2569
2570impl fmt::Debug for Ident {
2571    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2572        fmt::Display::fmt(self, f)?;
2573        fmt::Debug::fmt(&self.span.ctxt(), f)
2574    }
2575}
2576
2577/// This implementation is supposed to be used in error messages, so it's expected to be identical
2578/// to printing the original identifier token written in source code (`token_to_string`),
2579/// except that AST identifiers don't keep the rawness flag, so we have to guess it.
2580impl fmt::Display for Ident {
2581    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2582        fmt::Display::fmt(&IdentPrinter::new(self.name, self.guess_print_mode(), None), f)
2583    }
2584}
2585
2586pub enum IdentPrintMode {
2587    Normal,
2588    RawIdent,
2589    RawLifetime,
2590}
2591
2592/// The most general type to print identifiers.
2593///
2594/// AST pretty-printer is used as a fallback for turning AST structures into token streams for
2595/// proc macros. Additionally, proc macros may stringify their input and expect it survive the
2596/// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
2597/// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
2598/// hygiene data, most importantly name of the crate it refers to.
2599/// As a result we print `$crate` as `crate` if it refers to the local crate
2600/// and as `::other_crate_name` if it refers to some other crate.
2601/// Note, that this is only done if the ident token is printed from inside of AST pretty-printing,
2602/// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
2603/// so we should not perform this lossy conversion if the top level call to the pretty-printer was
2604/// done for a token stream or a single token.
2605pub struct IdentPrinter {
2606    symbol: Symbol,
2607    mode: IdentPrintMode,
2608    /// Span used for retrieving the crate name to which `$crate` refers to,
2609    /// if this field is `None` then the `$crate` conversion doesn't happen.
2610    convert_dollar_crate: Option<Span>,
2611}
2612
2613impl IdentPrinter {
2614    /// The most general `IdentPrinter` constructor. Do not use this.
2615    pub fn new(
2616        symbol: Symbol,
2617        mode: IdentPrintMode,
2618        convert_dollar_crate: Option<Span>,
2619    ) -> IdentPrinter {
2620        IdentPrinter { symbol, mode, convert_dollar_crate }
2621    }
2622
2623    /// This implementation is supposed to be used when printing identifiers
2624    /// as a part of pretty-printing for larger AST pieces.
2625    /// Do not use this either.
2626    pub fn for_ast_ident(ident: Ident, mode: IdentPrintMode) -> IdentPrinter {
2627        IdentPrinter::new(ident.name, mode, Some(ident.span))
2628    }
2629}
2630
2631impl fmt::Display for IdentPrinter {
2632    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2633        let s = match self.mode {
2634            IdentPrintMode::Normal
2635                if self.symbol == kw::DollarCrate
2636                    && let Some(span) = self.convert_dollar_crate =>
2637            {
2638                let converted = span.ctxt().dollar_crate_name();
2639                if !converted.is_path_segment_keyword() {
2640                    f.write_str("::")?;
2641                }
2642                converted
2643            }
2644            IdentPrintMode::Normal => self.symbol,
2645            IdentPrintMode::RawIdent => {
2646                f.write_str("r#")?;
2647                self.symbol
2648            }
2649            IdentPrintMode::RawLifetime => {
2650                f.write_str("'r#")?;
2651                let s = self
2652                    .symbol
2653                    .as_str()
2654                    .strip_prefix("'")
2655                    .expect("only lifetime idents should be passed with RawLifetime mode");
2656                Symbol::intern(s)
2657            }
2658        };
2659        s.fmt(f)
2660    }
2661}
2662
2663/// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
2664/// construction for "local variable hygiene" comparisons.
2665///
2666/// Use this type when you need to compare identifiers according to macro_rules hygiene.
2667/// This ensures compile-time safety and avoids manual normalization calls.
2668#[derive(Copy, Clone, Eq, PartialEq, Hash)]
2669pub struct MacroRulesNormalizedIdent(Ident);
2670
2671impl MacroRulesNormalizedIdent {
2672    #[inline]
2673    pub fn new(ident: Ident) -> Self {
2674        MacroRulesNormalizedIdent(ident.normalize_to_macro_rules())
2675    }
2676}
2677
2678impl fmt::Debug for MacroRulesNormalizedIdent {
2679    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2680        fmt::Debug::fmt(&self.0, f)
2681    }
2682}
2683
2684impl fmt::Display for MacroRulesNormalizedIdent {
2685    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2686        fmt::Display::fmt(&self.0, f)
2687    }
2688}
2689
2690/// An newtype around `Ident` that calls [Ident::normalize_to_macros_2_0] on
2691/// construction for "item hygiene" comparisons.
2692///
2693/// Identifiers with same string value become same if they came from the same macro 2.0 macro
2694/// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
2695/// different macro 2.0 macros.
2696#[derive(Copy, Clone, Eq, PartialEq, Hash)]
2697pub struct Macros20NormalizedIdent(pub Ident);
2698
2699impl Macros20NormalizedIdent {
2700    #[inline]
2701    pub fn new(ident: Ident) -> Self {
2702        Macros20NormalizedIdent(ident.normalize_to_macros_2_0())
2703    }
2704
2705    // dummy_span does not need to be normalized, so we can use `Ident` directly
2706    pub fn with_dummy_span(name: Symbol) -> Self {
2707        Macros20NormalizedIdent(Ident::with_dummy_span(name))
2708    }
2709}
2710
2711impl fmt::Debug for Macros20NormalizedIdent {
2712    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2713        fmt::Debug::fmt(&self.0, f)
2714    }
2715}
2716
2717impl fmt::Display for Macros20NormalizedIdent {
2718    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2719        fmt::Display::fmt(&self.0, f)
2720    }
2721}
2722
2723/// By impl Deref, we can access the wrapped Ident as if it were a normal Ident
2724/// such as `norm_ident.name` instead of `norm_ident.0.name`.
2725impl Deref for Macros20NormalizedIdent {
2726    type Target = Ident;
2727    fn deref(&self) -> &Self::Target {
2728        &self.0
2729    }
2730}
2731
2732/// An interned UTF-8 string.
2733///
2734/// Internally, a `Symbol` is implemented as an index, and all operations
2735/// (including hashing, equality, and ordering) operate on that index. The use
2736/// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
2737/// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
2738///
2739/// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
2740/// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
2741#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
2742pub struct Symbol(SymbolIndex);
2743
2744// Used within both `Symbol` and `ByteSymbol`.
2745rustc_index::newtype_index! {
2746    #[orderable]
2747    struct SymbolIndex {}
2748}
2749
2750impl Symbol {
2751    /// Avoid this except for things like deserialization of previously
2752    /// serialized symbols, and testing. Use `intern` instead.
2753    pub const fn new(n: u32) -> Self {
2754        Symbol(SymbolIndex::from_u32(n))
2755    }
2756
2757    /// Maps a string to its interned representation.
2758    #[rustc_diagnostic_item = "SymbolIntern"]
2759    pub fn intern(str: &str) -> Self {
2760        with_session_globals(|session_globals| session_globals.symbol_interner.intern_str(str))
2761    }
2762
2763    /// Access the underlying string. This is a slowish operation because it
2764    /// requires locking the symbol interner.
2765    ///
2766    /// Note that the lifetime of the return value is a lie. It's not the same
2767    /// as `&self`, but actually tied to the lifetime of the underlying
2768    /// interner. Interners are long-lived, and there are very few of them, and
2769    /// this function is typically used for short-lived things, so in practice
2770    /// it works out ok.
2771    pub fn as_str(&self) -> &str {
2772        with_session_globals(|session_globals| unsafe {
2773            std::mem::transmute::<&str, &str>(session_globals.symbol_interner.get_str(*self))
2774        })
2775    }
2776
2777    pub fn as_u32(self) -> u32 {
2778        self.0.as_u32()
2779    }
2780
2781    pub fn is_empty(self) -> bool {
2782        self == sym::empty
2783    }
2784
2785    /// This method is supposed to be used in error messages, so it's expected to be
2786    /// identical to printing the original identifier token written in source code
2787    /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
2788    /// or edition, so we have to guess the rawness using the global edition.
2789    pub fn to_ident_string(self) -> String {
2790        // Avoid creating an empty identifier, because that asserts in debug builds.
2791        if self == sym::empty { String::new() } else { Ident::with_dummy_span(self).to_string() }
2792    }
2793}
2794
2795impl fmt::Debug for Symbol {
2796    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2797        fmt::Debug::fmt(self.as_str(), f)
2798    }
2799}
2800
2801impl fmt::Display for Symbol {
2802    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2803        fmt::Display::fmt(self.as_str(), f)
2804    }
2805}
2806
2807impl<CTX> HashStable<CTX> for Symbol {
2808    #[inline]
2809    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
2810        self.as_str().hash_stable(hcx, hasher);
2811    }
2812}
2813
2814impl<CTX> ToStableHashKey<CTX> for Symbol {
2815    type KeyType = String;
2816    #[inline]
2817    fn to_stable_hash_key(&self, _: &CTX) -> String {
2818        self.as_str().to_string()
2819    }
2820}
2821
2822impl StableCompare for Symbol {
2823    const CAN_USE_UNSTABLE_SORT: bool = true;
2824
2825    fn stable_cmp(&self, other: &Self) -> std::cmp::Ordering {
2826        self.as_str().cmp(other.as_str())
2827    }
2828}
2829
2830/// Like `Symbol`, but for byte strings. `ByteSymbol` is used less widely, so
2831/// it has fewer operations defined than `Symbol`.
2832#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
2833pub struct ByteSymbol(SymbolIndex);
2834
2835impl ByteSymbol {
2836    /// Avoid this except for things like deserialization of previously
2837    /// serialized symbols, and testing. Use `intern` instead.
2838    pub const fn new(n: u32) -> Self {
2839        ByteSymbol(SymbolIndex::from_u32(n))
2840    }
2841
2842    /// Maps a string to its interned representation.
2843    pub fn intern(byte_str: &[u8]) -> Self {
2844        with_session_globals(|session_globals| {
2845            session_globals.symbol_interner.intern_byte_str(byte_str)
2846        })
2847    }
2848
2849    /// Like `Symbol::as_str`.
2850    pub fn as_byte_str(&self) -> &[u8] {
2851        with_session_globals(|session_globals| unsafe {
2852            std::mem::transmute::<&[u8], &[u8]>(session_globals.symbol_interner.get_byte_str(*self))
2853        })
2854    }
2855
2856    pub fn as_u32(self) -> u32 {
2857        self.0.as_u32()
2858    }
2859}
2860
2861impl fmt::Debug for ByteSymbol {
2862    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2863        fmt::Debug::fmt(self.as_byte_str(), f)
2864    }
2865}
2866
2867impl<CTX> HashStable<CTX> for ByteSymbol {
2868    #[inline]
2869    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
2870        self.as_byte_str().hash_stable(hcx, hasher);
2871    }
2872}
2873
2874// Interner used for both `Symbol`s and `ByteSymbol`s. If a string and a byte
2875// string with identical contents (e.g. "foo" and b"foo") are both interned,
2876// only one copy will be stored and the resulting `Symbol` and `ByteSymbol`
2877// will have the same index.
2878pub(crate) struct Interner(Lock<InternerInner>);
2879
2880// The `&'static [u8]`s in this type actually point into the arena.
2881//
2882// This type is private to prevent accidentally constructing more than one
2883// `Interner` on the same thread, which makes it easy to mix up `Symbol`s
2884// between `Interner`s.
2885struct InternerInner {
2886    arena: DroplessArena,
2887    byte_strs: FxIndexSet<&'static [u8]>,
2888}
2889
2890impl Interner {
2891    // These arguments are `&str`, but because of the sharing, we are
2892    // effectively pre-interning all these strings for both `Symbol` and
2893    // `ByteSymbol`.
2894    fn prefill(init: &[&'static str], extra: &[&'static str]) -> Self {
2895        let byte_strs = FxIndexSet::from_iter(
2896            init.iter().copied().chain(extra.iter().copied()).map(|str| str.as_bytes()),
2897        );
2898
2899        // The order in which duplicates are reported is irrelevant.
2900        #[expect(rustc::potential_query_instability)]
2901        if byte_strs.len() != init.len() + extra.len() {
2902            panic!(
2903                "duplicate symbols in the rustc symbol list and the extra symbols added by the driver: {:?}",
2904                FxHashSet::intersection(
2905                    &init.iter().copied().collect(),
2906                    &extra.iter().copied().collect(),
2907                )
2908                .collect::<Vec<_>>()
2909            )
2910        }
2911
2912        Interner(Lock::new(InternerInner { arena: Default::default(), byte_strs }))
2913    }
2914
2915    fn intern_str(&self, str: &str) -> Symbol {
2916        Symbol::new(self.intern_inner(str.as_bytes()))
2917    }
2918
2919    fn intern_byte_str(&self, byte_str: &[u8]) -> ByteSymbol {
2920        ByteSymbol::new(self.intern_inner(byte_str))
2921    }
2922
2923    #[inline]
2924    fn intern_inner(&self, byte_str: &[u8]) -> u32 {
2925        let mut inner = self.0.lock();
2926        if let Some(idx) = inner.byte_strs.get_index_of(byte_str) {
2927            return idx as u32;
2928        }
2929
2930        let byte_str: &[u8] = inner.arena.alloc_slice(byte_str);
2931
2932        // SAFETY: we can extend the arena allocation to `'static` because we
2933        // only access these while the arena is still alive.
2934        let byte_str: &'static [u8] = unsafe { &*(byte_str as *const [u8]) };
2935
2936        // This second hash table lookup can be avoided by using `RawEntryMut`,
2937        // but this code path isn't hot enough for it to be worth it. See
2938        // #91445 for details.
2939        let (idx, is_new) = inner.byte_strs.insert_full(byte_str);
2940        debug_assert!(is_new); // due to the get_index_of check above
2941
2942        idx as u32
2943    }
2944
2945    /// Get the symbol as a string.
2946    ///
2947    /// [`Symbol::as_str()`] should be used in preference to this function.
2948    fn get_str(&self, symbol: Symbol) -> &str {
2949        let byte_str = self.get_inner(symbol.0.as_usize());
2950        // SAFETY: known to be a UTF8 string because it's a `Symbol`.
2951        unsafe { str::from_utf8_unchecked(byte_str) }
2952    }
2953
2954    /// Get the symbol as a string.
2955    ///
2956    /// [`ByteSymbol::as_byte_str()`] should be used in preference to this function.
2957    fn get_byte_str(&self, symbol: ByteSymbol) -> &[u8] {
2958        self.get_inner(symbol.0.as_usize())
2959    }
2960
2961    fn get_inner(&self, index: usize) -> &[u8] {
2962        self.0.lock().byte_strs.get_index(index).unwrap()
2963    }
2964}
2965
2966// This module has a very short name because it's used a lot.
2967/// This module contains all the defined keyword `Symbol`s.
2968///
2969/// Given that `kw` is imported, use them like `kw::keyword_name`.
2970/// For example `kw::Loop` or `kw::Break`.
2971pub mod kw {
2972    pub use super::kw_generated::*;
2973}
2974
2975// This module has a very short name because it's used a lot.
2976/// This module contains all the defined non-keyword `Symbol`s.
2977///
2978/// Given that `sym` is imported, use them like `sym::symbol_name`.
2979/// For example `sym::rustfmt` or `sym::u8`.
2980pub mod sym {
2981    // Used from a macro in `librustc_feature/accepted.rs`
2982    use super::Symbol;
2983    pub use super::kw::MacroRules as macro_rules;
2984    #[doc(inline)]
2985    pub use super::sym_generated::*;
2986
2987    /// Get the symbol for an integer.
2988    ///
2989    /// The first few non-negative integers each have a static symbol and therefore
2990    /// are fast.
2991    pub fn integer<N: TryInto<usize> + Copy + itoa::Integer>(n: N) -> Symbol {
2992        if let Result::Ok(idx) = n.try_into() {
2993            if idx < 10 {
2994                return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
2995            }
2996        }
2997        let mut buffer = itoa::Buffer::new();
2998        let printed = buffer.format(n);
2999        Symbol::intern(printed)
3000    }
3001}
3002
3003impl Symbol {
3004    fn is_special(self) -> bool {
3005        self <= kw::Underscore
3006    }
3007
3008    fn is_used_keyword_always(self) -> bool {
3009        self >= kw::As && self <= kw::While
3010    }
3011
3012    fn is_unused_keyword_always(self) -> bool {
3013        self >= kw::Abstract && self <= kw::Yield
3014    }
3015
3016    fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
3017        (self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
3018    }
3019
3020    fn is_unused_keyword_conditional(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
3021        self == kw::Gen && edition().at_least_rust_2024()
3022            || self == kw::Try && edition().at_least_rust_2018()
3023    }
3024
3025    pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
3026        self.is_special()
3027            || self.is_used_keyword_always()
3028            || self.is_unused_keyword_always()
3029            || self.is_used_keyword_conditional(edition)
3030            || self.is_unused_keyword_conditional(edition)
3031    }
3032
3033    pub fn is_weak(self) -> bool {
3034        self >= kw::Auto && self <= kw::Yeet
3035    }
3036
3037    /// A keyword or reserved identifier that can be used as a path segment.
3038    pub fn is_path_segment_keyword(self) -> bool {
3039        self == kw::Super
3040            || self == kw::SelfLower
3041            || self == kw::SelfUpper
3042            || self == kw::Crate
3043            || self == kw::PathRoot
3044            || self == kw::DollarCrate
3045    }
3046
3047    /// Returns `true` if the symbol is `true` or `false`.
3048    pub fn is_bool_lit(self) -> bool {
3049        self == kw::True || self == kw::False
3050    }
3051
3052    /// Returns `true` if this symbol can be a raw identifier.
3053    pub fn can_be_raw(self) -> bool {
3054        self != sym::empty && self != kw::Underscore && !self.is_path_segment_keyword()
3055    }
3056
3057    /// Was this symbol index predefined in the compiler's `symbols!` macro?
3058    /// Note: this applies to both `Symbol`s and `ByteSymbol`s, which is why it
3059    /// takes a `u32` argument instead of a `&self` argument. Use with care.
3060    pub fn is_predefined(index: u32) -> bool {
3061        index < PREDEFINED_SYMBOLS_COUNT
3062    }
3063}
3064
3065impl Ident {
3066    /// Returns `true` for reserved identifiers used internally for elided lifetimes,
3067    /// unnamed method parameters, crate root module, error recovery etc.
3068    pub fn is_special(self) -> bool {
3069        self.name.is_special()
3070    }
3071
3072    /// Returns `true` if the token is a keyword used in the language.
3073    pub fn is_used_keyword(self) -> bool {
3074        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
3075        self.name.is_used_keyword_always()
3076            || self.name.is_used_keyword_conditional(|| self.span.edition())
3077    }
3078
3079    /// Returns `true` if the token is a keyword reserved for possible future use.
3080    pub fn is_unused_keyword(self) -> bool {
3081        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
3082        self.name.is_unused_keyword_always()
3083            || self.name.is_unused_keyword_conditional(|| self.span.edition())
3084    }
3085
3086    /// Returns `true` if the token is either a special identifier or a keyword.
3087    pub fn is_reserved(self) -> bool {
3088        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
3089        self.name.is_reserved(|| self.span.edition())
3090    }
3091
3092    /// A keyword or reserved identifier that can be used as a path segment.
3093    pub fn is_path_segment_keyword(self) -> bool {
3094        self.name.is_path_segment_keyword()
3095    }
3096
3097    /// We see this identifier in a normal identifier position, like variable name or a type.
3098    /// How was it written originally? Did it use the raw form? Let's try to guess.
3099    pub fn is_raw_guess(self) -> bool {
3100        self.name.can_be_raw() && self.is_reserved()
3101    }
3102
3103    /// Given the name of a lifetime without the first quote (`'`),
3104    /// returns whether the lifetime name is reserved (therefore invalid)
3105    pub fn is_reserved_lifetime(self) -> bool {
3106        self.is_reserved() && ![kw::Underscore, kw::Static].contains(&self.name)
3107    }
3108
3109    pub fn is_raw_lifetime_guess(self) -> bool {
3110        // Check that the name isn't just a single quote.
3111        // `self.without_first_quote()` would return empty ident, which triggers debug assert.
3112        if self.name.as_str() == "'" {
3113            return false;
3114        }
3115        let ident_without_apostrophe = self.without_first_quote();
3116        ident_without_apostrophe.name != self.name
3117            && ident_without_apostrophe.name.can_be_raw()
3118            && ident_without_apostrophe.is_reserved_lifetime()
3119    }
3120
3121    pub fn guess_print_mode(self) -> IdentPrintMode {
3122        if self.is_raw_lifetime_guess() {
3123            IdentPrintMode::RawLifetime
3124        } else if self.is_raw_guess() {
3125            IdentPrintMode::RawIdent
3126        } else {
3127            IdentPrintMode::Normal
3128        }
3129    }
3130
3131    /// Whether this would be the identifier for a tuple field like `self.0`, as
3132    /// opposed to a named field like `self.thing`.
3133    pub fn is_numeric(self) -> bool {
3134        self.as_str().bytes().all(|b| b.is_ascii_digit())
3135    }
3136}
3137
3138/// Collect all the keywords in a given edition into a vector.
3139///
3140/// *Note:* Please update this if a new keyword is added beyond the current
3141/// range.
3142pub fn used_keywords(edition: impl Copy + FnOnce() -> Edition) -> Vec<Symbol> {
3143    (kw::DollarCrate.as_u32()..kw::Yeet.as_u32())
3144        .filter_map(|kw| {
3145            let kw = Symbol::new(kw);
3146            if kw.is_used_keyword_always() || kw.is_used_keyword_conditional(edition) {
3147                Some(kw)
3148            } else {
3149                None
3150            }
3151        })
3152        .collect()
3153}