]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_span/src/symbol.rs
Rollup merge of #93118 - jackh726:param-heuristics-3, r=estebank
[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         rustdoc,
1208         rustdoc_internals,
1209         rustfmt,
1210         rvalue_static_promotion,
1211         s,
1212         sanitize,
1213         sanitizer_runtime,
1214         saturating_add,
1215         saturating_sub,
1216         self_in_typedefs,
1217         self_struct_ctor,
1218         semitransparent,
1219         shl,
1220         shl_assign,
1221         should_panic,
1222         shr,
1223         shr_assign,
1224         simd,
1225         simd_add,
1226         simd_and,
1227         simd_as,
1228         simd_bitmask,
1229         simd_cast,
1230         simd_ceil,
1231         simd_div,
1232         simd_eq,
1233         simd_extract,
1234         simd_fabs,
1235         simd_fcos,
1236         simd_fexp,
1237         simd_fexp2,
1238         simd_ffi,
1239         simd_flog,
1240         simd_flog10,
1241         simd_flog2,
1242         simd_floor,
1243         simd_fma,
1244         simd_fmax,
1245         simd_fmin,
1246         simd_fpow,
1247         simd_fpowi,
1248         simd_fsin,
1249         simd_fsqrt,
1250         simd_gather,
1251         simd_ge,
1252         simd_gt,
1253         simd_insert,
1254         simd_le,
1255         simd_lt,
1256         simd_mul,
1257         simd_ne,
1258         simd_neg,
1259         simd_or,
1260         simd_reduce_add_ordered,
1261         simd_reduce_add_unordered,
1262         simd_reduce_all,
1263         simd_reduce_and,
1264         simd_reduce_any,
1265         simd_reduce_max,
1266         simd_reduce_max_nanless,
1267         simd_reduce_min,
1268         simd_reduce_min_nanless,
1269         simd_reduce_mul_ordered,
1270         simd_reduce_mul_unordered,
1271         simd_reduce_or,
1272         simd_reduce_xor,
1273         simd_rem,
1274         simd_round,
1275         simd_saturating_add,
1276         simd_saturating_sub,
1277         simd_scatter,
1278         simd_select,
1279         simd_select_bitmask,
1280         simd_shl,
1281         simd_shr,
1282         simd_shuffle,
1283         simd_sub,
1284         simd_trunc,
1285         simd_xor,
1286         since,
1287         sinf32,
1288         sinf64,
1289         size,
1290         size_of,
1291         size_of_val,
1292         sized,
1293         skip,
1294         slice,
1295         slice_alloc,
1296         slice_len_fn,
1297         slice_patterns,
1298         slice_u8,
1299         slice_u8_alloc,
1300         slicing_syntax,
1301         soft,
1302         specialization,
1303         speed,
1304         spotlight,
1305         sqrtf32,
1306         sqrtf64,
1307         sreg,
1308         sreg_low16,
1309         sse,
1310         sse4a_target_feature,
1311         stable,
1312         staged_api,
1313         start,
1314         state,
1315         static_in_const,
1316         static_nobundle,
1317         static_recursion,
1318         staticlib,
1319         std,
1320         std_inject,
1321         std_panic,
1322         std_panic_2015_macro,
1323         std_panic_macro,
1324         stmt,
1325         stmt_expr_attributes,
1326         stop_after_dataflow,
1327         store,
1328         str,
1329         str_alloc,
1330         stringify,
1331         stringify_macro,
1332         struct_field_attributes,
1333         struct_inherit,
1334         struct_variant,
1335         structural_match,
1336         structural_peq,
1337         structural_teq,
1338         sty,
1339         sub,
1340         sub_assign,
1341         sub_with_overflow,
1342         suggestion,
1343         sym,
1344         sync,
1345         t32,
1346         target_abi,
1347         target_arch,
1348         target_endian,
1349         target_env,
1350         target_family,
1351         target_feature,
1352         target_feature_11,
1353         target_has_atomic,
1354         target_has_atomic_equal_alignment,
1355         target_has_atomic_load_store,
1356         target_os,
1357         target_pointer_width,
1358         target_target_vendor,
1359         target_thread_local,
1360         target_vendor,
1361         task,
1362         tbm_target_feature,
1363         termination,
1364         termination_trait,
1365         termination_trait_test,
1366         test,
1367         test_2018_feature,
1368         test_accepted_feature,
1369         test_case,
1370         test_removed_feature,
1371         test_runner,
1372         then_with,
1373         thread,
1374         thread_local,
1375         thread_local_macro,
1376         thumb2,
1377         thumb_mode: "thumb-mode",
1378         todo_macro,
1379         tool_attributes,
1380         tool_lints,
1381         trace_macros,
1382         track_caller,
1383         trait_alias,
1384         trait_upcasting,
1385         transmute,
1386         transparent,
1387         transparent_enums,
1388         transparent_unions,
1389         trivial_bounds,
1390         truncf32,
1391         truncf64,
1392         try_blocks,
1393         try_from,
1394         try_into,
1395         try_trait_v2,
1396         tt,
1397         tuple,
1398         tuple_from_req,
1399         tuple_indexing,
1400         two_phase,
1401         ty,
1402         type_alias_enum_variants,
1403         type_alias_impl_trait,
1404         type_ascription,
1405         type_changing_struct_update,
1406         type_id,
1407         type_length_limit,
1408         type_macros,
1409         type_name,
1410         u128,
1411         u16,
1412         u32,
1413         u64,
1414         u8,
1415         unaligned_volatile_load,
1416         unaligned_volatile_store,
1417         unboxed_closures,
1418         unchecked_add,
1419         unchecked_div,
1420         unchecked_mul,
1421         unchecked_rem,
1422         unchecked_shl,
1423         unchecked_shr,
1424         unchecked_sub,
1425         underscore_const_names,
1426         underscore_imports,
1427         underscore_lifetimes,
1428         uniform_paths,
1429         unimplemented_macro,
1430         unit,
1431         universal_impl_trait,
1432         unix,
1433         unlikely,
1434         unmarked_api,
1435         unpin,
1436         unreachable,
1437         unreachable_code,
1438         unreachable_macro,
1439         unrestricted_attribute_tokens,
1440         unsafe_block_in_unsafe_fn,
1441         unsafe_cell,
1442         unsafe_no_drop_flag,
1443         unsize,
1444         unsized_fn_params,
1445         unsized_locals,
1446         unsized_tuple_coercion,
1447         unstable,
1448         untagged_unions,
1449         unused_qualifications,
1450         unwind,
1451         unwind_attributes,
1452         unwind_safe_trait,
1453         unwrap,
1454         unwrap_or,
1455         use_extern_macros,
1456         use_nested_groups,
1457         used,
1458         usize,
1459         v1,
1460         va_arg,
1461         va_copy,
1462         va_end,
1463         va_list,
1464         va_start,
1465         val,
1466         var,
1467         variant_count,
1468         vec,
1469         vec_macro,
1470         version,
1471         vfp2,
1472         vis,
1473         visible_private_types,
1474         volatile,
1475         volatile_copy_memory,
1476         volatile_copy_nonoverlapping_memory,
1477         volatile_load,
1478         volatile_set_memory,
1479         volatile_store,
1480         vreg,
1481         vreg_low16,
1482         warn,
1483         wasm_abi,
1484         wasm_import_module,
1485         wasm_target_feature,
1486         while_let,
1487         width,
1488         windows,
1489         windows_subsystem,
1490         wrapping_add,
1491         wrapping_mul,
1492         wrapping_sub,
1493         wreg,
1494         write_bytes,
1495         write_macro,
1496         write_str,
1497         writeln_macro,
1498         x87_reg,
1499         xer,
1500         xmm_reg,
1501         ymm_reg,
1502         zmm_reg,
1503     }
1504 }
1505
1506 #[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
1507 pub struct Ident {
1508     pub name: Symbol,
1509     pub span: Span,
1510 }
1511
1512 impl Ident {
1513     #[inline]
1514     /// Constructs a new identifier from a symbol and a span.
1515     pub const fn new(name: Symbol, span: Span) -> Ident {
1516         Ident { name, span }
1517     }
1518
1519     /// Constructs a new identifier with a dummy span.
1520     #[inline]
1521     pub const fn with_dummy_span(name: Symbol) -> Ident {
1522         Ident::new(name, DUMMY_SP)
1523     }
1524
1525     #[inline]
1526     pub fn empty() -> Ident {
1527         Ident::with_dummy_span(kw::Empty)
1528     }
1529
1530     /// Maps a string to an identifier with a dummy span.
1531     pub fn from_str(string: &str) -> Ident {
1532         Ident::with_dummy_span(Symbol::intern(string))
1533     }
1534
1535     /// Maps a string and a span to an identifier.
1536     pub fn from_str_and_span(string: &str, span: Span) -> Ident {
1537         Ident::new(Symbol::intern(string), span)
1538     }
1539
1540     /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
1541     pub fn with_span_pos(self, span: Span) -> Ident {
1542         Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
1543     }
1544
1545     pub fn without_first_quote(self) -> Ident {
1546         Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
1547     }
1548
1549     /// "Normalize" ident for use in comparisons using "item hygiene".
1550     /// Identifiers with same string value become same if they came from the same macro 2.0 macro
1551     /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
1552     /// different macro 2.0 macros.
1553     /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
1554     pub fn normalize_to_macros_2_0(self) -> Ident {
1555         Ident::new(self.name, self.span.normalize_to_macros_2_0())
1556     }
1557
1558     /// "Normalize" ident for use in comparisons using "local variable hygiene".
1559     /// Identifiers with same string value become same if they came from the same non-transparent
1560     /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
1561     /// non-transparent macros.
1562     /// Technically, this operation strips all transparent marks from ident's syntactic context.
1563     pub fn normalize_to_macro_rules(self) -> Ident {
1564         Ident::new(self.name, self.span.normalize_to_macro_rules())
1565     }
1566
1567     /// Access the underlying string. This is a slowish operation because it
1568     /// requires locking the symbol interner.
1569     ///
1570     /// Note that the lifetime of the return value is a lie. See
1571     /// `Symbol::as_str()` for details.
1572     pub fn as_str(&self) -> &str {
1573         self.name.as_str()
1574     }
1575 }
1576
1577 impl PartialEq for Ident {
1578     fn eq(&self, rhs: &Self) -> bool {
1579         self.name == rhs.name && self.span.ctxt() == rhs.span.ctxt()
1580     }
1581 }
1582
1583 impl Hash for Ident {
1584     fn hash<H: Hasher>(&self, state: &mut H) {
1585         self.name.hash(state);
1586         self.span.ctxt().hash(state);
1587     }
1588 }
1589
1590 impl fmt::Debug for Ident {
1591     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1592         fmt::Display::fmt(self, f)?;
1593         fmt::Debug::fmt(&self.span.ctxt(), f)
1594     }
1595 }
1596
1597 /// This implementation is supposed to be used in error messages, so it's expected to be identical
1598 /// to printing the original identifier token written in source code (`token_to_string`),
1599 /// except that AST identifiers don't keep the rawness flag, so we have to guess it.
1600 impl fmt::Display for Ident {
1601     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1602         fmt::Display::fmt(&IdentPrinter::new(self.name, self.is_raw_guess(), None), f)
1603     }
1604 }
1605
1606 /// This is the most general way to print identifiers.
1607 /// AST pretty-printer is used as a fallback for turning AST structures into token streams for
1608 /// proc macros. Additionally, proc macros may stringify their input and expect it survive the
1609 /// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
1610 /// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
1611 /// hygiene data, most importantly name of the crate it refers to.
1612 /// As a result we print `$crate` as `crate` if it refers to the local crate
1613 /// and as `::other_crate_name` if it refers to some other crate.
1614 /// Note, that this is only done if the ident token is printed from inside of AST pretty-pringing,
1615 /// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
1616 /// so we should not perform this lossy conversion if the top level call to the pretty-printer was
1617 /// done for a token stream or a single token.
1618 pub struct IdentPrinter {
1619     symbol: Symbol,
1620     is_raw: bool,
1621     /// Span used for retrieving the crate name to which `$crate` refers to,
1622     /// if this field is `None` then the `$crate` conversion doesn't happen.
1623     convert_dollar_crate: Option<Span>,
1624 }
1625
1626 impl IdentPrinter {
1627     /// The most general `IdentPrinter` constructor. Do not use this.
1628     pub fn new(symbol: Symbol, is_raw: bool, convert_dollar_crate: Option<Span>) -> IdentPrinter {
1629         IdentPrinter { symbol, is_raw, convert_dollar_crate }
1630     }
1631
1632     /// This implementation is supposed to be used when printing identifiers
1633     /// as a part of pretty-printing for larger AST pieces.
1634     /// Do not use this either.
1635     pub fn for_ast_ident(ident: Ident, is_raw: bool) -> IdentPrinter {
1636         IdentPrinter::new(ident.name, is_raw, Some(ident.span))
1637     }
1638 }
1639
1640 impl fmt::Display for IdentPrinter {
1641     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1642         if self.is_raw {
1643             f.write_str("r#")?;
1644         } else if self.symbol == kw::DollarCrate {
1645             if let Some(span) = self.convert_dollar_crate {
1646                 let converted = span.ctxt().dollar_crate_name();
1647                 if !converted.is_path_segment_keyword() {
1648                     f.write_str("::")?;
1649                 }
1650                 return fmt::Display::fmt(&converted, f);
1651             }
1652         }
1653         fmt::Display::fmt(&self.symbol, f)
1654     }
1655 }
1656
1657 /// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
1658 /// construction.
1659 // FIXME(matthewj, petrochenkov) Use this more often, add a similar
1660 // `ModernIdent` struct and use that as well.
1661 #[derive(Copy, Clone, Eq, PartialEq, Hash)]
1662 pub struct MacroRulesNormalizedIdent(Ident);
1663
1664 impl MacroRulesNormalizedIdent {
1665     pub fn new(ident: Ident) -> Self {
1666         Self(ident.normalize_to_macro_rules())
1667     }
1668 }
1669
1670 impl fmt::Debug for MacroRulesNormalizedIdent {
1671     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1672         fmt::Debug::fmt(&self.0, f)
1673     }
1674 }
1675
1676 impl fmt::Display for MacroRulesNormalizedIdent {
1677     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1678         fmt::Display::fmt(&self.0, f)
1679     }
1680 }
1681
1682 /// An interned string.
1683 ///
1684 /// Internally, a `Symbol` is implemented as an index, and all operations
1685 /// (including hashing, equality, and ordering) operate on that index. The use
1686 /// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
1687 /// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
1688 ///
1689 /// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
1690 /// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
1691 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1692 pub struct Symbol(SymbolIndex);
1693
1694 rustc_index::newtype_index! {
1695     struct SymbolIndex { .. }
1696 }
1697
1698 impl Symbol {
1699     const fn new(n: u32) -> Self {
1700         Symbol(SymbolIndex::from_u32(n))
1701     }
1702
1703     /// Maps a string to its interned representation.
1704     pub fn intern(string: &str) -> Self {
1705         with_session_globals(|session_globals| session_globals.symbol_interner.intern(string))
1706     }
1707
1708     /// Access the underlying string. This is a slowish operation because it
1709     /// requires locking the symbol interner.
1710     ///
1711     /// Note that the lifetime of the return value is a lie. It's not the same
1712     /// as `&self`, but actually tied to the lifetime of the underlying
1713     /// interner. Interners are long-lived, and there are very few of them, and
1714     /// this function is typically used for short-lived things, so in practice
1715     /// it works out ok.
1716     pub fn as_str(&self) -> &str {
1717         with_session_globals(|session_globals| unsafe {
1718             std::mem::transmute::<&str, &str>(session_globals.symbol_interner.get(*self))
1719         })
1720     }
1721
1722     pub fn as_u32(self) -> u32 {
1723         self.0.as_u32()
1724     }
1725
1726     pub fn is_empty(self) -> bool {
1727         self == kw::Empty
1728     }
1729
1730     /// This method is supposed to be used in error messages, so it's expected to be
1731     /// identical to printing the original identifier token written in source code
1732     /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
1733     /// or edition, so we have to guess the rawness using the global edition.
1734     pub fn to_ident_string(self) -> String {
1735         Ident::with_dummy_span(self).to_string()
1736     }
1737 }
1738
1739 impl fmt::Debug for Symbol {
1740     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1741         fmt::Debug::fmt(self.as_str(), f)
1742     }
1743 }
1744
1745 impl fmt::Display for Symbol {
1746     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1747         fmt::Display::fmt(self.as_str(), f)
1748     }
1749 }
1750
1751 impl<S: Encoder> Encodable<S> for Symbol {
1752     fn encode(&self, s: &mut S) -> Result<(), S::Error> {
1753         s.emit_str(self.as_str())
1754     }
1755 }
1756
1757 impl<D: Decoder> Decodable<D> for Symbol {
1758     #[inline]
1759     fn decode(d: &mut D) -> Symbol {
1760         Symbol::intern(&d.read_str())
1761     }
1762 }
1763
1764 impl<CTX> HashStable<CTX> for Symbol {
1765     #[inline]
1766     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1767         self.as_str().hash_stable(hcx, hasher);
1768     }
1769 }
1770
1771 impl<CTX> ToStableHashKey<CTX> for Symbol {
1772     type KeyType = String;
1773     #[inline]
1774     fn to_stable_hash_key(&self, _: &CTX) -> String {
1775         self.as_str().to_string()
1776     }
1777 }
1778
1779 #[derive(Default)]
1780 pub(crate) struct Interner(Lock<InternerInner>);
1781
1782 // The `&'static str`s in this type actually point into the arena.
1783 //
1784 // The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
1785 // found that to regress performance up to 2% in some cases. This might be
1786 // revisited after further improvements to `indexmap`.
1787 //
1788 // This type is private to prevent accidentally constructing more than one
1789 // `Interner` on the same thread, which makes it easy to mixup `Symbol`s
1790 // between `Interner`s.
1791 #[derive(Default)]
1792 struct InternerInner {
1793     arena: DroplessArena,
1794     names: FxHashMap<&'static str, Symbol>,
1795     strings: Vec<&'static str>,
1796 }
1797
1798 impl Interner {
1799     fn prefill(init: &[&'static str]) -> Self {
1800         Interner(Lock::new(InternerInner {
1801             strings: init.into(),
1802             names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
1803             ..Default::default()
1804         }))
1805     }
1806
1807     #[inline]
1808     fn intern(&self, string: &str) -> Symbol {
1809         let mut inner = self.0.lock();
1810         if let Some(&name) = inner.names.get(string) {
1811             return name;
1812         }
1813
1814         let name = Symbol::new(inner.strings.len() as u32);
1815
1816         // SAFETY: we convert from `&str` to `&[u8]`, clone it into the arena,
1817         // and immediately convert the clone back to `&[u8], all because there
1818         // is no `inner.arena.alloc_str()` method. This is clearly safe.
1819         let string: &str =
1820             unsafe { str::from_utf8_unchecked(inner.arena.alloc_slice(string.as_bytes())) };
1821
1822         // SAFETY: we can extend the arena allocation to `'static` because we
1823         // only access these while the arena is still alive.
1824         let string: &'static str = unsafe { &*(string as *const str) };
1825         inner.strings.push(string);
1826
1827         // This second hash table lookup can be avoided by using `RawEntryMut`,
1828         // but this code path isn't hot enough for it to be worth it. See
1829         // #91445 for details.
1830         inner.names.insert(string, name);
1831         name
1832     }
1833
1834     // Get the symbol as a string. `Symbol::as_str()` should be used in
1835     // preference to this function.
1836     fn get(&self, symbol: Symbol) -> &str {
1837         self.0.lock().strings[symbol.0.as_usize()]
1838     }
1839 }
1840
1841 // This module has a very short name because it's used a lot.
1842 /// This module contains all the defined keyword `Symbol`s.
1843 ///
1844 /// Given that `kw` is imported, use them like `kw::keyword_name`.
1845 /// For example `kw::Loop` or `kw::Break`.
1846 pub mod kw {
1847     pub use super::kw_generated::*;
1848 }
1849
1850 // This module has a very short name because it's used a lot.
1851 /// This module contains all the defined non-keyword `Symbol`s.
1852 ///
1853 /// Given that `sym` is imported, use them like `sym::symbol_name`.
1854 /// For example `sym::rustfmt` or `sym::u8`.
1855 pub mod sym {
1856     use super::Symbol;
1857     use std::convert::TryInto;
1858
1859     #[doc(inline)]
1860     pub use super::sym_generated::*;
1861
1862     // Used from a macro in `librustc_feature/accepted.rs`
1863     pub use super::kw::MacroRules as macro_rules;
1864
1865     /// Get the symbol for an integer.
1866     ///
1867     /// The first few non-negative integers each have a static symbol and therefore
1868     /// are fast.
1869     pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
1870         if let Result::Ok(idx) = n.try_into() {
1871             if idx < 10 {
1872                 return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
1873             }
1874         }
1875         Symbol::intern(&n.to_string())
1876     }
1877 }
1878
1879 impl Symbol {
1880     fn is_special(self) -> bool {
1881         self <= kw::Underscore
1882     }
1883
1884     fn is_used_keyword_always(self) -> bool {
1885         self >= kw::As && self <= kw::While
1886     }
1887
1888     fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1889         (self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
1890     }
1891
1892     fn is_unused_keyword_always(self) -> bool {
1893         self >= kw::Abstract && self <= kw::Yield
1894     }
1895
1896     fn is_unused_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1897         self == kw::Try && edition() >= Edition::Edition2018
1898     }
1899
1900     pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
1901         self.is_special()
1902             || self.is_used_keyword_always()
1903             || self.is_unused_keyword_always()
1904             || self.is_used_keyword_conditional(edition)
1905             || self.is_unused_keyword_conditional(edition)
1906     }
1907
1908     /// A keyword or reserved identifier that can be used as a path segment.
1909     pub fn is_path_segment_keyword(self) -> bool {
1910         self == kw::Super
1911             || self == kw::SelfLower
1912             || self == kw::SelfUpper
1913             || self == kw::Crate
1914             || self == kw::PathRoot
1915             || self == kw::DollarCrate
1916     }
1917
1918     /// Returns `true` if the symbol is `true` or `false`.
1919     pub fn is_bool_lit(self) -> bool {
1920         self == kw::True || self == kw::False
1921     }
1922
1923     /// Returns `true` if this symbol can be a raw identifier.
1924     pub fn can_be_raw(self) -> bool {
1925         self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword()
1926     }
1927 }
1928
1929 impl Ident {
1930     // Returns `true` for reserved identifiers used internally for elided lifetimes,
1931     // unnamed method parameters, crate root module, error recovery etc.
1932     pub fn is_special(self) -> bool {
1933         self.name.is_special()
1934     }
1935
1936     /// Returns `true` if the token is a keyword used in the language.
1937     pub fn is_used_keyword(self) -> bool {
1938         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1939         self.name.is_used_keyword_always()
1940             || self.name.is_used_keyword_conditional(|| self.span.edition())
1941     }
1942
1943     /// Returns `true` if the token is a keyword reserved for possible future use.
1944     pub fn is_unused_keyword(self) -> bool {
1945         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1946         self.name.is_unused_keyword_always()
1947             || self.name.is_unused_keyword_conditional(|| self.span.edition())
1948     }
1949
1950     /// Returns `true` if the token is either a special identifier or a keyword.
1951     pub fn is_reserved(self) -> bool {
1952         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1953         self.name.is_reserved(|| self.span.edition())
1954     }
1955
1956     /// A keyword or reserved identifier that can be used as a path segment.
1957     pub fn is_path_segment_keyword(self) -> bool {
1958         self.name.is_path_segment_keyword()
1959     }
1960
1961     /// We see this identifier in a normal identifier position, like variable name or a type.
1962     /// How was it written originally? Did it use the raw form? Let's try to guess.
1963     pub fn is_raw_guess(self) -> bool {
1964         self.name.can_be_raw() && self.is_reserved()
1965     }
1966 }