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