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