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