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_epsilon,
941        f128_nan,
942        f16,
943        f16_epsilon,
944        f16_nan,
945        f16c_target_feature,
946        f32,
947        f32_epsilon,
948        f32_legacy_const_digits,
949        f32_legacy_const_epsilon,
950        f32_legacy_const_infinity,
951        f32_legacy_const_mantissa_dig,
952        f32_legacy_const_max,
953        f32_legacy_const_max_10_exp,
954        f32_legacy_const_max_exp,
955        f32_legacy_const_min,
956        f32_legacy_const_min_10_exp,
957        f32_legacy_const_min_exp,
958        f32_legacy_const_min_positive,
959        f32_legacy_const_nan,
960        f32_legacy_const_neg_infinity,
961        f32_legacy_const_radix,
962        f32_nan,
963        f64,
964        f64_epsilon,
965        f64_legacy_const_digits,
966        f64_legacy_const_epsilon,
967        f64_legacy_const_infinity,
968        f64_legacy_const_mantissa_dig,
969        f64_legacy_const_max,
970        f64_legacy_const_max_10_exp,
971        f64_legacy_const_max_exp,
972        f64_legacy_const_min,
973        f64_legacy_const_min_10_exp,
974        f64_legacy_const_min_exp,
975        f64_legacy_const_min_positive,
976        f64_legacy_const_nan,
977        f64_legacy_const_neg_infinity,
978        f64_legacy_const_radix,
979        f64_nan,
980        fabsf128,
981        fabsf16,
982        fabsf32,
983        fabsf64,
984        fadd_algebraic,
985        fadd_fast,
986        fake_variadic,
987        fallback,
988        fdiv_algebraic,
989        fdiv_fast,
990        feature,
991        fence,
992        ferris: "🦀",
993        fetch_update,
994        ffi,
995        ffi_const,
996        ffi_pure,
997        ffi_returns_twice,
998        field,
999        field_init_shorthand,
1000        file,
1001        file_options,
1002        flags,
1003        float,
1004        float_to_int_unchecked,
1005        floorf128,
1006        floorf16,
1007        floorf32,
1008        floorf64,
1009        fmaf128,
1010        fmaf16,
1011        fmaf32,
1012        fmaf64,
1013        fmt,
1014        fmt_debug,
1015        fmul_algebraic,
1016        fmul_fast,
1017        fmuladdf128,
1018        fmuladdf16,
1019        fmuladdf32,
1020        fmuladdf64,
1021        fn_align,
1022        fn_body,
1023        fn_delegation,
1024        fn_must_use,
1025        fn_mut,
1026        fn_once,
1027        fn_once_output,
1028        fn_ptr_addr,
1029        fn_ptr_trait,
1030        forbid,
1031        forget,
1032        format,
1033        format_args,
1034        format_args_capture,
1035        format_args_macro,
1036        format_args_nl,
1037        format_argument,
1038        format_arguments,
1039        format_count,
1040        format_macro,
1041        format_placeholder,
1042        format_unsafe_arg,
1043        freeze,
1044        freeze_impls,
1045        freg,
1046        frem_algebraic,
1047        frem_fast,
1048        from,
1049        from_desugaring,
1050        from_fn,
1051        from_iter,
1052        from_iter_fn,
1053        from_output,
1054        from_residual,
1055        from_size_align_unchecked,
1056        from_str_method,
1057        from_u16,
1058        from_usize,
1059        from_yeet,
1060        frontmatter,
1061        fs_create_dir,
1062        fsub_algebraic,
1063        fsub_fast,
1064        fsxr,
1065        full,
1066        fundamental,
1067        fused_iterator,
1068        future,
1069        future_drop_poll,
1070        future_output,
1071        future_trait,
1072        gdb_script_file,
1073        ge,
1074        gen_blocks,
1075        gen_future,
1076        generator_clone,
1077        generators,
1078        generic_arg_infer,
1079        generic_assert,
1080        generic_associated_types,
1081        generic_associated_types_extended,
1082        generic_const_exprs,
1083        generic_const_items,
1084        generic_const_parameter_types,
1085        generic_param_attrs,
1086        generic_pattern_types,
1087        get_context,
1088        global_alloc_ty,
1089        global_allocator,
1090        global_asm,
1091        global_registration,
1092        globs,
1093        gt,
1094        guard_patterns,
1095        half_open_range_patterns,
1096        half_open_range_patterns_in_slices,
1097        hash,
1098        hashmap_contains_key,
1099        hashmap_drain_ty,
1100        hashmap_insert,
1101        hashmap_iter_mut_ty,
1102        hashmap_iter_ty,
1103        hashmap_keys_ty,
1104        hashmap_values_mut_ty,
1105        hashmap_values_ty,
1106        hashset_drain_ty,
1107        hashset_iter,
1108        hashset_iter_ty,
1109        hexagon_target_feature,
1110        hidden,
1111        hint,
1112        homogeneous_aggregate,
1113        host,
1114        html_favicon_url,
1115        html_logo_url,
1116        html_no_source,
1117        html_playground_url,
1118        html_root_url,
1119        hwaddress,
1120        i,
1121        i128,
1122        i128_legacy_const_max,
1123        i128_legacy_const_min,
1124        i128_legacy_fn_max_value,
1125        i128_legacy_fn_min_value,
1126        i128_legacy_mod,
1127        i128_type,
1128        i16,
1129        i16_legacy_const_max,
1130        i16_legacy_const_min,
1131        i16_legacy_fn_max_value,
1132        i16_legacy_fn_min_value,
1133        i16_legacy_mod,
1134        i32,
1135        i32_legacy_const_max,
1136        i32_legacy_const_min,
1137        i32_legacy_fn_max_value,
1138        i32_legacy_fn_min_value,
1139        i32_legacy_mod,
1140        i64,
1141        i64_legacy_const_max,
1142        i64_legacy_const_min,
1143        i64_legacy_fn_max_value,
1144        i64_legacy_fn_min_value,
1145        i64_legacy_mod,
1146        i8,
1147        i8_legacy_const_max,
1148        i8_legacy_const_min,
1149        i8_legacy_fn_max_value,
1150        i8_legacy_fn_min_value,
1151        i8_legacy_mod,
1152        ident,
1153        if_let,
1154        if_let_guard,
1155        if_let_rescope,
1156        if_while_or_patterns,
1157        ignore,
1158        impl_header_lifetime_elision,
1159        impl_lint_pass,
1160        impl_trait_in_assoc_type,
1161        impl_trait_in_bindings,
1162        impl_trait_in_fn_trait_return,
1163        impl_trait_projections,
1164        implement_via_object,
1165        implied_by,
1166        import,
1167        import_name_type,
1168        import_shadowing,
1169        import_trait_associated_functions,
1170        imported_main,
1171        in_band_lifetimes,
1172        include,
1173        include_bytes,
1174        include_bytes_macro,
1175        include_str,
1176        include_str_macro,
1177        inclusive_range_syntax,
1178        index,
1179        index_mut,
1180        infer_outlives_requirements,
1181        infer_static_outlives_requirements,
1182        inherent_associated_types,
1183        inherit,
1184        inlateout,
1185        inline,
1186        inline_const,
1187        inline_const_pat,
1188        inout,
1189        instant_now,
1190        instruction_set,
1191        integer_: "integer", // underscore to avoid clashing with the function `sym::integer` below
1192        integral,
1193        internal_features,
1194        into_async_iter_into_iter,
1195        into_future,
1196        into_iter,
1197        intra_doc_pointers,
1198        intrinsics,
1199        intrinsics_unaligned_volatile_load,
1200        intrinsics_unaligned_volatile_store,
1201        io_stderr,
1202        io_stdout,
1203        irrefutable_let_patterns,
1204        is,
1205        is_val_statically_known,
1206        isa_attribute,
1207        isize,
1208        isize_legacy_const_max,
1209        isize_legacy_const_min,
1210        isize_legacy_fn_max_value,
1211        isize_legacy_fn_min_value,
1212        isize_legacy_mod,
1213        issue,
1214        issue_5723_bootstrap,
1215        issue_tracker_base_url,
1216        item,
1217        item_like_imports,
1218        iter,
1219        iter_cloned,
1220        iter_copied,
1221        iter_filter,
1222        iter_mut,
1223        iter_repeat,
1224        iterator,
1225        iterator_collect_fn,
1226        kcfi,
1227        keylocker_x86,
1228        keyword,
1229        kind,
1230        kreg,
1231        kreg0,
1232        label,
1233        label_break_value,
1234        lahfsahf_target_feature,
1235        lang,
1236        lang_items,
1237        large_assignments,
1238        lateout,
1239        lazy_normalization_consts,
1240        lazy_type_alias,
1241        le,
1242        legacy_receiver,
1243        len,
1244        let_chains,
1245        let_else,
1246        lhs,
1247        lib,
1248        libc,
1249        lifetime,
1250        lifetime_capture_rules_2024,
1251        lifetimes,
1252        likely,
1253        line,
1254        link,
1255        link_arg_attribute,
1256        link_args,
1257        link_cfg,
1258        link_llvm_intrinsics,
1259        link_name,
1260        link_ordinal,
1261        link_section,
1262        linkage,
1263        linker,
1264        linker_messages,
1265        lint_reasons,
1266        literal,
1267        load,
1268        loaded_from_disk,
1269        local,
1270        local_inner_macros,
1271        log10f128,
1272        log10f16,
1273        log10f32,
1274        log10f64,
1275        log2f128,
1276        log2f16,
1277        log2f32,
1278        log2f64,
1279        log_syntax,
1280        logf128,
1281        logf16,
1282        logf32,
1283        logf64,
1284        loongarch_target_feature,
1285        loop_break_value,
1286        lt,
1287        m68k_target_feature,
1288        macro_at_most_once_rep,
1289        macro_attributes_in_derive_output,
1290        macro_escape,
1291        macro_export,
1292        macro_lifetime_matcher,
1293        macro_literal_matcher,
1294        macro_metavar_expr,
1295        macro_metavar_expr_concat,
1296        macro_reexport,
1297        macro_use,
1298        macro_vis_matcher,
1299        macros_in_extern,
1300        main,
1301        managed_boxes,
1302        manually_drop,
1303        map,
1304        map_err,
1305        marker,
1306        marker_trait_attr,
1307        masked,
1308        match_beginning_vert,
1309        match_default_bindings,
1310        matches_macro,
1311        maximumf128,
1312        maximumf16,
1313        maximumf32,
1314        maximumf64,
1315        maxnumf128,
1316        maxnumf16,
1317        maxnumf32,
1318        maxnumf64,
1319        may_dangle,
1320        may_unwind,
1321        maybe_uninit,
1322        maybe_uninit_uninit,
1323        maybe_uninit_zeroed,
1324        mem_discriminant,
1325        mem_drop,
1326        mem_forget,
1327        mem_replace,
1328        mem_size_of,
1329        mem_size_of_val,
1330        mem_swap,
1331        mem_uninitialized,
1332        mem_variant_count,
1333        mem_zeroed,
1334        member_constraints,
1335        memory,
1336        memtag,
1337        message,
1338        meta,
1339        metadata_type,
1340        min_align_of,
1341        min_align_of_val,
1342        min_const_fn,
1343        min_const_generics,
1344        min_const_unsafe_fn,
1345        min_exhaustive_patterns,
1346        min_generic_const_args,
1347        min_specialization,
1348        min_type_alias_impl_trait,
1349        minimumf128,
1350        minimumf16,
1351        minimumf32,
1352        minimumf64,
1353        minnumf128,
1354        minnumf16,
1355        minnumf32,
1356        minnumf64,
1357        mips_target_feature,
1358        mir_assume,
1359        mir_basic_block,
1360        mir_call,
1361        mir_cast_ptr_to_ptr,
1362        mir_cast_transmute,
1363        mir_checked,
1364        mir_copy_for_deref,
1365        mir_debuginfo,
1366        mir_deinit,
1367        mir_discriminant,
1368        mir_drop,
1369        mir_field,
1370        mir_goto,
1371        mir_len,
1372        mir_make_place,
1373        mir_move,
1374        mir_offset,
1375        mir_ptr_metadata,
1376        mir_retag,
1377        mir_return,
1378        mir_return_to,
1379        mir_set_discriminant,
1380        mir_static,
1381        mir_static_mut,
1382        mir_storage_dead,
1383        mir_storage_live,
1384        mir_tail_call,
1385        mir_unreachable,
1386        mir_unwind_cleanup,
1387        mir_unwind_continue,
1388        mir_unwind_resume,
1389        mir_unwind_terminate,
1390        mir_unwind_terminate_reason,
1391        mir_unwind_unreachable,
1392        mir_variant,
1393        miri,
1394        mmx_reg,
1395        modifiers,
1396        module,
1397        module_path,
1398        more_maybe_bounds,
1399        more_qualified_paths,
1400        more_struct_aliases,
1401        movbe_target_feature,
1402        move_ref_pattern,
1403        move_size_limit,
1404        movrs_target_feature,
1405        mul,
1406        mul_assign,
1407        mul_with_overflow,
1408        multiple_supertrait_upcastable,
1409        must_not_suspend,
1410        must_use,
1411        mut_preserve_binding_mode_2024,
1412        mut_ref,
1413        naked,
1414        naked_asm,
1415        naked_functions,
1416        naked_functions_rustic_abi,
1417        naked_functions_target_feature,
1418        name,
1419        names,
1420        native_link_modifiers,
1421        native_link_modifiers_as_needed,
1422        native_link_modifiers_bundle,
1423        native_link_modifiers_verbatim,
1424        native_link_modifiers_whole_archive,
1425        natvis_file,
1426        ne,
1427        needs_allocator,
1428        needs_drop,
1429        needs_panic_runtime,
1430        neg,
1431        negate_unsigned,
1432        negative_bounds,
1433        negative_impls,
1434        neon,
1435        nested,
1436        never,
1437        never_patterns,
1438        never_type,
1439        never_type_fallback,
1440        new,
1441        new_binary,
1442        new_const,
1443        new_debug,
1444        new_debug_noop,
1445        new_display,
1446        new_lower_exp,
1447        new_lower_hex,
1448        new_octal,
1449        new_pointer,
1450        new_range,
1451        new_unchecked,
1452        new_upper_exp,
1453        new_upper_hex,
1454        new_v1,
1455        new_v1_formatted,
1456        next,
1457        niko,
1458        nll,
1459        no,
1460        no_builtins,
1461        no_core,
1462        no_coverage,
1463        no_crate_inject,
1464        no_debug,
1465        no_default_passes,
1466        no_implicit_prelude,
1467        no_inline,
1468        no_link,
1469        no_main,
1470        no_mangle,
1471        no_sanitize,
1472        no_stack_check,
1473        no_std,
1474        nomem,
1475        non_ascii_idents,
1476        non_exhaustive,
1477        non_exhaustive_omitted_patterns_lint,
1478        non_lifetime_binders,
1479        non_modrs_mods,
1480        none,
1481        nontemporal_store,
1482        noop_method_borrow,
1483        noop_method_clone,
1484        noop_method_deref,
1485        noreturn,
1486        nostack,
1487        not,
1488        notable_trait,
1489        note,
1490        object_safe_for_dispatch,
1491        of,
1492        off,
1493        offset,
1494        offset_of,
1495        offset_of_enum,
1496        offset_of_nested,
1497        offset_of_slice,
1498        ok_or_else,
1499        omit_gdb_pretty_printer_section,
1500        on,
1501        on_unimplemented,
1502        opaque,
1503        opaque_module_name_placeholder: "<opaque>",
1504        open_options_new,
1505        ops,
1506        opt_out_copy,
1507        optimize,
1508        optimize_attribute,
1509        optin_builtin_traits,
1510        option,
1511        option_env,
1512        option_expect,
1513        option_unwrap,
1514        options,
1515        or,
1516        or_patterns,
1517        ord_cmp_method,
1518        os_str_to_os_string,
1519        os_string_as_os_str,
1520        other,
1521        out,
1522        overflow_checks,
1523        overlapping_marker_traits,
1524        owned_box,
1525        packed,
1526        packed_bundled_libs,
1527        panic,
1528        panic_2015,
1529        panic_2021,
1530        panic_abort,
1531        panic_any,
1532        panic_bounds_check,
1533        panic_cannot_unwind,
1534        panic_const_add_overflow,
1535        panic_const_async_fn_resumed,
1536        panic_const_async_fn_resumed_drop,
1537        panic_const_async_fn_resumed_panic,
1538        panic_const_async_gen_fn_resumed,
1539        panic_const_async_gen_fn_resumed_drop,
1540        panic_const_async_gen_fn_resumed_panic,
1541        panic_const_coroutine_resumed,
1542        panic_const_coroutine_resumed_drop,
1543        panic_const_coroutine_resumed_panic,
1544        panic_const_div_by_zero,
1545        panic_const_div_overflow,
1546        panic_const_gen_fn_none,
1547        panic_const_gen_fn_none_drop,
1548        panic_const_gen_fn_none_panic,
1549        panic_const_mul_overflow,
1550        panic_const_neg_overflow,
1551        panic_const_rem_by_zero,
1552        panic_const_rem_overflow,
1553        panic_const_shl_overflow,
1554        panic_const_shr_overflow,
1555        panic_const_sub_overflow,
1556        panic_fmt,
1557        panic_handler,
1558        panic_impl,
1559        panic_implementation,
1560        panic_in_cleanup,
1561        panic_info,
1562        panic_location,
1563        panic_misaligned_pointer_dereference,
1564        panic_nounwind,
1565        panic_null_pointer_dereference,
1566        panic_runtime,
1567        panic_str_2015,
1568        panic_unwind,
1569        panicking,
1570        param_attrs,
1571        parent_label,
1572        partial_cmp,
1573        partial_ord,
1574        passes,
1575        pat,
1576        pat_param,
1577        patchable_function_entry,
1578        path,
1579        path_main_separator,
1580        path_to_pathbuf,
1581        pathbuf_as_path,
1582        pattern_complexity_limit,
1583        pattern_parentheses,
1584        pattern_type,
1585        pattern_type_range_trait,
1586        pattern_types,
1587        permissions_from_mode,
1588        phantom_data,
1589        pic,
1590        pie,
1591        pin,
1592        pin_ergonomics,
1593        platform_intrinsics,
1594        plugin,
1595        plugin_registrar,
1596        plugins,
1597        pointee,
1598        pointee_trait,
1599        pointer,
1600        pointer_like,
1601        poll,
1602        poll_next,
1603        position,
1604        post_dash_lto: "post-lto",
1605        postfix_match,
1606        powerpc_target_feature,
1607        powf128,
1608        powf16,
1609        powf32,
1610        powf64,
1611        powif128,
1612        powif16,
1613        powif32,
1614        powif64,
1615        pre_dash_lto: "pre-lto",
1616        precise_capturing,
1617        precise_capturing_in_traits,
1618        precise_pointer_size_matching,
1619        precision,
1620        pref_align_of,
1621        prefetch_read_data,
1622        prefetch_read_instruction,
1623        prefetch_write_data,
1624        prefetch_write_instruction,
1625        prefix_nops,
1626        preg,
1627        prelude,
1628        prelude_import,
1629        preserves_flags,
1630        prfchw_target_feature,
1631        print_macro,
1632        println_macro,
1633        proc_dash_macro: "proc-macro",
1634        proc_macro,
1635        proc_macro_attribute,
1636        proc_macro_derive,
1637        proc_macro_expr,
1638        proc_macro_gen,
1639        proc_macro_hygiene,
1640        proc_macro_internals,
1641        proc_macro_mod,
1642        proc_macro_non_items,
1643        proc_macro_path_invoc,
1644        process_abort,
1645        process_exit,
1646        profiler_builtins,
1647        profiler_runtime,
1648        ptr,
1649        ptr_cast,
1650        ptr_cast_const,
1651        ptr_cast_mut,
1652        ptr_const_is_null,
1653        ptr_copy,
1654        ptr_copy_nonoverlapping,
1655        ptr_eq,
1656        ptr_from_ref,
1657        ptr_guaranteed_cmp,
1658        ptr_is_null,
1659        ptr_mask,
1660        ptr_metadata,
1661        ptr_null,
1662        ptr_null_mut,
1663        ptr_offset_from,
1664        ptr_offset_from_unsigned,
1665        ptr_read,
1666        ptr_read_unaligned,
1667        ptr_read_volatile,
1668        ptr_replace,
1669        ptr_slice_from_raw_parts,
1670        ptr_slice_from_raw_parts_mut,
1671        ptr_swap,
1672        ptr_swap_nonoverlapping,
1673        ptr_unique,
1674        ptr_write,
1675        ptr_write_bytes,
1676        ptr_write_unaligned,
1677        ptr_write_volatile,
1678        pub_macro_rules,
1679        pub_restricted,
1680        public,
1681        pure,
1682        pushpop_unsafe,
1683        qreg,
1684        qreg_low4,
1685        qreg_low8,
1686        quad_precision_float,
1687        question_mark,
1688        quote,
1689        range_inclusive_new,
1690        raw_dylib,
1691        raw_dylib_elf,
1692        raw_eq,
1693        raw_identifiers,
1694        raw_ref_op,
1695        re_rebalance_coherence,
1696        read_enum,
1697        read_enum_variant,
1698        read_enum_variant_arg,
1699        read_struct,
1700        read_struct_field,
1701        read_via_copy,
1702        readonly,
1703        realloc,
1704        reason,
1705        receiver,
1706        receiver_target,
1707        recursion_limit,
1708        reexport_test_harness_main,
1709        ref_pat_eat_one_layer_2024,
1710        ref_pat_eat_one_layer_2024_structural,
1711        ref_pat_everywhere,
1712        ref_unwind_safe_trait,
1713        reference,
1714        reflect,
1715        reg,
1716        reg16,
1717        reg32,
1718        reg64,
1719        reg_abcd,
1720        reg_addr,
1721        reg_byte,
1722        reg_data,
1723        reg_iw,
1724        reg_nonzero,
1725        reg_pair,
1726        reg_ptr,
1727        reg_upper,
1728        register_attr,
1729        register_tool,
1730        relaxed_adts,
1731        relaxed_struct_unsize,
1732        relocation_model,
1733        rem,
1734        rem_assign,
1735        repr,
1736        repr128,
1737        repr_align,
1738        repr_align_enum,
1739        repr_packed,
1740        repr_simd,
1741        repr_transparent,
1742        require,
1743        reserve_x18: "reserve-x18",
1744        residual,
1745        result,
1746        result_ffi_guarantees,
1747        result_ok_method,
1748        resume,
1749        return_position_impl_trait_in_trait,
1750        return_type_notation,
1751        rhs,
1752        riscv_target_feature,
1753        rlib,
1754        ropi,
1755        ropi_rwpi: "ropi-rwpi",
1756        rotate_left,
1757        rotate_right,
1758        round_ties_even_f128,
1759        round_ties_even_f16,
1760        round_ties_even_f32,
1761        round_ties_even_f64,
1762        roundf128,
1763        roundf16,
1764        roundf32,
1765        roundf64,
1766        rt,
1767        rtm_target_feature,
1768        rust,
1769        rust_2015,
1770        rust_2018,
1771        rust_2018_preview,
1772        rust_2021,
1773        rust_2024,
1774        rust_analyzer,
1775        rust_begin_unwind,
1776        rust_cold_cc,
1777        rust_eh_catch_typeinfo,
1778        rust_eh_personality,
1779        rust_future,
1780        rust_logo,
1781        rust_out,
1782        rustc,
1783        rustc_abi,
1784        rustc_allocator,
1785        rustc_allocator_zeroed,
1786        rustc_allow_const_fn_unstable,
1787        rustc_allow_incoherent_impl,
1788        rustc_allowed_through_unstable_modules,
1789        rustc_as_ptr,
1790        rustc_attrs,
1791        rustc_autodiff,
1792        rustc_builtin_macro,
1793        rustc_capture_analysis,
1794        rustc_clean,
1795        rustc_coherence_is_core,
1796        rustc_coinductive,
1797        rustc_confusables,
1798        rustc_const_panic_str,
1799        rustc_const_stable,
1800        rustc_const_stable_indirect,
1801        rustc_const_unstable,
1802        rustc_conversion_suggestion,
1803        rustc_deallocator,
1804        rustc_def_path,
1805        rustc_default_body_unstable,
1806        rustc_delayed_bug_from_inside_query,
1807        rustc_deny_explicit_impl,
1808        rustc_deprecated_safe_2024,
1809        rustc_diagnostic_item,
1810        rustc_diagnostic_macros,
1811        rustc_dirty,
1812        rustc_do_not_const_check,
1813        rustc_do_not_implement_via_object,
1814        rustc_doc_primitive,
1815        rustc_driver,
1816        rustc_dummy,
1817        rustc_dump_def_parents,
1818        rustc_dump_item_bounds,
1819        rustc_dump_predicates,
1820        rustc_dump_user_args,
1821        rustc_dump_vtable,
1822        rustc_effective_visibility,
1823        rustc_evaluate_where_clauses,
1824        rustc_expected_cgu_reuse,
1825        rustc_force_inline,
1826        rustc_has_incoherent_inherent_impls,
1827        rustc_hidden_type_of_opaques,
1828        rustc_if_this_changed,
1829        rustc_inherit_overflow_checks,
1830        rustc_insignificant_dtor,
1831        rustc_intrinsic,
1832        rustc_intrinsic_const_stable_indirect,
1833        rustc_layout,
1834        rustc_layout_scalar_valid_range_end,
1835        rustc_layout_scalar_valid_range_start,
1836        rustc_legacy_const_generics,
1837        rustc_lint_diagnostics,
1838        rustc_lint_opt_deny_field_access,
1839        rustc_lint_opt_ty,
1840        rustc_lint_query_instability,
1841        rustc_lint_untracked_query_information,
1842        rustc_macro_transparency,
1843        rustc_main,
1844        rustc_mir,
1845        rustc_must_implement_one_of,
1846        rustc_never_returns_null_ptr,
1847        rustc_never_type_options,
1848        rustc_no_implicit_autorefs,
1849        rustc_no_mir_inline,
1850        rustc_nonnull_optimization_guaranteed,
1851        rustc_nounwind,
1852        rustc_object_lifetime_default,
1853        rustc_on_unimplemented,
1854        rustc_outlives,
1855        rustc_paren_sugar,
1856        rustc_partition_codegened,
1857        rustc_partition_reused,
1858        rustc_pass_by_value,
1859        rustc_peek,
1860        rustc_peek_liveness,
1861        rustc_peek_maybe_init,
1862        rustc_peek_maybe_uninit,
1863        rustc_preserve_ub_checks,
1864        rustc_private,
1865        rustc_proc_macro_decls,
1866        rustc_promotable,
1867        rustc_pub_transparent,
1868        rustc_reallocator,
1869        rustc_regions,
1870        rustc_reservation_impl,
1871        rustc_serialize,
1872        rustc_skip_during_method_dispatch,
1873        rustc_specialization_trait,
1874        rustc_std_internal_symbol,
1875        rustc_strict_coherence,
1876        rustc_symbol_name,
1877        rustc_test_marker,
1878        rustc_then_this_would_need,
1879        rustc_trivial_field_reads,
1880        rustc_unsafe_specialization_marker,
1881        rustc_variance,
1882        rustc_variance_of_opaques,
1883        rustdoc,
1884        rustdoc_internals,
1885        rustdoc_missing_doc_code_examples,
1886        rustfmt,
1887        rvalue_static_promotion,
1888        rwpi,
1889        s,
1890        s390x_target_feature,
1891        safety,
1892        sanitize,
1893        sanitizer_cfi_generalize_pointers,
1894        sanitizer_cfi_normalize_integers,
1895        sanitizer_runtime,
1896        saturating_add,
1897        saturating_div,
1898        saturating_sub,
1899        sdylib,
1900        search_unbox,
1901        select_unpredictable,
1902        self_in_typedefs,
1903        self_struct_ctor,
1904        semiopaque,
1905        semitransparent,
1906        sha2,
1907        sha3,
1908        sha512_sm_x86,
1909        shadow_call_stack,
1910        shallow,
1911        shl,
1912        shl_assign,
1913        shorter_tail_lifetimes,
1914        should_panic,
1915        shr,
1916        shr_assign,
1917        sig_dfl,
1918        sig_ign,
1919        simd,
1920        simd_add,
1921        simd_and,
1922        simd_arith_offset,
1923        simd_as,
1924        simd_bitmask,
1925        simd_bitreverse,
1926        simd_bswap,
1927        simd_cast,
1928        simd_cast_ptr,
1929        simd_ceil,
1930        simd_ctlz,
1931        simd_ctpop,
1932        simd_cttz,
1933        simd_div,
1934        simd_eq,
1935        simd_expose_provenance,
1936        simd_extract,
1937        simd_extract_dyn,
1938        simd_fabs,
1939        simd_fcos,
1940        simd_fexp,
1941        simd_fexp2,
1942        simd_ffi,
1943        simd_flog,
1944        simd_flog10,
1945        simd_flog2,
1946        simd_floor,
1947        simd_fma,
1948        simd_fmax,
1949        simd_fmin,
1950        simd_fsin,
1951        simd_fsqrt,
1952        simd_gather,
1953        simd_ge,
1954        simd_gt,
1955        simd_insert,
1956        simd_insert_dyn,
1957        simd_le,
1958        simd_lt,
1959        simd_masked_load,
1960        simd_masked_store,
1961        simd_mul,
1962        simd_ne,
1963        simd_neg,
1964        simd_or,
1965        simd_reduce_add_ordered,
1966        simd_reduce_add_unordered,
1967        simd_reduce_all,
1968        simd_reduce_and,
1969        simd_reduce_any,
1970        simd_reduce_max,
1971        simd_reduce_min,
1972        simd_reduce_mul_ordered,
1973        simd_reduce_mul_unordered,
1974        simd_reduce_or,
1975        simd_reduce_xor,
1976        simd_relaxed_fma,
1977        simd_rem,
1978        simd_round,
1979        simd_saturating_add,
1980        simd_saturating_sub,
1981        simd_scatter,
1982        simd_select,
1983        simd_select_bitmask,
1984        simd_shl,
1985        simd_shr,
1986        simd_shuffle,
1987        simd_shuffle_const_generic,
1988        simd_sub,
1989        simd_trunc,
1990        simd_with_exposed_provenance,
1991        simd_xor,
1992        since,
1993        sinf128,
1994        sinf16,
1995        sinf32,
1996        sinf64,
1997        size,
1998        size_of,
1999        size_of_val,
2000        sized,
2001        skip,
2002        slice,
2003        slice_from_raw_parts,
2004        slice_from_raw_parts_mut,
2005        slice_get_unchecked,
2006        slice_into_vec,
2007        slice_iter,
2008        slice_len_fn,
2009        slice_patterns,
2010        slicing_syntax,
2011        soft,
2012        sparc_target_feature,
2013        specialization,
2014        speed,
2015        spotlight,
2016        sqrtf128,
2017        sqrtf16,
2018        sqrtf32,
2019        sqrtf64,
2020        sreg,
2021        sreg_low16,
2022        sse,
2023        sse2,
2024        sse4a_target_feature,
2025        stable,
2026        staged_api,
2027        start,
2028        state,
2029        static_in_const,
2030        static_nobundle,
2031        static_recursion,
2032        staticlib,
2033        std,
2034        std_panic,
2035        std_panic_2015_macro,
2036        std_panic_macro,
2037        stmt,
2038        stmt_expr_attributes,
2039        stop_after_dataflow,
2040        store,
2041        str,
2042        str_chars,
2043        str_ends_with,
2044        str_from_utf8,
2045        str_from_utf8_mut,
2046        str_from_utf8_unchecked,
2047        str_from_utf8_unchecked_mut,
2048        str_inherent_from_utf8,
2049        str_inherent_from_utf8_mut,
2050        str_inherent_from_utf8_unchecked,
2051        str_inherent_from_utf8_unchecked_mut,
2052        str_len,
2053        str_split_whitespace,
2054        str_starts_with,
2055        str_trim,
2056        str_trim_end,
2057        str_trim_start,
2058        strict_provenance_lints,
2059        string_as_mut_str,
2060        string_as_str,
2061        string_deref_patterns,
2062        string_from_utf8,
2063        string_insert_str,
2064        string_new,
2065        string_push_str,
2066        stringify,
2067        struct_field_attributes,
2068        struct_inherit,
2069        struct_variant,
2070        structural_match,
2071        structural_peq,
2072        sub,
2073        sub_assign,
2074        sub_with_overflow,
2075        suggestion,
2076        super_let,
2077        supertrait_item_shadowing,
2078        sym,
2079        sync,
2080        synthetic,
2081        sys_mutex_lock,
2082        sys_mutex_try_lock,
2083        sys_mutex_unlock,
2084        t32,
2085        target,
2086        target_abi,
2087        target_arch,
2088        target_endian,
2089        target_env,
2090        target_family,
2091        target_feature,
2092        target_feature_11,
2093        target_has_atomic,
2094        target_has_atomic_equal_alignment,
2095        target_has_atomic_load_store,
2096        target_has_reliable_f128,
2097        target_has_reliable_f128_math,
2098        target_has_reliable_f16,
2099        target_has_reliable_f16_math,
2100        target_os,
2101        target_pointer_width,
2102        target_thread_local,
2103        target_vendor,
2104        tbm_target_feature,
2105        termination,
2106        termination_trait,
2107        termination_trait_test,
2108        test,
2109        test_2018_feature,
2110        test_accepted_feature,
2111        test_case,
2112        test_removed_feature,
2113        test_runner,
2114        test_unstable_lint,
2115        thread,
2116        thread_local,
2117        thread_local_macro,
2118        three_way_compare,
2119        thumb2,
2120        thumb_mode: "thumb-mode",
2121        tmm_reg,
2122        to_owned_method,
2123        to_string,
2124        to_string_method,
2125        to_vec,
2126        todo_macro,
2127        tool_attributes,
2128        tool_lints,
2129        trace_macros,
2130        track_caller,
2131        trait_alias,
2132        trait_upcasting,
2133        transmute,
2134        transmute_generic_consts,
2135        transmute_opts,
2136        transmute_trait,
2137        transmute_unchecked,
2138        transparent,
2139        transparent_enums,
2140        transparent_unions,
2141        trivial_bounds,
2142        truncf128,
2143        truncf16,
2144        truncf32,
2145        truncf64,
2146        try_blocks,
2147        try_capture,
2148        try_from,
2149        try_from_fn,
2150        try_into,
2151        try_trait_v2,
2152        tt,
2153        tuple,
2154        tuple_indexing,
2155        tuple_trait,
2156        two_phase,
2157        ty,
2158        type_alias_enum_variants,
2159        type_alias_impl_trait,
2160        type_ascribe,
2161        type_ascription,
2162        type_changing_struct_update,
2163        type_const,
2164        type_id,
2165        type_ir_infer_ctxt_like,
2166        type_ir_inherent,
2167        type_ir_interner,
2168        type_length_limit,
2169        type_macros,
2170        type_name,
2171        type_privacy_lints,
2172        typed_swap_nonoverlapping,
2173        u128,
2174        u128_legacy_const_max,
2175        u128_legacy_const_min,
2176        u128_legacy_fn_max_value,
2177        u128_legacy_fn_min_value,
2178        u128_legacy_mod,
2179        u16,
2180        u16_legacy_const_max,
2181        u16_legacy_const_min,
2182        u16_legacy_fn_max_value,
2183        u16_legacy_fn_min_value,
2184        u16_legacy_mod,
2185        u32,
2186        u32_legacy_const_max,
2187        u32_legacy_const_min,
2188        u32_legacy_fn_max_value,
2189        u32_legacy_fn_min_value,
2190        u32_legacy_mod,
2191        u64,
2192        u64_legacy_const_max,
2193        u64_legacy_const_min,
2194        u64_legacy_fn_max_value,
2195        u64_legacy_fn_min_value,
2196        u64_legacy_mod,
2197        u8,
2198        u8_legacy_const_max,
2199        u8_legacy_const_min,
2200        u8_legacy_fn_max_value,
2201        u8_legacy_fn_min_value,
2202        u8_legacy_mod,
2203        ub_checks,
2204        unaligned_volatile_load,
2205        unaligned_volatile_store,
2206        unboxed_closures,
2207        unchecked_add,
2208        unchecked_div,
2209        unchecked_mul,
2210        unchecked_rem,
2211        unchecked_shl,
2212        unchecked_shr,
2213        unchecked_sub,
2214        underscore_const_names,
2215        underscore_imports,
2216        underscore_lifetimes,
2217        uniform_paths,
2218        unimplemented_macro,
2219        unit,
2220        universal_impl_trait,
2221        unix,
2222        unlikely,
2223        unmarked_api,
2224        unnamed_fields,
2225        unpin,
2226        unqualified_local_imports,
2227        unreachable,
2228        unreachable_2015,
2229        unreachable_2015_macro,
2230        unreachable_2021,
2231        unreachable_code,
2232        unreachable_display,
2233        unreachable_macro,
2234        unrestricted_attribute_tokens,
2235        unsafe_attributes,
2236        unsafe_binders,
2237        unsafe_block_in_unsafe_fn,
2238        unsafe_cell,
2239        unsafe_cell_raw_get,
2240        unsafe_extern_blocks,
2241        unsafe_fields,
2242        unsafe_no_drop_flag,
2243        unsafe_pinned,
2244        unsafe_unpin,
2245        unsize,
2246        unsized_const_param_ty,
2247        unsized_const_params,
2248        unsized_fn_params,
2249        unsized_locals,
2250        unsized_tuple_coercion,
2251        unstable,
2252        unstable_location_reason_default: "this crate is being loaded from the sysroot, an \
2253                          unstable location; did you mean to load this crate \
2254                          from crates.io via `Cargo.toml` instead?",
2255        untagged_unions,
2256        unused_imports,
2257        unwind,
2258        unwind_attributes,
2259        unwind_safe_trait,
2260        unwrap,
2261        unwrap_binder,
2262        unwrap_or,
2263        use_cloned,
2264        use_extern_macros,
2265        use_nested_groups,
2266        used,
2267        used_with_arg,
2268        using,
2269        usize,
2270        usize_legacy_const_max,
2271        usize_legacy_const_min,
2272        usize_legacy_fn_max_value,
2273        usize_legacy_fn_min_value,
2274        usize_legacy_mod,
2275        v8plus,
2276        va_arg,
2277        va_copy,
2278        va_end,
2279        va_list,
2280        va_start,
2281        val,
2282        validity,
2283        values,
2284        var,
2285        variant_count,
2286        vec,
2287        vec_as_mut_slice,
2288        vec_as_slice,
2289        vec_from_elem,
2290        vec_is_empty,
2291        vec_macro,
2292        vec_new,
2293        vec_pop,
2294        vec_reserve,
2295        vec_with_capacity,
2296        vecdeque_iter,
2297        vecdeque_reserve,
2298        vector,
2299        version,
2300        vfp2,
2301        vis,
2302        visible_private_types,
2303        volatile,
2304        volatile_copy_memory,
2305        volatile_copy_nonoverlapping_memory,
2306        volatile_load,
2307        volatile_set_memory,
2308        volatile_store,
2309        vreg,
2310        vreg_low16,
2311        vsx,
2312        vtable_align,
2313        vtable_size,
2314        warn,
2315        wasip2,
2316        wasm_abi,
2317        wasm_import_module,
2318        wasm_target_feature,
2319        where_clause_attrs,
2320        while_let,
2321        width,
2322        windows,
2323        windows_subsystem,
2324        with_negative_coherence,
2325        wrap_binder,
2326        wrapping_add,
2327        wrapping_div,
2328        wrapping_mul,
2329        wrapping_rem,
2330        wrapping_rem_euclid,
2331        wrapping_sub,
2332        wreg,
2333        write_bytes,
2334        write_fmt,
2335        write_macro,
2336        write_str,
2337        write_via_move,
2338        writeln_macro,
2339        x86_amx_intrinsics,
2340        x87_reg,
2341        x87_target_feature,
2342        xer,
2343        xmm_reg,
2344        xop_target_feature,
2345        yeet_desugar_details,
2346        yeet_expr,
2347        yes,
2348        yield_expr,
2349        ymm_reg,
2350        yreg,
2351        zfh,
2352        zfhmin,
2353        zmm_reg,
2354    }
2355}
2356
2357/// Symbols for crates that are part of the stable standard library: `std`, `core`, `alloc`, and
2358/// `proc_macro`.
2359pub const STDLIB_STABLE_CRATES: &[Symbol] = &[sym::std, sym::core, sym::alloc, sym::proc_macro];
2360
2361#[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
2362pub struct Ident {
2363    // `name` should never be the empty symbol. If you are considering that,
2364    // you are probably conflating "empty identifer with "no identifier" and
2365    // you should use `Option<Ident>` instead.
2366    pub name: Symbol,
2367    pub span: Span,
2368}
2369
2370impl Ident {
2371    #[inline]
2372    /// Constructs a new identifier from a symbol and a span.
2373    pub fn new(name: Symbol, span: Span) -> Ident {
2374        debug_assert_ne!(name, sym::empty);
2375        Ident { name, span }
2376    }
2377
2378    /// Constructs a new identifier with a dummy span.
2379    #[inline]
2380    pub fn with_dummy_span(name: Symbol) -> Ident {
2381        Ident::new(name, DUMMY_SP)
2382    }
2383
2384    // For dummy identifiers that are never used and absolutely must be
2385    // present. Note that this does *not* use the empty symbol; `sym::dummy`
2386    // makes it clear that it's intended as a dummy value, and is more likely
2387    // to be detected if it accidentally does get used.
2388    #[inline]
2389    pub fn dummy() -> Ident {
2390        Ident::with_dummy_span(sym::dummy)
2391    }
2392
2393    /// Maps a string to an identifier with a dummy span.
2394    pub fn from_str(string: &str) -> Ident {
2395        Ident::with_dummy_span(Symbol::intern(string))
2396    }
2397
2398    /// Maps a string and a span to an identifier.
2399    pub fn from_str_and_span(string: &str, span: Span) -> Ident {
2400        Ident::new(Symbol::intern(string), span)
2401    }
2402
2403    /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
2404    pub fn with_span_pos(self, span: Span) -> Ident {
2405        Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
2406    }
2407
2408    pub fn without_first_quote(self) -> Ident {
2409        Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
2410    }
2411
2412    /// "Normalize" ident for use in comparisons using "item hygiene".
2413    /// Identifiers with same string value become same if they came from the same macro 2.0 macro
2414    /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
2415    /// different macro 2.0 macros.
2416    /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
2417    pub fn normalize_to_macros_2_0(self) -> Ident {
2418        Ident::new(self.name, self.span.normalize_to_macros_2_0())
2419    }
2420
2421    /// "Normalize" ident for use in comparisons using "local variable hygiene".
2422    /// Identifiers with same string value become same if they came from the same non-transparent
2423    /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
2424    /// non-transparent macros.
2425    /// Technically, this operation strips all transparent marks from ident's syntactic context.
2426    #[inline]
2427    pub fn normalize_to_macro_rules(self) -> Ident {
2428        Ident::new(self.name, self.span.normalize_to_macro_rules())
2429    }
2430
2431    /// Access the underlying string. This is a slowish operation because it
2432    /// requires locking the symbol interner.
2433    ///
2434    /// Note that the lifetime of the return value is a lie. See
2435    /// `Symbol::as_str()` for details.
2436    pub fn as_str(&self) -> &str {
2437        self.name.as_str()
2438    }
2439}
2440
2441impl PartialEq for Ident {
2442    #[inline]
2443    fn eq(&self, rhs: &Self) -> bool {
2444        self.name == rhs.name && self.span.eq_ctxt(rhs.span)
2445    }
2446}
2447
2448impl Hash for Ident {
2449    fn hash<H: Hasher>(&self, state: &mut H) {
2450        self.name.hash(state);
2451        self.span.ctxt().hash(state);
2452    }
2453}
2454
2455impl fmt::Debug for Ident {
2456    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2457        fmt::Display::fmt(self, f)?;
2458        fmt::Debug::fmt(&self.span.ctxt(), f)
2459    }
2460}
2461
2462/// This implementation is supposed to be used in error messages, so it's expected to be identical
2463/// to printing the original identifier token written in source code (`token_to_string`),
2464/// except that AST identifiers don't keep the rawness flag, so we have to guess it.
2465impl fmt::Display for Ident {
2466    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2467        fmt::Display::fmt(&IdentPrinter::new(self.name, self.is_raw_guess(), None), f)
2468    }
2469}
2470
2471/// The most general type to print identifiers.
2472///
2473/// AST pretty-printer is used as a fallback for turning AST structures into token streams for
2474/// proc macros. Additionally, proc macros may stringify their input and expect it survive the
2475/// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
2476/// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
2477/// hygiene data, most importantly name of the crate it refers to.
2478/// As a result we print `$crate` as `crate` if it refers to the local crate
2479/// and as `::other_crate_name` if it refers to some other crate.
2480/// Note, that this is only done if the ident token is printed from inside of AST pretty-printing,
2481/// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
2482/// so we should not perform this lossy conversion if the top level call to the pretty-printer was
2483/// done for a token stream or a single token.
2484pub struct IdentPrinter {
2485    symbol: Symbol,
2486    is_raw: bool,
2487    /// Span used for retrieving the crate name to which `$crate` refers to,
2488    /// if this field is `None` then the `$crate` conversion doesn't happen.
2489    convert_dollar_crate: Option<Span>,
2490}
2491
2492impl IdentPrinter {
2493    /// The most general `IdentPrinter` constructor. Do not use this.
2494    pub fn new(symbol: Symbol, is_raw: bool, convert_dollar_crate: Option<Span>) -> IdentPrinter {
2495        IdentPrinter { symbol, is_raw, convert_dollar_crate }
2496    }
2497
2498    /// This implementation is supposed to be used when printing identifiers
2499    /// as a part of pretty-printing for larger AST pieces.
2500    /// Do not use this either.
2501    pub fn for_ast_ident(ident: Ident, is_raw: bool) -> IdentPrinter {
2502        IdentPrinter::new(ident.name, is_raw, Some(ident.span))
2503    }
2504}
2505
2506impl fmt::Display for IdentPrinter {
2507    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2508        if self.is_raw {
2509            f.write_str("r#")?;
2510        } else if self.symbol == kw::DollarCrate {
2511            if let Some(span) = self.convert_dollar_crate {
2512                let converted = span.ctxt().dollar_crate_name();
2513                if !converted.is_path_segment_keyword() {
2514                    f.write_str("::")?;
2515                }
2516                return fmt::Display::fmt(&converted, f);
2517            }
2518        }
2519        fmt::Display::fmt(&self.symbol, f)
2520    }
2521}
2522
2523/// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
2524/// construction.
2525// FIXME(matthewj, petrochenkov) Use this more often, add a similar
2526// `ModernIdent` struct and use that as well.
2527#[derive(Copy, Clone, Eq, PartialEq, Hash)]
2528pub struct MacroRulesNormalizedIdent(Ident);
2529
2530impl MacroRulesNormalizedIdent {
2531    #[inline]
2532    pub fn new(ident: Ident) -> Self {
2533        Self(ident.normalize_to_macro_rules())
2534    }
2535}
2536
2537impl fmt::Debug for MacroRulesNormalizedIdent {
2538    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2539        fmt::Debug::fmt(&self.0, f)
2540    }
2541}
2542
2543impl fmt::Display for MacroRulesNormalizedIdent {
2544    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2545        fmt::Display::fmt(&self.0, f)
2546    }
2547}
2548
2549/// An interned string.
2550///
2551/// Internally, a `Symbol` is implemented as an index, and all operations
2552/// (including hashing, equality, and ordering) operate on that index. The use
2553/// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
2554/// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
2555///
2556/// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
2557/// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
2558#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
2559pub struct Symbol(SymbolIndex);
2560
2561rustc_index::newtype_index! {
2562    #[orderable]
2563    struct SymbolIndex {}
2564}
2565
2566impl Symbol {
2567    pub const fn new(n: u32) -> Self {
2568        Symbol(SymbolIndex::from_u32(n))
2569    }
2570
2571    /// Maps a string to its interned representation.
2572    #[rustc_diagnostic_item = "SymbolIntern"]
2573    pub fn intern(string: &str) -> Self {
2574        with_session_globals(|session_globals| session_globals.symbol_interner.intern(string))
2575    }
2576
2577    /// Access the underlying string. This is a slowish operation because it
2578    /// requires locking the symbol interner.
2579    ///
2580    /// Note that the lifetime of the return value is a lie. It's not the same
2581    /// as `&self`, but actually tied to the lifetime of the underlying
2582    /// interner. Interners are long-lived, and there are very few of them, and
2583    /// this function is typically used for short-lived things, so in practice
2584    /// it works out ok.
2585    pub fn as_str(&self) -> &str {
2586        with_session_globals(|session_globals| unsafe {
2587            std::mem::transmute::<&str, &str>(session_globals.symbol_interner.get(*self))
2588        })
2589    }
2590
2591    pub fn as_u32(self) -> u32 {
2592        self.0.as_u32()
2593    }
2594
2595    pub fn is_empty(self) -> bool {
2596        self == sym::empty
2597    }
2598
2599    /// This method is supposed to be used in error messages, so it's expected to be
2600    /// identical to printing the original identifier token written in source code
2601    /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
2602    /// or edition, so we have to guess the rawness using the global edition.
2603    pub fn to_ident_string(self) -> String {
2604        // Avoid creating an empty identifier, because that asserts in debug builds.
2605        if self == sym::empty { String::new() } else { Ident::with_dummy_span(self).to_string() }
2606    }
2607}
2608
2609impl fmt::Debug for Symbol {
2610    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2611        fmt::Debug::fmt(self.as_str(), f)
2612    }
2613}
2614
2615impl fmt::Display for Symbol {
2616    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2617        fmt::Display::fmt(self.as_str(), f)
2618    }
2619}
2620
2621impl<CTX> HashStable<CTX> for Symbol {
2622    #[inline]
2623    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
2624        self.as_str().hash_stable(hcx, hasher);
2625    }
2626}
2627
2628impl<CTX> ToStableHashKey<CTX> for Symbol {
2629    type KeyType = String;
2630    #[inline]
2631    fn to_stable_hash_key(&self, _: &CTX) -> String {
2632        self.as_str().to_string()
2633    }
2634}
2635
2636impl StableCompare for Symbol {
2637    const CAN_USE_UNSTABLE_SORT: bool = true;
2638
2639    fn stable_cmp(&self, other: &Self) -> std::cmp::Ordering {
2640        self.as_str().cmp(other.as_str())
2641    }
2642}
2643
2644pub(crate) struct Interner(Lock<InternerInner>);
2645
2646// The `&'static str`s in this type actually point into the arena.
2647//
2648// This type is private to prevent accidentally constructing more than one
2649// `Interner` on the same thread, which makes it easy to mix up `Symbol`s
2650// between `Interner`s.
2651struct InternerInner {
2652    arena: DroplessArena,
2653    strings: FxIndexSet<&'static str>,
2654}
2655
2656impl Interner {
2657    fn prefill(init: &[&'static str], extra: &[&'static str]) -> Self {
2658        let strings = FxIndexSet::from_iter(init.iter().copied().chain(extra.iter().copied()));
2659        assert_eq!(
2660            strings.len(),
2661            init.len() + extra.len(),
2662            "`init` or `extra` contain duplicate symbols",
2663        );
2664        Interner(Lock::new(InternerInner { arena: Default::default(), strings }))
2665    }
2666
2667    #[inline]
2668    fn intern(&self, string: &str) -> Symbol {
2669        let mut inner = self.0.lock();
2670        if let Some(idx) = inner.strings.get_index_of(string) {
2671            return Symbol::new(idx as u32);
2672        }
2673
2674        let string: &str = inner.arena.alloc_str(string);
2675
2676        // SAFETY: we can extend the arena allocation to `'static` because we
2677        // only access these while the arena is still alive.
2678        let string: &'static str = unsafe { &*(string as *const str) };
2679
2680        // This second hash table lookup can be avoided by using `RawEntryMut`,
2681        // but this code path isn't hot enough for it to be worth it. See
2682        // #91445 for details.
2683        let (idx, is_new) = inner.strings.insert_full(string);
2684        debug_assert!(is_new); // due to the get_index_of check above
2685
2686        Symbol::new(idx as u32)
2687    }
2688
2689    /// Get the symbol as a string.
2690    ///
2691    /// [`Symbol::as_str()`] should be used in preference to this function.
2692    fn get(&self, symbol: Symbol) -> &str {
2693        self.0.lock().strings.get_index(symbol.0.as_usize()).unwrap()
2694    }
2695}
2696
2697// This module has a very short name because it's used a lot.
2698/// This module contains all the defined keyword `Symbol`s.
2699///
2700/// Given that `kw` is imported, use them like `kw::keyword_name`.
2701/// For example `kw::Loop` or `kw::Break`.
2702pub mod kw {
2703    pub use super::kw_generated::*;
2704}
2705
2706// This module has a very short name because it's used a lot.
2707/// This module contains all the defined non-keyword `Symbol`s.
2708///
2709/// Given that `sym` is imported, use them like `sym::symbol_name`.
2710/// For example `sym::rustfmt` or `sym::u8`.
2711pub mod sym {
2712    // Used from a macro in `librustc_feature/accepted.rs`
2713    use super::Symbol;
2714    pub use super::kw::MacroRules as macro_rules;
2715    #[doc(inline)]
2716    pub use super::sym_generated::*;
2717
2718    /// Get the symbol for an integer.
2719    ///
2720    /// The first few non-negative integers each have a static symbol and therefore
2721    /// are fast.
2722    pub fn integer<N: TryInto<usize> + Copy + itoa::Integer>(n: N) -> Symbol {
2723        if let Result::Ok(idx) = n.try_into() {
2724            if idx < 10 {
2725                return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
2726            }
2727        }
2728        let mut buffer = itoa::Buffer::new();
2729        let printed = buffer.format(n);
2730        Symbol::intern(printed)
2731    }
2732}
2733
2734impl Symbol {
2735    fn is_special(self) -> bool {
2736        self <= kw::Underscore
2737    }
2738
2739    fn is_used_keyword_always(self) -> bool {
2740        self >= kw::As && self <= kw::While
2741    }
2742
2743    fn is_unused_keyword_always(self) -> bool {
2744        self >= kw::Abstract && self <= kw::Yield
2745    }
2746
2747    fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
2748        (self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
2749    }
2750
2751    fn is_unused_keyword_conditional(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
2752        self == kw::Gen && edition().at_least_rust_2024()
2753            || self == kw::Try && edition().at_least_rust_2018()
2754    }
2755
2756    pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
2757        self.is_special()
2758            || self.is_used_keyword_always()
2759            || self.is_unused_keyword_always()
2760            || self.is_used_keyword_conditional(edition)
2761            || self.is_unused_keyword_conditional(edition)
2762    }
2763
2764    pub fn is_weak(self) -> bool {
2765        self >= kw::Auto && self <= kw::Yeet
2766    }
2767
2768    /// A keyword or reserved identifier that can be used as a path segment.
2769    pub fn is_path_segment_keyword(self) -> bool {
2770        self == kw::Super
2771            || self == kw::SelfLower
2772            || self == kw::SelfUpper
2773            || self == kw::Crate
2774            || self == kw::PathRoot
2775            || self == kw::DollarCrate
2776    }
2777
2778    /// Returns `true` if the symbol is `true` or `false`.
2779    pub fn is_bool_lit(self) -> bool {
2780        self == kw::True || self == kw::False
2781    }
2782
2783    /// Returns `true` if this symbol can be a raw identifier.
2784    pub fn can_be_raw(self) -> bool {
2785        self != sym::empty && self != kw::Underscore && !self.is_path_segment_keyword()
2786    }
2787
2788    /// Was this symbol predefined in the compiler's `symbols!` macro
2789    pub fn is_predefined(self) -> bool {
2790        self.as_u32() < PREDEFINED_SYMBOLS_COUNT
2791    }
2792}
2793
2794impl Ident {
2795    /// Returns `true` for reserved identifiers used internally for elided lifetimes,
2796    /// unnamed method parameters, crate root module, error recovery etc.
2797    pub fn is_special(self) -> bool {
2798        self.name.is_special()
2799    }
2800
2801    /// Returns `true` if the token is a keyword used in the language.
2802    pub fn is_used_keyword(self) -> bool {
2803        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
2804        self.name.is_used_keyword_always()
2805            || self.name.is_used_keyword_conditional(|| self.span.edition())
2806    }
2807
2808    /// Returns `true` if the token is a keyword reserved for possible future use.
2809    pub fn is_unused_keyword(self) -> bool {
2810        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
2811        self.name.is_unused_keyword_always()
2812            || self.name.is_unused_keyword_conditional(|| self.span.edition())
2813    }
2814
2815    /// Returns `true` if the token is either a special identifier or a keyword.
2816    pub fn is_reserved(self) -> bool {
2817        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
2818        self.name.is_reserved(|| self.span.edition())
2819    }
2820
2821    /// A keyword or reserved identifier that can be used as a path segment.
2822    pub fn is_path_segment_keyword(self) -> bool {
2823        self.name.is_path_segment_keyword()
2824    }
2825
2826    /// We see this identifier in a normal identifier position, like variable name or a type.
2827    /// How was it written originally? Did it use the raw form? Let's try to guess.
2828    pub fn is_raw_guess(self) -> bool {
2829        self.name.can_be_raw() && self.is_reserved()
2830    }
2831
2832    /// Whether this would be the identifier for a tuple field like `self.0`, as
2833    /// opposed to a named field like `self.thing`.
2834    pub fn is_numeric(self) -> bool {
2835        self.as_str().bytes().all(|b| b.is_ascii_digit())
2836    }
2837}
2838
2839/// Collect all the keywords in a given edition into a vector.
2840///
2841/// *Note:* Please update this if a new keyword is added beyond the current
2842/// range.
2843pub fn used_keywords(edition: impl Copy + FnOnce() -> Edition) -> Vec<Symbol> {
2844    (kw::DollarCrate.as_u32()..kw::Yeet.as_u32())
2845        .filter_map(|kw| {
2846            let kw = Symbol::new(kw);
2847            if kw.is_used_keyword_always() || kw.is_used_keyword_conditional(edition) {
2848                Some(kw)
2849            } else {
2850                None
2851            }
2852        })
2853        .collect()
2854}