rustc_span/
symbol.rs

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