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