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