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