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