rustc_span/
symbol.rs

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