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