]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_span/src/symbol.rs
Auto merge of #99283 - RalfJung:miri, r=RalfJung
[rust.git] / compiler / rustc_span / src / 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
5 use rustc_arena::DroplessArena;
6 use rustc_data_structures::fx::FxHashMap;
7 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
8 use rustc_data_structures::sync::Lock;
9 use rustc_macros::HashStable_Generic;
10 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
11
12 use std::cmp::{Ord, PartialEq, PartialOrd};
13 use std::fmt;
14 use std::hash::{Hash, Hasher};
15 use std::str;
16
17 use crate::{with_session_globals, Edition, Span, DUMMY_SP};
18
19 #[cfg(test)]
20 mod tests;
21
22 // The proc macro code for this is in `compiler/rustc_macros/src/symbols.rs`.
23 symbols! {
24     // After modifying this list adjust `is_special`, `is_used_keyword`/`is_unused_keyword`,
25     // this should be rarely necessary though if the keywords are kept in alphabetic order.
26     Keywords {
27         // Special reserved identifiers used internally for elided lifetimes,
28         // unnamed method parameters, crate root module, error recovery etc.
29         Empty:              "",
30         PathRoot:           "{{root}}",
31         DollarCrate:        "$crate",
32         Underscore:         "_",
33
34         // Keywords that are used in stable Rust.
35         As:                 "as",
36         Break:              "break",
37         Const:              "const",
38         Continue:           "continue",
39         Crate:              "crate",
40         Else:               "else",
41         Enum:               "enum",
42         Extern:             "extern",
43         False:              "false",
44         Fn:                 "fn",
45         For:                "for",
46         If:                 "if",
47         Impl:               "impl",
48         In:                 "in",
49         Let:                "let",
50         Loop:               "loop",
51         Match:              "match",
52         Mod:                "mod",
53         Move:               "move",
54         Mut:                "mut",
55         Pub:                "pub",
56         Ref:                "ref",
57         Return:             "return",
58         SelfLower:          "self",
59         SelfUpper:          "Self",
60         Static:             "static",
61         Struct:             "struct",
62         Super:              "super",
63         Trait:              "trait",
64         True:               "true",
65         Type:               "type",
66         Unsafe:             "unsafe",
67         Use:                "use",
68         Where:              "where",
69         While:              "while",
70
71         // Keywords that are used in unstable Rust or reserved for future use.
72         Abstract:           "abstract",
73         Become:             "become",
74         Box:                "box",
75         Do:                 "do",
76         Final:              "final",
77         Macro:              "macro",
78         Override:           "override",
79         Priv:               "priv",
80         Typeof:             "typeof",
81         Unsized:            "unsized",
82         Virtual:            "virtual",
83         Yield:              "yield",
84
85         // Edition-specific keywords that are used in stable Rust.
86         Async:              "async", // >= 2018 Edition only
87         Await:              "await", // >= 2018 Edition only
88         Dyn:                "dyn", // >= 2018 Edition only
89
90         // Edition-specific keywords that are used in unstable Rust or reserved for future use.
91         Try:                "try", // >= 2018 Edition only
92
93         // Special lifetime names
94         UnderscoreLifetime: "'_",
95         StaticLifetime:     "'static",
96
97         // Weak keywords, have special meaning only in specific contexts.
98         Auto:               "auto",
99         Catch:              "catch",
100         Default:            "default",
101         MacroRules:         "macro_rules",
102         Raw:                "raw",
103         Union:              "union",
104         Yeet:               "yeet",
105     }
106
107     // Pre-interned symbols that can be referred to with `rustc_span::sym::*`.
108     //
109     // The symbol is the stringified identifier unless otherwise specified, in
110     // which case the name should mention the non-identifier punctuation.
111     // E.g. `sym::proc_dash_macro` represents "proc-macro", and it shouldn't be
112     // called `sym::proc_macro` because then it's easy to mistakenly think it
113     // represents "proc_macro".
114     //
115     // As well as the symbols listed, there are symbols for the strings
116     // "0", "1", ..., "9", which are accessible via `sym::integer`.
117     //
118     // The proc macro will abort if symbols are not in alphabetical order (as
119     // defined by `impl Ord for str`) or if any symbols are duplicated. Vim
120     // users can sort the list by selecting it and executing the command
121     // `:'<,'>!LC_ALL=C sort`.
122     //
123     // There is currently no checking that all symbols are used; that would be
124     // nice to have.
125     Symbols {
126         AcqRel,
127         Acquire,
128         AddSubdiagnostic,
129         Alignment,
130         Any,
131         Arc,
132         Argument,
133         ArgumentV1,
134         ArgumentV1Methods,
135         Arguments,
136         AsMut,
137         AsRef,
138         AssertParamIsClone,
139         AssertParamIsCopy,
140         AssertParamIsEq,
141         AtomicBool,
142         AtomicI128,
143         AtomicI16,
144         AtomicI32,
145         AtomicI64,
146         AtomicI8,
147         AtomicIsize,
148         AtomicPtr,
149         AtomicU128,
150         AtomicU16,
151         AtomicU32,
152         AtomicU64,
153         AtomicU8,
154         AtomicUsize,
155         BTreeEntry,
156         BTreeMap,
157         BTreeSet,
158         BinaryHeap,
159         Borrow,
160         Break,
161         C,
162         CStr,
163         CString,
164         Capture,
165         Center,
166         Clone,
167         Continue,
168         Copy,
169         Count,
170         Cow,
171         Debug,
172         DebugStruct,
173         DebugTuple,
174         Decodable,
175         Decoder,
176         DecorateLint,
177         Default,
178         Deref,
179         DiagnosticMessage,
180         DirBuilder,
181         Display,
182         DoubleEndedIterator,
183         Duration,
184         Encodable,
185         Encoder,
186         Eq,
187         Equal,
188         Err,
189         Error,
190         File,
191         FileType,
192         Fn,
193         FnMut,
194         FnOnce,
195         FormatSpec,
196         Formatter,
197         From,
198         FromIterator,
199         FromResidual,
200         Future,
201         FxHashMap,
202         FxHashSet,
203         GlobalAlloc,
204         Hash,
205         HashMap,
206         HashMapEntry,
207         HashSet,
208         Hasher,
209         Implied,
210         Input,
211         Into,
212         IntoFuture,
213         IntoIterator,
214         IoRead,
215         IoWrite,
216         IrTyKind,
217         Is,
218         ItemContext,
219         Iterator,
220         Layout,
221         Left,
222         LinkedList,
223         LintPass,
224         Mutex,
225         N,
226         None,
227         Ok,
228         Option,
229         Ord,
230         Ordering,
231         OsStr,
232         OsString,
233         Output,
234         Param,
235         PartialEq,
236         PartialOrd,
237         Path,
238         PathBuf,
239         Pending,
240         Pin,
241         Pointer,
242         Poll,
243         ProcMacro,
244         ProcMacroHack,
245         ProceduralMasqueradeDummyType,
246         Range,
247         RangeFrom,
248         RangeFull,
249         RangeInclusive,
250         RangeTo,
251         RangeToInclusive,
252         Rc,
253         Ready,
254         Receiver,
255         Relaxed,
256         Release,
257         Result,
258         Return,
259         Right,
260         RustcDecodable,
261         RustcEncodable,
262         Send,
263         SeqCst,
264         SessionDiagnostic,
265         SliceIndex,
266         Some,
267         String,
268         StructuralEq,
269         StructuralPartialEq,
270         SubdiagnosticMessage,
271         Sync,
272         Target,
273         ToOwned,
274         ToString,
275         Try,
276         TryCaptureGeneric,
277         TryCapturePrintable,
278         TryFrom,
279         TryInto,
280         Ty,
281         TyCtxt,
282         TyKind,
283         Unknown,
284         UnsafeArg,
285         Vec,
286         VecDeque,
287         Wrapper,
288         Yield,
289         _DECLS,
290         _Self,
291         __D,
292         __H,
293         __S,
294         __awaitee,
295         __try_var,
296         _d,
297         _e,
298         _task_context,
299         a32,
300         aarch64_target_feature,
301         aarch64_ver_target_feature,
302         abi,
303         abi_amdgpu_kernel,
304         abi_avr_interrupt,
305         abi_c_cmse_nonsecure_call,
306         abi_efiapi,
307         abi_msp430_interrupt,
308         abi_ptx,
309         abi_sysv64,
310         abi_thiscall,
311         abi_unadjusted,
312         abi_vectorcall,
313         abi_x86_interrupt,
314         abort,
315         aborts,
316         add,
317         add_assign,
318         add_with_overflow,
319         address,
320         adt_const_params,
321         advanced_slice_patterns,
322         adx_target_feature,
323         alias,
324         align,
325         align_offset,
326         alignstack,
327         all,
328         alloc,
329         alloc_error_handler,
330         alloc_layout,
331         alloc_zeroed,
332         allocator,
333         allocator_api,
334         allocator_internals,
335         allow,
336         allow_fail,
337         allow_internal_unsafe,
338         allow_internal_unstable,
339         allowed,
340         alu32,
341         always,
342         and,
343         and_then,
344         anonymous_lifetime_in_impl_trait,
345         any,
346         append_const_msg,
347         arbitrary_enum_discriminant,
348         arbitrary_self_types,
349         args,
350         arith_offset,
351         arm,
352         arm_target_feature,
353         array,
354         arrays,
355         as_ptr,
356         as_ref,
357         as_str,
358         asm,
359         asm_const,
360         asm_experimental_arch,
361         asm_sym,
362         asm_unwind,
363         assert,
364         assert_eq_macro,
365         assert_inhabited,
366         assert_macro,
367         assert_ne_macro,
368         assert_receiver_is_total_eq,
369         assert_uninit_valid,
370         assert_zero_valid,
371         asserting,
372         associated_const_equality,
373         associated_consts,
374         associated_type_bounds,
375         associated_type_defaults,
376         associated_types,
377         assume,
378         assume_init,
379         async_await,
380         async_closure,
381         atomic,
382         atomic_mod,
383         atomics,
384         att_syntax,
385         attr,
386         attr_literals,
387         attributes,
388         augmented_assignments,
389         auto_traits,
390         automatically_derived,
391         avx,
392         avx512_target_feature,
393         avx512bw,
394         avx512f,
395         await_macro,
396         bang,
397         begin_panic,
398         bench,
399         bin,
400         bind_by_move_pattern_guards,
401         bindings_after_at,
402         bitand,
403         bitand_assign,
404         bitor,
405         bitor_assign,
406         bitreverse,
407         bitxor,
408         bitxor_assign,
409         black_box,
410         block,
411         bool,
412         borrowck_graphviz_format,
413         borrowck_graphviz_postflow,
414         borrowck_graphviz_preflow,
415         box_free,
416         box_patterns,
417         box_syntax,
418         bpf_target_feature,
419         braced_empty_structs,
420         branch,
421         breakpoint,
422         bridge,
423         bswap,
424         c_str,
425         c_unwind,
426         c_variadic,
427         call,
428         call_mut,
429         call_once,
430         caller_location,
431         capture_disjoint_fields,
432         cdylib,
433         ceilf32,
434         ceilf64,
435         cfg,
436         cfg_accessible,
437         cfg_attr,
438         cfg_attr_multi,
439         cfg_doctest,
440         cfg_eval,
441         cfg_hide,
442         cfg_macro,
443         cfg_panic,
444         cfg_sanitize,
445         cfg_target_abi,
446         cfg_target_compact,
447         cfg_target_feature,
448         cfg_target_has_atomic,
449         cfg_target_has_atomic_equal_alignment,
450         cfg_target_has_atomic_load_store,
451         cfg_target_thread_local,
452         cfg_target_vendor,
453         cfg_version,
454         cfi,
455         char,
456         client,
457         clippy,
458         clobber_abi,
459         clone,
460         clone_closures,
461         clone_from,
462         closure,
463         closure_lifetime_binder,
464         closure_to_fn_coercion,
465         closure_track_caller,
466         cmp,
467         cmp_max,
468         cmp_min,
469         cmpxchg16b_target_feature,
470         cmse_nonsecure_entry,
471         coerce_unsized,
472         cold,
473         column,
474         column_macro,
475         compare_and_swap,
476         compare_exchange,
477         compare_exchange_weak,
478         compile_error,
479         compile_error_macro,
480         compiler,
481         compiler_builtins,
482         compiler_fence,
483         concat,
484         concat_bytes,
485         concat_idents,
486         concat_macro,
487         conservative_impl_trait,
488         console,
489         const_allocate,
490         const_async_blocks,
491         const_compare_raw_pointers,
492         const_constructor,
493         const_deallocate,
494         const_eval_limit,
495         const_eval_select,
496         const_eval_select_ct,
497         const_evaluatable_checked,
498         const_extern_fn,
499         const_fn,
500         const_fn_floating_point_arithmetic,
501         const_fn_fn_ptr_basics,
502         const_fn_trait_bound,
503         const_fn_transmute,
504         const_fn_union,
505         const_fn_unsize,
506         const_for,
507         const_format_args,
508         const_generic_defaults,
509         const_generics,
510         const_generics_defaults,
511         const_if_match,
512         const_impl_trait,
513         const_in_array_repeat_expressions,
514         const_indexing,
515         const_let,
516         const_loop,
517         const_mut_refs,
518         const_panic,
519         const_panic_fmt,
520         const_precise_live_drops,
521         const_raw_ptr_deref,
522         const_raw_ptr_to_usize_cast,
523         const_refs_to_cell,
524         const_trait,
525         const_trait_bound_opt_out,
526         const_trait_impl,
527         const_transmute,
528         const_try,
529         constant,
530         constructor,
531         contents,
532         context,
533         convert,
534         copy,
535         copy_closures,
536         copy_nonoverlapping,
537         copysignf32,
538         copysignf64,
539         core,
540         core_intrinsics,
541         core_panic,
542         core_panic_2015_macro,
543         core_panic_macro,
544         cosf32,
545         cosf64,
546         count,
547         cr,
548         crate_id,
549         crate_in_paths,
550         crate_local,
551         crate_name,
552         crate_type,
553         crate_visibility_modifier,
554         crt_dash_static: "crt-static",
555         cstring_type,
556         ctlz,
557         ctlz_nonzero,
558         ctpop,
559         cttz,
560         cttz_nonzero,
561         custom_attribute,
562         custom_derive,
563         custom_inner_attributes,
564         custom_test_frameworks,
565         d,
566         d32,
567         dbg_macro,
568         dead_code,
569         dealloc,
570         debug,
571         debug_assert_eq_macro,
572         debug_assert_macro,
573         debug_assert_ne_macro,
574         debug_assertions,
575         debug_struct,
576         debug_struct_fields_finish,
577         debug_trait_builder,
578         debug_tuple,
579         debug_tuple_fields_finish,
580         debugger_visualizer,
581         decl_macro,
582         declare_lint_pass,
583         decode,
584         default_alloc_error_handler,
585         default_lib_allocator,
586         default_method_body_is_const,
587         default_type_parameter_fallback,
588         default_type_params,
589         delay_span_bug_from_inside_query,
590         deny,
591         deprecated,
592         deprecated_safe,
593         deprecated_suggestion,
594         deref,
595         deref_method,
596         deref_mut,
597         deref_target,
598         derive,
599         derive_default_enum,
600         destruct,
601         destructuring_assignment,
602         diagnostic,
603         direct,
604         discriminant_kind,
605         discriminant_type,
606         discriminant_value,
607         dispatch_from_dyn,
608         display_trait,
609         div,
610         div_assign,
611         doc,
612         doc_alias,
613         doc_auto_cfg,
614         doc_cfg,
615         doc_cfg_hide,
616         doc_keyword,
617         doc_masked,
618         doc_notable_trait,
619         doc_primitive,
620         doc_spotlight,
621         doctest,
622         document_private_items,
623         dotdot: "..",
624         dotdot_in_tuple_patterns,
625         dotdoteq_in_patterns,
626         dreg,
627         dreg_low16,
628         dreg_low8,
629         drop,
630         drop_in_place,
631         drop_types_in_const,
632         dropck_eyepatch,
633         dropck_parametricity,
634         dylib,
635         dyn_metadata,
636         dyn_trait,
637         e,
638         edition_macro_pats,
639         edition_panic,
640         eh_catch_typeinfo,
641         eh_personality,
642         emit_enum,
643         emit_enum_variant,
644         emit_enum_variant_arg,
645         emit_struct,
646         emit_struct_field,
647         enable,
648         enclosing_scope,
649         encode,
650         end,
651         env,
652         env_macro,
653         eprint_macro,
654         eprintln_macro,
655         eq,
656         ermsb_target_feature,
657         exact_div,
658         except,
659         exchange_malloc,
660         exclusive_range_pattern,
661         exhaustive_integer_patterns,
662         exhaustive_patterns,
663         existential_type,
664         exp2f32,
665         exp2f64,
666         expect,
667         expected,
668         expf32,
669         expf64,
670         explicit_generic_args_with_impl_trait,
671         export_name,
672         expr,
673         extended_key_value_attributes,
674         extern_absolute_paths,
675         extern_crate_item_prelude,
676         extern_crate_self,
677         extern_in_paths,
678         extern_prelude,
679         extern_types,
680         external_doc,
681         f,
682         f16c_target_feature,
683         f32,
684         f64,
685         fabsf32,
686         fabsf64,
687         fadd_fast,
688         fdiv_fast,
689         feature,
690         fence,
691         ferris: "🦀",
692         fetch_update,
693         ffi,
694         ffi_const,
695         ffi_pure,
696         ffi_returns_twice,
697         field,
698         field_init_shorthand,
699         file,
700         file_macro,
701         fill,
702         finish,
703         flags,
704         float,
705         float_to_int_unchecked,
706         floorf32,
707         floorf64,
708         fmaf32,
709         fmaf64,
710         fmt,
711         fmt_as_str,
712         fmt_internals,
713         fmul_fast,
714         fn_align,
715         fn_must_use,
716         fn_mut,
717         fn_once,
718         fn_once_output,
719         forbid,
720         forget,
721         format,
722         format_args,
723         format_args_capture,
724         format_args_macro,
725         format_args_nl,
726         format_macro,
727         fp,
728         freeze,
729         freg,
730         frem_fast,
731         from,
732         from_desugaring,
733         from_generator,
734         from_iter,
735         from_method,
736         from_output,
737         from_residual,
738         from_size_align_unchecked,
739         from_usize,
740         from_yeet,
741         fsub_fast,
742         fundamental,
743         future,
744         future_trait,
745         gdb_script_file,
746         ge,
747         gen_future,
748         gen_kill,
749         generator,
750         generator_return,
751         generator_state,
752         generators,
753         generic_arg_infer,
754         generic_assert,
755         generic_associated_types,
756         generic_associated_types_extended,
757         generic_const_exprs,
758         generic_param_attrs,
759         get_context,
760         global_allocator,
761         global_asm,
762         globs,
763         gt,
764         half_open_range_patterns,
765         hash,
766         hexagon_target_feature,
767         hidden,
768         homogeneous_aggregate,
769         html_favicon_url,
770         html_logo_url,
771         html_no_source,
772         html_playground_url,
773         html_root_url,
774         hwaddress,
775         i,
776         i128,
777         i128_type,
778         i16,
779         i32,
780         i64,
781         i8,
782         ident,
783         if_let,
784         if_let_guard,
785         if_while_or_patterns,
786         ignore,
787         impl_header_lifetime_elision,
788         impl_lint_pass,
789         impl_macros,
790         impl_trait_in_bindings,
791         import,
792         import_shadowing,
793         imported_main,
794         in_band_lifetimes,
795         include,
796         include_bytes,
797         include_bytes_macro,
798         include_macro,
799         include_str,
800         include_str_macro,
801         inclusive_range_syntax,
802         index,
803         index_mut,
804         infer_outlives_requirements,
805         infer_static_outlives_requirements,
806         inherent_associated_types,
807         inlateout,
808         inline,
809         inline_const,
810         inline_const_pat,
811         inout,
812         instruction_set,
813         integer_: "integer",
814         integral,
815         intel,
816         into_future,
817         into_iter,
818         intra_doc_pointers,
819         intrinsics,
820         irrefutable_let_patterns,
821         isa_attribute,
822         isize,
823         issue,
824         issue_5723_bootstrap,
825         issue_tracker_base_url,
826         item,
827         item_like_imports,
828         iter,
829         iter_repeat,
830         keyword,
831         kind,
832         kreg,
833         kreg0,
834         label,
835         label_break_value,
836         lang,
837         lang_items,
838         large_assignments,
839         lateout,
840         lazy_normalization_consts,
841         le,
842         len,
843         let_chains,
844         let_else,
845         lhs,
846         lib,
847         libc,
848         lifetime,
849         likely,
850         line,
851         line_macro,
852         link,
853         link_args,
854         link_cfg,
855         link_llvm_intrinsics,
856         link_name,
857         link_ordinal,
858         link_section,
859         linkage,
860         linker,
861         lint_reasons,
862         literal,
863         load,
864         loaded_from_disk,
865         local,
866         local_inner_macros,
867         log10f32,
868         log10f64,
869         log2f32,
870         log2f64,
871         log_syntax,
872         logf32,
873         logf64,
874         loop_break_value,
875         lt,
876         macro_at_most_once_rep,
877         macro_attributes_in_derive_output,
878         macro_escape,
879         macro_export,
880         macro_lifetime_matcher,
881         macro_literal_matcher,
882         macro_metavar_expr,
883         macro_reexport,
884         macro_use,
885         macro_vis_matcher,
886         macros_in_extern,
887         main,
888         managed_boxes,
889         manually_drop,
890         map,
891         marker,
892         marker_trait_attr,
893         masked,
894         match_beginning_vert,
895         match_default_bindings,
896         matches_macro,
897         maxnumf32,
898         maxnumf64,
899         may_dangle,
900         may_unwind,
901         maybe_uninit,
902         maybe_uninit_uninit,
903         maybe_uninit_zeroed,
904         mem_discriminant,
905         mem_drop,
906         mem_forget,
907         mem_replace,
908         mem_size_of,
909         mem_size_of_val,
910         mem_uninitialized,
911         mem_variant_count,
912         mem_zeroed,
913         member_constraints,
914         memory,
915         memtag,
916         message,
917         meta,
918         metadata_type,
919         min_align_of,
920         min_align_of_val,
921         min_const_fn,
922         min_const_generics,
923         min_const_unsafe_fn,
924         min_specialization,
925         min_type_alias_impl_trait,
926         minnumf32,
927         minnumf64,
928         mips_target_feature,
929         miri,
930         misc,
931         mmx_reg,
932         modifiers,
933         module,
934         module_path,
935         module_path_macro,
936         more_qualified_paths,
937         more_struct_aliases,
938         movbe_target_feature,
939         move_ref_pattern,
940         move_size_limit,
941         mul,
942         mul_assign,
943         mul_with_overflow,
944         must_not_suspend,
945         must_use,
946         naked,
947         naked_functions,
948         name,
949         names,
950         native_link_modifiers,
951         native_link_modifiers_as_needed,
952         native_link_modifiers_bundle,
953         native_link_modifiers_verbatim,
954         native_link_modifiers_whole_archive,
955         natvis_file,
956         ne,
957         nearbyintf32,
958         nearbyintf64,
959         needs_allocator,
960         needs_drop,
961         needs_panic_runtime,
962         neg,
963         negate_unsigned,
964         negative_impls,
965         neon,
966         never,
967         never_type,
968         never_type_fallback,
969         new,
970         new_unchecked,
971         next,
972         nll,
973         no,
974         no_builtins,
975         no_core,
976         no_coverage,
977         no_crate_inject,
978         no_debug,
979         no_default_passes,
980         no_implicit_prelude,
981         no_inline,
982         no_link,
983         no_main,
984         no_mangle,
985         no_sanitize,
986         no_stack_check,
987         no_start,
988         no_std,
989         nomem,
990         non_ascii_idents,
991         non_exhaustive,
992         non_exhaustive_omitted_patterns_lint,
993         non_modrs_mods,
994         none_error,
995         nontemporal_store,
996         noop_method_borrow,
997         noop_method_clone,
998         noop_method_deref,
999         noreturn,
1000         nostack,
1001         not,
1002         notable_trait,
1003         note,
1004         object_safe_for_dispatch,
1005         of,
1006         offset,
1007         omit_gdb_pretty_printer_section,
1008         on,
1009         on_unimplemented,
1010         oom,
1011         opaque,
1012         ops,
1013         opt_out_copy,
1014         optimize,
1015         optimize_attribute,
1016         optin_builtin_traits,
1017         option,
1018         option_env,
1019         option_env_macro,
1020         options,
1021         or,
1022         or_patterns,
1023         other,
1024         out,
1025         overlapping_marker_traits,
1026         owned_box,
1027         packed,
1028         panic,
1029         panic_2015,
1030         panic_2021,
1031         panic_abort,
1032         panic_bounds_check,
1033         panic_display,
1034         panic_fmt,
1035         panic_handler,
1036         panic_impl,
1037         panic_implementation,
1038         panic_info,
1039         panic_location,
1040         panic_no_unwind,
1041         panic_runtime,
1042         panic_str,
1043         panic_unwind,
1044         panicking,
1045         param_attrs,
1046         partial_cmp,
1047         partial_ord,
1048         passes,
1049         pat,
1050         pat_param,
1051         path,
1052         pattern_parentheses,
1053         phantom_data,
1054         pin,
1055         platform_intrinsics,
1056         plugin,
1057         plugin_registrar,
1058         plugins,
1059         pointee_trait,
1060         pointer,
1061         pointer_trait_fmt,
1062         poll,
1063         position,
1064         post_dash_lto: "post-lto",
1065         powerpc_target_feature,
1066         powf32,
1067         powf64,
1068         powif32,
1069         powif64,
1070         pre_dash_lto: "pre-lto",
1071         precise_pointer_size_matching,
1072         precision,
1073         pref_align_of,
1074         prefetch_read_data,
1075         prefetch_read_instruction,
1076         prefetch_write_data,
1077         prefetch_write_instruction,
1078         preg,
1079         prelude,
1080         prelude_import,
1081         preserves_flags,
1082         primitive,
1083         print_macro,
1084         println_macro,
1085         proc_dash_macro: "proc-macro",
1086         proc_macro,
1087         proc_macro_attribute,
1088         proc_macro_def_site,
1089         proc_macro_derive,
1090         proc_macro_expr,
1091         proc_macro_gen,
1092         proc_macro_hygiene,
1093         proc_macro_internals,
1094         proc_macro_mod,
1095         proc_macro_non_items,
1096         proc_macro_path_invoc,
1097         profiler_builtins,
1098         profiler_runtime,
1099         ptr,
1100         ptr_guaranteed_eq,
1101         ptr_guaranteed_ne,
1102         ptr_null,
1103         ptr_null_mut,
1104         ptr_offset_from,
1105         ptr_offset_from_unsigned,
1106         pub_macro_rules,
1107         pub_restricted,
1108         pure,
1109         pushpop_unsafe,
1110         qreg,
1111         qreg_low4,
1112         qreg_low8,
1113         quad_precision_float,
1114         question_mark,
1115         quote,
1116         range_inclusive_new,
1117         raw_dylib,
1118         raw_eq,
1119         raw_identifiers,
1120         raw_ref_op,
1121         re_rebalance_coherence,
1122         read_enum,
1123         read_enum_variant,
1124         read_enum_variant_arg,
1125         read_struct,
1126         read_struct_field,
1127         readonly,
1128         realloc,
1129         reason,
1130         receiver,
1131         recursion_limit,
1132         reexport_test_harness_main,
1133         ref_unwind_safe_trait,
1134         reference,
1135         reflect,
1136         reg,
1137         reg16,
1138         reg32,
1139         reg64,
1140         reg_abcd,
1141         reg_byte,
1142         reg_iw,
1143         reg_nonzero,
1144         reg_pair,
1145         reg_ptr,
1146         reg_upper,
1147         register_attr,
1148         register_tool,
1149         relaxed_adts,
1150         relaxed_struct_unsize,
1151         rem,
1152         rem_assign,
1153         repr,
1154         repr128,
1155         repr_align,
1156         repr_align_enum,
1157         repr_packed,
1158         repr_simd,
1159         repr_transparent,
1160         residual,
1161         result,
1162         rhs,
1163         rintf32,
1164         rintf64,
1165         riscv_target_feature,
1166         rlib,
1167         rotate_left,
1168         rotate_right,
1169         roundf32,
1170         roundf64,
1171         rt,
1172         rtm_target_feature,
1173         rust,
1174         rust_2015,
1175         rust_2015_preview,
1176         rust_2018,
1177         rust_2018_preview,
1178         rust_2021,
1179         rust_2021_preview,
1180         rust_2024,
1181         rust_2024_preview,
1182         rust_begin_unwind,
1183         rust_cold_cc,
1184         rust_eh_catch_typeinfo,
1185         rust_eh_personality,
1186         rust_eh_register_frames,
1187         rust_eh_unregister_frames,
1188         rust_oom,
1189         rustc,
1190         rustc_allocator,
1191         rustc_allocator_nounwind,
1192         rustc_allow_const_fn_unstable,
1193         rustc_allow_incoherent_impl,
1194         rustc_allowed_through_unstable_modules,
1195         rustc_attrs,
1196         rustc_box,
1197         rustc_builtin_macro,
1198         rustc_capture_analysis,
1199         rustc_clean,
1200         rustc_coherence_is_core,
1201         rustc_const_stable,
1202         rustc_const_unstable,
1203         rustc_conversion_suggestion,
1204         rustc_def_path,
1205         rustc_diagnostic_item,
1206         rustc_diagnostic_macros,
1207         rustc_dirty,
1208         rustc_do_not_const_check,
1209         rustc_dummy,
1210         rustc_dump_env_program_clauses,
1211         rustc_dump_program_clauses,
1212         rustc_dump_user_substs,
1213         rustc_dump_vtable,
1214         rustc_error,
1215         rustc_evaluate_where_clauses,
1216         rustc_expected_cgu_reuse,
1217         rustc_has_incoherent_inherent_impls,
1218         rustc_if_this_changed,
1219         rustc_inherit_overflow_checks,
1220         rustc_insignificant_dtor,
1221         rustc_layout,
1222         rustc_layout_scalar_valid_range_end,
1223         rustc_layout_scalar_valid_range_start,
1224         rustc_legacy_const_generics,
1225         rustc_lint_diagnostics,
1226         rustc_lint_query_instability,
1227         rustc_macro_transparency,
1228         rustc_main,
1229         rustc_mir,
1230         rustc_must_implement_one_of,
1231         rustc_nonnull_optimization_guaranteed,
1232         rustc_object_lifetime_default,
1233         rustc_on_unimplemented,
1234         rustc_outlives,
1235         rustc_paren_sugar,
1236         rustc_partition_codegened,
1237         rustc_partition_reused,
1238         rustc_pass_by_value,
1239         rustc_peek,
1240         rustc_peek_definite_init,
1241         rustc_peek_liveness,
1242         rustc_peek_maybe_init,
1243         rustc_peek_maybe_uninit,
1244         rustc_polymorphize_error,
1245         rustc_private,
1246         rustc_proc_macro_decls,
1247         rustc_promotable,
1248         rustc_regions,
1249         rustc_reservation_impl,
1250         rustc_serialize,
1251         rustc_skip_array_during_method_dispatch,
1252         rustc_specialization_trait,
1253         rustc_stable,
1254         rustc_std_internal_symbol,
1255         rustc_strict_coherence,
1256         rustc_symbol_name,
1257         rustc_test_marker,
1258         rustc_then_this_would_need,
1259         rustc_trivial_field_reads,
1260         rustc_unsafe_specialization_marker,
1261         rustc_variance,
1262         rustdoc,
1263         rustdoc_internals,
1264         rustfmt,
1265         rvalue_static_promotion,
1266         s,
1267         sanitize,
1268         sanitizer_runtime,
1269         saturating_add,
1270         saturating_sub,
1271         self_in_typedefs,
1272         self_struct_ctor,
1273         semitransparent,
1274         shl,
1275         shl_assign,
1276         should_panic,
1277         shr,
1278         shr_assign,
1279         simd,
1280         simd_add,
1281         simd_and,
1282         simd_arith_offset,
1283         simd_as,
1284         simd_bitmask,
1285         simd_cast,
1286         simd_ceil,
1287         simd_div,
1288         simd_eq,
1289         simd_extract,
1290         simd_fabs,
1291         simd_fcos,
1292         simd_fexp,
1293         simd_fexp2,
1294         simd_ffi,
1295         simd_flog,
1296         simd_flog10,
1297         simd_flog2,
1298         simd_floor,
1299         simd_fma,
1300         simd_fmax,
1301         simd_fmin,
1302         simd_fpow,
1303         simd_fpowi,
1304         simd_fsin,
1305         simd_fsqrt,
1306         simd_gather,
1307         simd_ge,
1308         simd_gt,
1309         simd_insert,
1310         simd_le,
1311         simd_lt,
1312         simd_mul,
1313         simd_ne,
1314         simd_neg,
1315         simd_or,
1316         simd_reduce_add_ordered,
1317         simd_reduce_add_unordered,
1318         simd_reduce_all,
1319         simd_reduce_and,
1320         simd_reduce_any,
1321         simd_reduce_max,
1322         simd_reduce_max_nanless,
1323         simd_reduce_min,
1324         simd_reduce_min_nanless,
1325         simd_reduce_mul_ordered,
1326         simd_reduce_mul_unordered,
1327         simd_reduce_or,
1328         simd_reduce_xor,
1329         simd_rem,
1330         simd_round,
1331         simd_saturating_add,
1332         simd_saturating_sub,
1333         simd_scatter,
1334         simd_select,
1335         simd_select_bitmask,
1336         simd_shl,
1337         simd_shr,
1338         simd_shuffle,
1339         simd_sub,
1340         simd_trunc,
1341         simd_xor,
1342         since,
1343         sinf32,
1344         sinf64,
1345         size,
1346         size_of,
1347         size_of_val,
1348         sized,
1349         skip,
1350         slice,
1351         slice_len_fn,
1352         slice_patterns,
1353         slicing_syntax,
1354         soft,
1355         specialization,
1356         speed,
1357         spotlight,
1358         sqrtf32,
1359         sqrtf64,
1360         sreg,
1361         sreg_low16,
1362         sse,
1363         sse4a_target_feature,
1364         stable,
1365         staged_api,
1366         start,
1367         state,
1368         static_in_const,
1369         static_nobundle,
1370         static_recursion,
1371         staticlib,
1372         std,
1373         std_inject,
1374         std_panic,
1375         std_panic_2015_macro,
1376         std_panic_macro,
1377         stmt,
1378         stmt_expr_attributes,
1379         stop_after_dataflow,
1380         store,
1381         str,
1382         str_split_whitespace,
1383         str_trim,
1384         str_trim_end,
1385         str_trim_start,
1386         strict_provenance,
1387         stringify,
1388         stringify_macro,
1389         struct_field_attributes,
1390         struct_inherit,
1391         struct_variant,
1392         structural_match,
1393         structural_peq,
1394         structural_teq,
1395         sty,
1396         sub,
1397         sub_assign,
1398         sub_with_overflow,
1399         suggestion,
1400         sym,
1401         sync,
1402         t32,
1403         target,
1404         target_abi,
1405         target_arch,
1406         target_endian,
1407         target_env,
1408         target_family,
1409         target_feature,
1410         target_feature_11,
1411         target_has_atomic,
1412         target_has_atomic_equal_alignment,
1413         target_has_atomic_load_store,
1414         target_os,
1415         target_pointer_width,
1416         target_target_vendor,
1417         target_thread_local,
1418         target_vendor,
1419         task,
1420         tbm_target_feature,
1421         termination,
1422         termination_trait,
1423         termination_trait_test,
1424         test,
1425         test_2018_feature,
1426         test_accepted_feature,
1427         test_case,
1428         test_removed_feature,
1429         test_runner,
1430         test_unstable_lint,
1431         then_with,
1432         thread,
1433         thread_local,
1434         thread_local_macro,
1435         thumb2,
1436         thumb_mode: "thumb-mode",
1437         tmm_reg,
1438         to_string,
1439         to_vec,
1440         todo_macro,
1441         tool_attributes,
1442         tool_lints,
1443         trace_macros,
1444         track_caller,
1445         trait_alias,
1446         trait_upcasting,
1447         transmute,
1448         transparent,
1449         transparent_enums,
1450         transparent_unions,
1451         trivial_bounds,
1452         truncf32,
1453         truncf64,
1454         try_blocks,
1455         try_capture,
1456         try_from,
1457         try_into,
1458         try_trait_v2,
1459         tt,
1460         tuple,
1461         tuple_from_req,
1462         tuple_indexing,
1463         tuple_variadic,
1464         two_phase,
1465         ty,
1466         type_alias_enum_variants,
1467         type_alias_impl_trait,
1468         type_ascription,
1469         type_changing_struct_update,
1470         type_id,
1471         type_length_limit,
1472         type_macros,
1473         type_name,
1474         u128,
1475         u16,
1476         u32,
1477         u64,
1478         u8,
1479         unaligned_volatile_load,
1480         unaligned_volatile_store,
1481         unboxed_closures,
1482         unchecked_add,
1483         unchecked_div,
1484         unchecked_mul,
1485         unchecked_rem,
1486         unchecked_shl,
1487         unchecked_shr,
1488         unchecked_sub,
1489         underscore_const_names,
1490         underscore_imports,
1491         underscore_lifetimes,
1492         uniform_paths,
1493         unimplemented_macro,
1494         unit,
1495         universal_impl_trait,
1496         unix,
1497         unlikely,
1498         unmarked_api,
1499         unpin,
1500         unreachable,
1501         unreachable_2015,
1502         unreachable_2015_macro,
1503         unreachable_2021,
1504         unreachable_2021_macro,
1505         unreachable_code,
1506         unreachable_display,
1507         unreachable_macro,
1508         unrestricted_attribute_tokens,
1509         unsafe_block_in_unsafe_fn,
1510         unsafe_cell,
1511         unsafe_no_drop_flag,
1512         unsafe_pin_internals,
1513         unsize,
1514         unsized_fn_params,
1515         unsized_locals,
1516         unsized_tuple_coercion,
1517         unstable,
1518         untagged_unions,
1519         unused_imports,
1520         unused_qualifications,
1521         unwind,
1522         unwind_attributes,
1523         unwind_safe_trait,
1524         unwrap,
1525         unwrap_or,
1526         use_extern_macros,
1527         use_nested_groups,
1528         used,
1529         used_with_arg,
1530         using,
1531         usize,
1532         v1,
1533         va_arg,
1534         va_copy,
1535         va_end,
1536         va_list,
1537         va_start,
1538         val,
1539         values,
1540         var,
1541         variant_count,
1542         vec,
1543         vec_macro,
1544         version,
1545         vfp2,
1546         vis,
1547         visible_private_types,
1548         volatile,
1549         volatile_copy_memory,
1550         volatile_copy_nonoverlapping_memory,
1551         volatile_load,
1552         volatile_set_memory,
1553         volatile_store,
1554         vreg,
1555         vreg_low16,
1556         warn,
1557         wasm_abi,
1558         wasm_import_module,
1559         wasm_target_feature,
1560         while_let,
1561         width,
1562         windows,
1563         windows_subsystem,
1564         with_negative_coherence,
1565         wrapping_add,
1566         wrapping_mul,
1567         wrapping_sub,
1568         wreg,
1569         write_bytes,
1570         write_macro,
1571         write_str,
1572         writeln_macro,
1573         x87_reg,
1574         xer,
1575         xmm_reg,
1576         yeet_desugar_details,
1577         yeet_expr,
1578         ymm_reg,
1579         zmm_reg,
1580     }
1581 }
1582
1583 #[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
1584 pub struct Ident {
1585     pub name: Symbol,
1586     pub span: Span,
1587 }
1588
1589 impl Ident {
1590     #[inline]
1591     /// Constructs a new identifier from a symbol and a span.
1592     pub const fn new(name: Symbol, span: Span) -> Ident {
1593         Ident { name, span }
1594     }
1595
1596     /// Constructs a new identifier with a dummy span.
1597     #[inline]
1598     pub const fn with_dummy_span(name: Symbol) -> Ident {
1599         Ident::new(name, DUMMY_SP)
1600     }
1601
1602     #[inline]
1603     pub fn empty() -> Ident {
1604         Ident::with_dummy_span(kw::Empty)
1605     }
1606
1607     /// Maps a string to an identifier with a dummy span.
1608     pub fn from_str(string: &str) -> Ident {
1609         Ident::with_dummy_span(Symbol::intern(string))
1610     }
1611
1612     /// Maps a string and a span to an identifier.
1613     pub fn from_str_and_span(string: &str, span: Span) -> Ident {
1614         Ident::new(Symbol::intern(string), span)
1615     }
1616
1617     /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
1618     pub fn with_span_pos(self, span: Span) -> Ident {
1619         Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
1620     }
1621
1622     pub fn without_first_quote(self) -> Ident {
1623         Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
1624     }
1625
1626     /// "Normalize" ident for use in comparisons using "item hygiene".
1627     /// Identifiers with same string value become same if they came from the same macro 2.0 macro
1628     /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
1629     /// different macro 2.0 macros.
1630     /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
1631     pub fn normalize_to_macros_2_0(self) -> Ident {
1632         Ident::new(self.name, self.span.normalize_to_macros_2_0())
1633     }
1634
1635     /// "Normalize" ident for use in comparisons using "local variable hygiene".
1636     /// Identifiers with same string value become same if they came from the same non-transparent
1637     /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
1638     /// non-transparent macros.
1639     /// Technically, this operation strips all transparent marks from ident's syntactic context.
1640     pub fn normalize_to_macro_rules(self) -> Ident {
1641         Ident::new(self.name, self.span.normalize_to_macro_rules())
1642     }
1643
1644     /// Access the underlying string. This is a slowish operation because it
1645     /// requires locking the symbol interner.
1646     ///
1647     /// Note that the lifetime of the return value is a lie. See
1648     /// `Symbol::as_str()` for details.
1649     pub fn as_str(&self) -> &str {
1650         self.name.as_str()
1651     }
1652 }
1653
1654 impl PartialEq for Ident {
1655     fn eq(&self, rhs: &Self) -> bool {
1656         self.name == rhs.name && self.span.eq_ctxt(rhs.span)
1657     }
1658 }
1659
1660 impl Hash for Ident {
1661     fn hash<H: Hasher>(&self, state: &mut H) {
1662         self.name.hash(state);
1663         self.span.ctxt().hash(state);
1664     }
1665 }
1666
1667 impl fmt::Debug for Ident {
1668     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1669         fmt::Display::fmt(self, f)?;
1670         fmt::Debug::fmt(&self.span.ctxt(), f)
1671     }
1672 }
1673
1674 /// This implementation is supposed to be used in error messages, so it's expected to be identical
1675 /// to printing the original identifier token written in source code (`token_to_string`),
1676 /// except that AST identifiers don't keep the rawness flag, so we have to guess it.
1677 impl fmt::Display for Ident {
1678     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1679         fmt::Display::fmt(&IdentPrinter::new(self.name, self.is_raw_guess(), None), f)
1680     }
1681 }
1682
1683 /// This is the most general way to print identifiers.
1684 /// AST pretty-printer is used as a fallback for turning AST structures into token streams for
1685 /// proc macros. Additionally, proc macros may stringify their input and expect it survive the
1686 /// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
1687 /// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
1688 /// hygiene data, most importantly name of the crate it refers to.
1689 /// As a result we print `$crate` as `crate` if it refers to the local crate
1690 /// and as `::other_crate_name` if it refers to some other crate.
1691 /// Note, that this is only done if the ident token is printed from inside of AST pretty-printing,
1692 /// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
1693 /// so we should not perform this lossy conversion if the top level call to the pretty-printer was
1694 /// done for a token stream or a single token.
1695 pub struct IdentPrinter {
1696     symbol: Symbol,
1697     is_raw: bool,
1698     /// Span used for retrieving the crate name to which `$crate` refers to,
1699     /// if this field is `None` then the `$crate` conversion doesn't happen.
1700     convert_dollar_crate: Option<Span>,
1701 }
1702
1703 impl IdentPrinter {
1704     /// The most general `IdentPrinter` constructor. Do not use this.
1705     pub fn new(symbol: Symbol, is_raw: bool, convert_dollar_crate: Option<Span>) -> IdentPrinter {
1706         IdentPrinter { symbol, is_raw, convert_dollar_crate }
1707     }
1708
1709     /// This implementation is supposed to be used when printing identifiers
1710     /// as a part of pretty-printing for larger AST pieces.
1711     /// Do not use this either.
1712     pub fn for_ast_ident(ident: Ident, is_raw: bool) -> IdentPrinter {
1713         IdentPrinter::new(ident.name, is_raw, Some(ident.span))
1714     }
1715 }
1716
1717 impl fmt::Display for IdentPrinter {
1718     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1719         if self.is_raw {
1720             f.write_str("r#")?;
1721         } else if self.symbol == kw::DollarCrate {
1722             if let Some(span) = self.convert_dollar_crate {
1723                 let converted = span.ctxt().dollar_crate_name();
1724                 if !converted.is_path_segment_keyword() {
1725                     f.write_str("::")?;
1726                 }
1727                 return fmt::Display::fmt(&converted, f);
1728             }
1729         }
1730         fmt::Display::fmt(&self.symbol, f)
1731     }
1732 }
1733
1734 /// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
1735 /// construction.
1736 // FIXME(matthewj, petrochenkov) Use this more often, add a similar
1737 // `ModernIdent` struct and use that as well.
1738 #[derive(Copy, Clone, Eq, PartialEq, Hash)]
1739 pub struct MacroRulesNormalizedIdent(Ident);
1740
1741 impl MacroRulesNormalizedIdent {
1742     pub fn new(ident: Ident) -> Self {
1743         Self(ident.normalize_to_macro_rules())
1744     }
1745 }
1746
1747 impl fmt::Debug for MacroRulesNormalizedIdent {
1748     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1749         fmt::Debug::fmt(&self.0, f)
1750     }
1751 }
1752
1753 impl fmt::Display for MacroRulesNormalizedIdent {
1754     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1755         fmt::Display::fmt(&self.0, f)
1756     }
1757 }
1758
1759 /// An interned string.
1760 ///
1761 /// Internally, a `Symbol` is implemented as an index, and all operations
1762 /// (including hashing, equality, and ordering) operate on that index. The use
1763 /// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
1764 /// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
1765 ///
1766 /// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
1767 /// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
1768 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1769 pub struct Symbol(SymbolIndex);
1770
1771 rustc_index::newtype_index! {
1772     struct SymbolIndex { .. }
1773 }
1774
1775 impl Symbol {
1776     const fn new(n: u32) -> Self {
1777         Symbol(SymbolIndex::from_u32(n))
1778     }
1779
1780     /// Maps a string to its interned representation.
1781     pub fn intern(string: &str) -> Self {
1782         with_session_globals(|session_globals| session_globals.symbol_interner.intern(string))
1783     }
1784
1785     /// Access the underlying string. This is a slowish operation because it
1786     /// requires locking the symbol interner.
1787     ///
1788     /// Note that the lifetime of the return value is a lie. It's not the same
1789     /// as `&self`, but actually tied to the lifetime of the underlying
1790     /// interner. Interners are long-lived, and there are very few of them, and
1791     /// this function is typically used for short-lived things, so in practice
1792     /// it works out ok.
1793     pub fn as_str(&self) -> &str {
1794         with_session_globals(|session_globals| unsafe {
1795             std::mem::transmute::<&str, &str>(session_globals.symbol_interner.get(*self))
1796         })
1797     }
1798
1799     pub fn as_u32(self) -> u32 {
1800         self.0.as_u32()
1801     }
1802
1803     pub fn is_empty(self) -> bool {
1804         self == kw::Empty
1805     }
1806
1807     /// This method is supposed to be used in error messages, so it's expected to be
1808     /// identical to printing the original identifier token written in source code
1809     /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
1810     /// or edition, so we have to guess the rawness using the global edition.
1811     pub fn to_ident_string(self) -> String {
1812         Ident::with_dummy_span(self).to_string()
1813     }
1814 }
1815
1816 impl fmt::Debug for Symbol {
1817     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1818         fmt::Debug::fmt(self.as_str(), f)
1819     }
1820 }
1821
1822 impl fmt::Display for Symbol {
1823     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1824         fmt::Display::fmt(self.as_str(), f)
1825     }
1826 }
1827
1828 impl<S: Encoder> Encodable<S> for Symbol {
1829     fn encode(&self, s: &mut S) {
1830         s.emit_str(self.as_str());
1831     }
1832 }
1833
1834 impl<D: Decoder> Decodable<D> for Symbol {
1835     #[inline]
1836     fn decode(d: &mut D) -> Symbol {
1837         Symbol::intern(&d.read_str())
1838     }
1839 }
1840
1841 impl<CTX> HashStable<CTX> for Symbol {
1842     #[inline]
1843     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1844         self.as_str().hash_stable(hcx, hasher);
1845     }
1846 }
1847
1848 impl<CTX> ToStableHashKey<CTX> for Symbol {
1849     type KeyType = String;
1850     #[inline]
1851     fn to_stable_hash_key(&self, _: &CTX) -> String {
1852         self.as_str().to_string()
1853     }
1854 }
1855
1856 #[derive(Default)]
1857 pub(crate) struct Interner(Lock<InternerInner>);
1858
1859 // The `&'static str`s in this type actually point into the arena.
1860 //
1861 // The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
1862 // found that to regress performance up to 2% in some cases. This might be
1863 // revisited after further improvements to `indexmap`.
1864 //
1865 // This type is private to prevent accidentally constructing more than one
1866 // `Interner` on the same thread, which makes it easy to mix up `Symbol`s
1867 // between `Interner`s.
1868 #[derive(Default)]
1869 struct InternerInner {
1870     arena: DroplessArena,
1871     names: FxHashMap<&'static str, Symbol>,
1872     strings: Vec<&'static str>,
1873 }
1874
1875 impl Interner {
1876     fn prefill(init: &[&'static str]) -> Self {
1877         Interner(Lock::new(InternerInner {
1878             strings: init.into(),
1879             names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
1880             ..Default::default()
1881         }))
1882     }
1883
1884     #[inline]
1885     fn intern(&self, string: &str) -> Symbol {
1886         let mut inner = self.0.lock();
1887         if let Some(&name) = inner.names.get(string) {
1888             return name;
1889         }
1890
1891         let name = Symbol::new(inner.strings.len() as u32);
1892
1893         // SAFETY: we convert from `&str` to `&[u8]`, clone it into the arena,
1894         // and immediately convert the clone back to `&[u8], all because there
1895         // is no `inner.arena.alloc_str()` method. This is clearly safe.
1896         let string: &str =
1897             unsafe { str::from_utf8_unchecked(inner.arena.alloc_slice(string.as_bytes())) };
1898
1899         // SAFETY: we can extend the arena allocation to `'static` because we
1900         // only access these while the arena is still alive.
1901         let string: &'static str = unsafe { &*(string as *const str) };
1902         inner.strings.push(string);
1903
1904         // This second hash table lookup can be avoided by using `RawEntryMut`,
1905         // but this code path isn't hot enough for it to be worth it. See
1906         // #91445 for details.
1907         inner.names.insert(string, name);
1908         name
1909     }
1910
1911     // Get the symbol as a string. `Symbol::as_str()` should be used in
1912     // preference to this function.
1913     fn get(&self, symbol: Symbol) -> &str {
1914         self.0.lock().strings[symbol.0.as_usize()]
1915     }
1916 }
1917
1918 // This module has a very short name because it's used a lot.
1919 /// This module contains all the defined keyword `Symbol`s.
1920 ///
1921 /// Given that `kw` is imported, use them like `kw::keyword_name`.
1922 /// For example `kw::Loop` or `kw::Break`.
1923 pub mod kw {
1924     pub use super::kw_generated::*;
1925 }
1926
1927 // This module has a very short name because it's used a lot.
1928 /// This module contains all the defined non-keyword `Symbol`s.
1929 ///
1930 /// Given that `sym` is imported, use them like `sym::symbol_name`.
1931 /// For example `sym::rustfmt` or `sym::u8`.
1932 pub mod sym {
1933     use super::Symbol;
1934     use std::convert::TryInto;
1935
1936     #[doc(inline)]
1937     pub use super::sym_generated::*;
1938
1939     // Used from a macro in `librustc_feature/accepted.rs`
1940     pub use super::kw::MacroRules as macro_rules;
1941
1942     /// Get the symbol for an integer.
1943     ///
1944     /// The first few non-negative integers each have a static symbol and therefore
1945     /// are fast.
1946     pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
1947         if let Result::Ok(idx) = n.try_into() {
1948             if idx < 10 {
1949                 return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
1950             }
1951         }
1952         Symbol::intern(&n.to_string())
1953     }
1954 }
1955
1956 impl Symbol {
1957     fn is_special(self) -> bool {
1958         self <= kw::Underscore
1959     }
1960
1961     fn is_used_keyword_always(self) -> bool {
1962         self >= kw::As && self <= kw::While
1963     }
1964
1965     fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1966         (self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
1967     }
1968
1969     fn is_unused_keyword_always(self) -> bool {
1970         self >= kw::Abstract && self <= kw::Yield
1971     }
1972
1973     fn is_unused_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1974         self == kw::Try && edition() >= Edition::Edition2018
1975     }
1976
1977     pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
1978         self.is_special()
1979             || self.is_used_keyword_always()
1980             || self.is_unused_keyword_always()
1981             || self.is_used_keyword_conditional(edition)
1982             || self.is_unused_keyword_conditional(edition)
1983     }
1984
1985     /// A keyword or reserved identifier that can be used as a path segment.
1986     pub fn is_path_segment_keyword(self) -> bool {
1987         self == kw::Super
1988             || self == kw::SelfLower
1989             || self == kw::SelfUpper
1990             || self == kw::Crate
1991             || self == kw::PathRoot
1992             || self == kw::DollarCrate
1993     }
1994
1995     /// Returns `true` if the symbol is `true` or `false`.
1996     pub fn is_bool_lit(self) -> bool {
1997         self == kw::True || self == kw::False
1998     }
1999
2000     /// Returns `true` if this symbol can be a raw identifier.
2001     pub fn can_be_raw(self) -> bool {
2002         self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword()
2003     }
2004 }
2005
2006 impl Ident {
2007     // Returns `true` for reserved identifiers used internally for elided lifetimes,
2008     // unnamed method parameters, crate root module, error recovery etc.
2009     pub fn is_special(self) -> bool {
2010         self.name.is_special()
2011     }
2012
2013     /// Returns `true` if the token is a keyword used in the language.
2014     pub fn is_used_keyword(self) -> bool {
2015         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
2016         self.name.is_used_keyword_always()
2017             || self.name.is_used_keyword_conditional(|| self.span.edition())
2018     }
2019
2020     /// Returns `true` if the token is a keyword reserved for possible future use.
2021     pub fn is_unused_keyword(self) -> bool {
2022         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
2023         self.name.is_unused_keyword_always()
2024             || self.name.is_unused_keyword_conditional(|| self.span.edition())
2025     }
2026
2027     /// Returns `true` if the token is either a special identifier or a keyword.
2028     pub fn is_reserved(self) -> bool {
2029         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
2030         self.name.is_reserved(|| self.span.edition())
2031     }
2032
2033     /// A keyword or reserved identifier that can be used as a path segment.
2034     pub fn is_path_segment_keyword(self) -> bool {
2035         self.name.is_path_segment_keyword()
2036     }
2037
2038     /// We see this identifier in a normal identifier position, like variable name or a type.
2039     /// How was it written originally? Did it use the raw form? Let's try to guess.
2040     pub fn is_raw_guess(self) -> bool {
2041         self.name.can_be_raw() && self.is_reserved()
2042     }
2043 }