]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_span/src/symbol.rs
Spellchecking compiler comments
[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         aarch64_ver_target_feature,
282         abi,
283         abi_amdgpu_kernel,
284         abi_avr_interrupt,
285         abi_c_cmse_nonsecure_call,
286         abi_efiapi,
287         abi_msp430_interrupt,
288         abi_ptx,
289         abi_sysv64,
290         abi_thiscall,
291         abi_unadjusted,
292         abi_vectorcall,
293         abi_x86_interrupt,
294         abort,
295         aborts,
296         add,
297         add_assign,
298         add_with_overflow,
299         address,
300         adt_const_params,
301         advanced_slice_patterns,
302         adx_target_feature,
303         alias,
304         align,
305         align_offset,
306         alignstack,
307         all,
308         alloc,
309         alloc_error_handler,
310         alloc_layout,
311         alloc_zeroed,
312         allocator,
313         allocator_api,
314         allocator_internals,
315         allow,
316         allow_fail,
317         allow_internal_unsafe,
318         allow_internal_unstable,
319         allowed,
320         alu32,
321         always,
322         and,
323         and_then,
324         any,
325         append_const_msg,
326         arbitrary_enum_discriminant,
327         arbitrary_self_types,
328         args,
329         arith_offset,
330         arm,
331         arm_target_feature,
332         array,
333         arrays,
334         as_ptr,
335         as_ref,
336         as_str,
337         asm,
338         asm_const,
339         asm_experimental_arch,
340         asm_sym,
341         asm_unwind,
342         assert,
343         assert_eq_macro,
344         assert_inhabited,
345         assert_macro,
346         assert_ne_macro,
347         assert_receiver_is_total_eq,
348         assert_uninit_valid,
349         assert_zero_valid,
350         associated_const_equality,
351         associated_consts,
352         associated_type_bounds,
353         associated_type_defaults,
354         associated_types,
355         assume,
356         assume_init,
357         async_await,
358         async_closure,
359         atomic,
360         atomic_mod,
361         atomics,
362         att_syntax,
363         attr,
364         attr_literals,
365         attributes,
366         augmented_assignments,
367         auto_traits,
368         automatically_derived,
369         avx,
370         avx512_target_feature,
371         avx512bw,
372         avx512f,
373         await_macro,
374         bang,
375         begin_panic,
376         bench,
377         bin,
378         bind_by_move_pattern_guards,
379         bindings_after_at,
380         bitand,
381         bitand_assign,
382         bitor,
383         bitor_assign,
384         bitreverse,
385         bitxor,
386         bitxor_assign,
387         black_box,
388         block,
389         bool,
390         borrowck_graphviz_format,
391         borrowck_graphviz_postflow,
392         borrowck_graphviz_preflow,
393         box_free,
394         box_patterns,
395         box_syntax,
396         bpf_target_feature,
397         braced_empty_structs,
398         branch,
399         breakpoint,
400         bridge,
401         bswap,
402         c_str,
403         c_unwind,
404         c_variadic,
405         call,
406         call_mut,
407         call_once,
408         caller_location,
409         capture_disjoint_fields,
410         cdylib,
411         ceilf32,
412         ceilf64,
413         cfg,
414         cfg_accessible,
415         cfg_attr,
416         cfg_attr_multi,
417         cfg_doctest,
418         cfg_eval,
419         cfg_hide,
420         cfg_macro,
421         cfg_panic,
422         cfg_sanitize,
423         cfg_target_abi,
424         cfg_target_feature,
425         cfg_target_has_atomic,
426         cfg_target_has_atomic_equal_alignment,
427         cfg_target_has_atomic_load_store,
428         cfg_target_thread_local,
429         cfg_target_vendor,
430         cfg_version,
431         cfi,
432         char,
433         client,
434         clippy,
435         clobber_abi,
436         clone,
437         clone_closures,
438         clone_from,
439         closure,
440         closure_to_fn_coercion,
441         closure_track_caller,
442         cmp,
443         cmp_max,
444         cmp_min,
445         cmpxchg16b_target_feature,
446         cmse_nonsecure_entry,
447         coerce_unsized,
448         cold,
449         column,
450         column_macro,
451         compare_and_swap,
452         compare_exchange,
453         compare_exchange_weak,
454         compile_error,
455         compile_error_macro,
456         compiler,
457         compiler_builtins,
458         compiler_fence,
459         concat,
460         concat_bytes,
461         concat_idents,
462         concat_macro,
463         conservative_impl_trait,
464         console,
465         const_allocate,
466         const_async_blocks,
467         const_compare_raw_pointers,
468         const_constructor,
469         const_deallocate,
470         const_eval_limit,
471         const_eval_select,
472         const_eval_select_ct,
473         const_evaluatable_checked,
474         const_extern_fn,
475         const_fn,
476         const_fn_floating_point_arithmetic,
477         const_fn_fn_ptr_basics,
478         const_fn_trait_bound,
479         const_fn_transmute,
480         const_fn_union,
481         const_fn_unsize,
482         const_for,
483         const_format_args,
484         const_generic_defaults,
485         const_generics,
486         const_generics_defaults,
487         const_if_match,
488         const_impl_trait,
489         const_in_array_repeat_expressions,
490         const_indexing,
491         const_let,
492         const_loop,
493         const_mut_refs,
494         const_panic,
495         const_panic_fmt,
496         const_precise_live_drops,
497         const_raw_ptr_deref,
498         const_raw_ptr_to_usize_cast,
499         const_refs_to_cell,
500         const_trait_bound_opt_out,
501         const_trait_impl,
502         const_transmute,
503         const_try,
504         constant,
505         constructor,
506         contents,
507         context,
508         convert,
509         copy,
510         copy_closures,
511         copy_nonoverlapping,
512         copysignf32,
513         copysignf64,
514         core,
515         core_intrinsics,
516         core_panic,
517         core_panic_2015_macro,
518         core_panic_macro,
519         cosf32,
520         cosf64,
521         count,
522         cr,
523         crate_id,
524         crate_in_paths,
525         crate_local,
526         crate_name,
527         crate_type,
528         crate_visibility_modifier,
529         crt_dash_static: "crt-static",
530         cstring_type,
531         ctlz,
532         ctlz_nonzero,
533         ctpop,
534         cttz,
535         cttz_nonzero,
536         custom_attribute,
537         custom_derive,
538         custom_inner_attributes,
539         custom_test_frameworks,
540         d,
541         d32,
542         dbg_macro,
543         dead_code,
544         dealloc,
545         debug,
546         debug_assert_eq_macro,
547         debug_assert_macro,
548         debug_assert_ne_macro,
549         debug_assertions,
550         debug_struct,
551         debug_trait_builder,
552         debug_tuple,
553         decl_macro,
554         declare_lint_pass,
555         decode,
556         default_alloc_error_handler,
557         default_lib_allocator,
558         default_method_body_is_const,
559         default_type_parameter_fallback,
560         default_type_params,
561         delay_span_bug_from_inside_query,
562         deny,
563         deprecated,
564         deprecated_safe,
565         deprecated_suggestion,
566         deref,
567         deref_method,
568         deref_mut,
569         deref_target,
570         derive,
571         derive_default_enum,
572         destruct,
573         destructuring_assignment,
574         diagnostic,
575         direct,
576         discriminant_kind,
577         discriminant_type,
578         discriminant_value,
579         dispatch_from_dyn,
580         display_trait,
581         div,
582         div_assign,
583         doc,
584         doc_alias,
585         doc_auto_cfg,
586         doc_cfg,
587         doc_cfg_hide,
588         doc_keyword,
589         doc_masked,
590         doc_notable_trait,
591         doc_primitive,
592         doc_spotlight,
593         doctest,
594         document_private_items,
595         dotdot: "..",
596         dotdot_in_tuple_patterns,
597         dotdoteq_in_patterns,
598         dreg,
599         dreg_low16,
600         dreg_low8,
601         drop,
602         drop_in_place,
603         drop_types_in_const,
604         dropck_eyepatch,
605         dropck_parametricity,
606         dylib,
607         dyn_metadata,
608         dyn_trait,
609         e,
610         edition_macro_pats,
611         edition_panic,
612         eh_catch_typeinfo,
613         eh_personality,
614         emit_enum,
615         emit_enum_variant,
616         emit_enum_variant_arg,
617         emit_struct,
618         emit_struct_field,
619         enable,
620         enclosing_scope,
621         encode,
622         end,
623         env,
624         env_macro,
625         eprint_macro,
626         eprintln_macro,
627         eq,
628         ermsb_target_feature,
629         exact_div,
630         except,
631         exchange_malloc,
632         exclusive_range_pattern,
633         exhaustive_integer_patterns,
634         exhaustive_patterns,
635         existential_type,
636         exp2f32,
637         exp2f64,
638         expect,
639         expected,
640         expf32,
641         expf64,
642         explicit_generic_args_with_impl_trait,
643         export_name,
644         expr,
645         extended_key_value_attributes,
646         extern_absolute_paths,
647         extern_crate_item_prelude,
648         extern_crate_self,
649         extern_in_paths,
650         extern_prelude,
651         extern_types,
652         external_doc,
653         f,
654         f16c_target_feature,
655         f32,
656         f64,
657         fabsf32,
658         fabsf64,
659         fadd_fast,
660         fdiv_fast,
661         feature,
662         fence,
663         ferris: "🦀",
664         fetch_update,
665         ffi,
666         ffi_const,
667         ffi_pure,
668         ffi_returns_twice,
669         field,
670         field_init_shorthand,
671         file,
672         file_macro,
673         fill,
674         finish,
675         flags,
676         float,
677         float_to_int_unchecked,
678         floorf32,
679         floorf64,
680         fmaf32,
681         fmaf64,
682         fmt,
683         fmt_as_str,
684         fmt_internals,
685         fmul_fast,
686         fn_align,
687         fn_must_use,
688         fn_mut,
689         fn_once,
690         fn_once_output,
691         forbid,
692         forget,
693         format,
694         format_args,
695         format_args_capture,
696         format_args_macro,
697         format_args_nl,
698         format_macro,
699         fp,
700         freeze,
701         freg,
702         frem_fast,
703         from,
704         from_desugaring,
705         from_generator,
706         from_iter,
707         from_method,
708         from_output,
709         from_residual,
710         from_size_align_unchecked,
711         from_usize,
712         fsub_fast,
713         fundamental,
714         future,
715         future_trait,
716         ge,
717         gen_future,
718         gen_kill,
719         generator,
720         generator_return,
721         generator_state,
722         generators,
723         generic_arg_infer,
724         generic_associated_types,
725         generic_const_exprs,
726         generic_param_attrs,
727         get_context,
728         global_allocator,
729         global_asm,
730         globs,
731         gt,
732         half_open_range_patterns,
733         hash,
734         hexagon_target_feature,
735         hidden,
736         homogeneous_aggregate,
737         html_favicon_url,
738         html_logo_url,
739         html_no_source,
740         html_playground_url,
741         html_root_url,
742         hwaddress,
743         i,
744         i128,
745         i128_type,
746         i16,
747         i32,
748         i64,
749         i8,
750         ident,
751         if_let,
752         if_let_guard,
753         if_while_or_patterns,
754         ignore,
755         impl_header_lifetime_elision,
756         impl_lint_pass,
757         impl_macros,
758         impl_trait_in_bindings,
759         import_shadowing,
760         imported_main,
761         in_band_lifetimes,
762         include,
763         include_bytes,
764         include_bytes_macro,
765         include_macro,
766         include_str,
767         include_str_macro,
768         inclusive_range_syntax,
769         index,
770         index_mut,
771         infer_outlives_requirements,
772         infer_static_outlives_requirements,
773         inherent_associated_types,
774         inlateout,
775         inline,
776         inline_const,
777         inline_const_pat,
778         inout,
779         instruction_set,
780         integer_: "integer",
781         integral,
782         intel,
783         into_future,
784         into_iter,
785         intra_doc_pointers,
786         intrinsics,
787         irrefutable_let_patterns,
788         isa_attribute,
789         isize,
790         issue,
791         issue_5723_bootstrap,
792         issue_tracker_base_url,
793         item,
794         item_like_imports,
795         iter,
796         iter_repeat,
797         keyword,
798         kind,
799         kreg,
800         label,
801         label_break_value,
802         lang,
803         lang_items,
804         large_assignments,
805         lateout,
806         lazy_normalization_consts,
807         le,
808         len,
809         let_chains,
810         let_else,
811         lhs,
812         lib,
813         libc,
814         lifetime,
815         likely,
816         line,
817         line_macro,
818         link,
819         link_args,
820         link_cfg,
821         link_llvm_intrinsics,
822         link_name,
823         link_ordinal,
824         link_section,
825         linkage,
826         linker,
827         lint_reasons,
828         literal,
829         load,
830         loaded_from_disk,
831         local,
832         local_inner_macros,
833         log10f32,
834         log10f64,
835         log2f32,
836         log2f64,
837         log_syntax,
838         logf32,
839         logf64,
840         loop_break_value,
841         lt,
842         macro_at_most_once_rep,
843         macro_attributes_in_derive_output,
844         macro_escape,
845         macro_export,
846         macro_lifetime_matcher,
847         macro_literal_matcher,
848         macro_metavar_expr,
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         naked,
913         naked_functions,
914         name,
915         names,
916         native_link_modifiers,
917         native_link_modifiers_as_needed,
918         native_link_modifiers_bundle,
919         native_link_modifiers_verbatim,
920         native_link_modifiers_whole_archive,
921         ne,
922         nearbyintf32,
923         nearbyintf64,
924         needs_allocator,
925         needs_drop,
926         needs_panic_runtime,
927         neg,
928         negate_unsigned,
929         negative_impls,
930         neon,
931         never,
932         never_type,
933         never_type_fallback,
934         new,
935         new_unchecked,
936         next,
937         nll,
938         no,
939         no_builtins,
940         no_core,
941         no_coverage,
942         no_crate_inject,
943         no_debug,
944         no_default_passes,
945         no_implicit_prelude,
946         no_inline,
947         no_link,
948         no_main,
949         no_mangle,
950         no_niche,
951         no_sanitize,
952         no_stack_check,
953         no_start,
954         no_std,
955         nomem,
956         non_ascii_idents,
957         non_exhaustive,
958         non_exhaustive_omitted_patterns_lint,
959         non_modrs_mods,
960         none_error,
961         nontemporal_store,
962         noop_method_borrow,
963         noop_method_clone,
964         noop_method_deref,
965         noreturn,
966         nostack,
967         not,
968         notable_trait,
969         note,
970         object_safe_for_dispatch,
971         of,
972         offset,
973         omit_gdb_pretty_printer_section,
974         on,
975         on_unimplemented,
976         oom,
977         opaque,
978         ops,
979         opt_out_copy,
980         optimize,
981         optimize_attribute,
982         optin_builtin_traits,
983         option,
984         option_env,
985         option_env_macro,
986         options,
987         or,
988         or_patterns,
989         other,
990         out,
991         overlapping_marker_traits,
992         owned_box,
993         packed,
994         panic,
995         panic_2015,
996         panic_2021,
997         panic_abort,
998         panic_bounds_check,
999         panic_display,
1000         panic_fmt,
1001         panic_handler,
1002         panic_impl,
1003         panic_implementation,
1004         panic_info,
1005         panic_location,
1006         panic_no_unwind,
1007         panic_runtime,
1008         panic_str,
1009         panic_unwind,
1010         panicking,
1011         param_attrs,
1012         partial_cmp,
1013         partial_ord,
1014         passes,
1015         pat,
1016         pat_param,
1017         path,
1018         pattern_parentheses,
1019         phantom_data,
1020         pin,
1021         pinned,
1022         platform_intrinsics,
1023         plugin,
1024         plugin_registrar,
1025         plugins,
1026         pointee_trait,
1027         pointer,
1028         pointer_trait_fmt,
1029         poll,
1030         position,
1031         post_dash_lto: "post-lto",
1032         powerpc_target_feature,
1033         powf32,
1034         powf64,
1035         powif32,
1036         powif64,
1037         pre_dash_lto: "pre-lto",
1038         precise_pointer_size_matching,
1039         precision,
1040         pref_align_of,
1041         prefetch_read_data,
1042         prefetch_read_instruction,
1043         prefetch_write_data,
1044         prefetch_write_instruction,
1045         preg,
1046         prelude,
1047         prelude_import,
1048         preserves_flags,
1049         primitive,
1050         print_macro,
1051         println_macro,
1052         proc_dash_macro: "proc-macro",
1053         proc_macro,
1054         proc_macro_attribute,
1055         proc_macro_def_site,
1056         proc_macro_derive,
1057         proc_macro_expr,
1058         proc_macro_gen,
1059         proc_macro_hygiene,
1060         proc_macro_internals,
1061         proc_macro_mod,
1062         proc_macro_non_items,
1063         proc_macro_path_invoc,
1064         profiler_builtins,
1065         profiler_runtime,
1066         ptr,
1067         ptr_guaranteed_eq,
1068         ptr_guaranteed_ne,
1069         ptr_null,
1070         ptr_null_mut,
1071         ptr_offset_from,
1072         pub_macro_rules,
1073         pub_restricted,
1074         pure,
1075         pushpop_unsafe,
1076         qreg,
1077         qreg_low4,
1078         qreg_low8,
1079         quad_precision_float,
1080         question_mark,
1081         quote,
1082         range_inclusive_new,
1083         raw_dylib,
1084         raw_eq,
1085         raw_identifiers,
1086         raw_ref_op,
1087         re_rebalance_coherence,
1088         read_enum,
1089         read_enum_variant,
1090         read_enum_variant_arg,
1091         read_struct,
1092         read_struct_field,
1093         readonly,
1094         realloc,
1095         reason,
1096         receiver,
1097         recursion_limit,
1098         reexport_test_harness_main,
1099         ref_unwind_safe_trait,
1100         reference,
1101         reflect,
1102         reg,
1103         reg16,
1104         reg32,
1105         reg64,
1106         reg_abcd,
1107         reg_byte,
1108         reg_iw,
1109         reg_nonzero,
1110         reg_pair,
1111         reg_ptr,
1112         reg_upper,
1113         register_attr,
1114         register_tool,
1115         relaxed_adts,
1116         relaxed_struct_unsize,
1117         rem,
1118         rem_assign,
1119         repr,
1120         repr128,
1121         repr_align,
1122         repr_align_enum,
1123         repr_no_niche,
1124         repr_packed,
1125         repr_simd,
1126         repr_transparent,
1127         residual,
1128         result,
1129         rhs,
1130         rintf32,
1131         rintf64,
1132         riscv_target_feature,
1133         rlib,
1134         rotate_left,
1135         rotate_right,
1136         roundf32,
1137         roundf64,
1138         rt,
1139         rtm_target_feature,
1140         rust,
1141         rust_2015,
1142         rust_2015_preview,
1143         rust_2018,
1144         rust_2018_preview,
1145         rust_2021,
1146         rust_2021_preview,
1147         rust_begin_unwind,
1148         rust_eh_catch_typeinfo,
1149         rust_eh_personality,
1150         rust_eh_register_frames,
1151         rust_eh_unregister_frames,
1152         rust_oom,
1153         rustc,
1154         rustc_allocator,
1155         rustc_allocator_nounwind,
1156         rustc_allow_const_fn_unstable,
1157         rustc_allow_incoherent_impl,
1158         rustc_attrs,
1159         rustc_builtin_macro,
1160         rustc_capture_analysis,
1161         rustc_clean,
1162         rustc_coherence_is_core,
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_len_fn,
1312         slice_patterns,
1313         slicing_syntax,
1314         soft,
1315         specialization,
1316         speed,
1317         spotlight,
1318         sqrtf32,
1319         sqrtf64,
1320         sreg,
1321         sreg_low16,
1322         sse,
1323         sse4a_target_feature,
1324         stable,
1325         staged_api,
1326         start,
1327         state,
1328         static_in_const,
1329         static_nobundle,
1330         static_recursion,
1331         staticlib,
1332         std,
1333         std_inject,
1334         std_panic,
1335         std_panic_2015_macro,
1336         std_panic_macro,
1337         stmt,
1338         stmt_expr_attributes,
1339         stop_after_dataflow,
1340         store,
1341         str,
1342         str_split_whitespace,
1343         str_trim,
1344         str_trim_end,
1345         str_trim_start,
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         test_unstable_lint,
1389         then_with,
1390         thread,
1391         thread_local,
1392         thread_local_macro,
1393         thumb2,
1394         thumb_mode: "thumb-mode",
1395         todo_macro,
1396         tool_attributes,
1397         tool_lints,
1398         trace_macros,
1399         track_caller,
1400         trait_alias,
1401         trait_upcasting,
1402         transmute,
1403         transparent,
1404         transparent_enums,
1405         transparent_unions,
1406         trivial_bounds,
1407         truncf32,
1408         truncf64,
1409         try_blocks,
1410         try_from,
1411         try_into,
1412         try_trait_v2,
1413         tt,
1414         tuple,
1415         tuple_from_req,
1416         tuple_indexing,
1417         two_phase,
1418         ty,
1419         type_alias_enum_variants,
1420         type_alias_impl_trait,
1421         type_ascription,
1422         type_changing_struct_update,
1423         type_id,
1424         type_length_limit,
1425         type_macros,
1426         type_name,
1427         u128,
1428         u16,
1429         u32,
1430         u64,
1431         u8,
1432         unaligned_volatile_load,
1433         unaligned_volatile_store,
1434         unboxed_closures,
1435         unchecked_add,
1436         unchecked_div,
1437         unchecked_mul,
1438         unchecked_rem,
1439         unchecked_shl,
1440         unchecked_shr,
1441         unchecked_sub,
1442         underscore_const_names,
1443         underscore_imports,
1444         underscore_lifetimes,
1445         uniform_paths,
1446         unimplemented_macro,
1447         unit,
1448         universal_impl_trait,
1449         unix,
1450         unlikely,
1451         unmarked_api,
1452         unpin,
1453         unreachable,
1454         unreachable_2015,
1455         unreachable_2015_macro,
1456         unreachable_2021,
1457         unreachable_2021_macro,
1458         unreachable_code,
1459         unreachable_display,
1460         unreachable_macro,
1461         unrestricted_attribute_tokens,
1462         unsafe_block_in_unsafe_fn,
1463         unsafe_cell,
1464         unsafe_no_drop_flag,
1465         unsafe_pin_internals,
1466         unsize,
1467         unsized_fn_params,
1468         unsized_locals,
1469         unsized_tuple_coercion,
1470         unstable,
1471         untagged_unions,
1472         unused_qualifications,
1473         unwind,
1474         unwind_attributes,
1475         unwind_safe_trait,
1476         unwrap,
1477         unwrap_or,
1478         use_extern_macros,
1479         use_nested_groups,
1480         used,
1481         used_with_arg,
1482         usize,
1483         v1,
1484         va_arg,
1485         va_copy,
1486         va_end,
1487         va_list,
1488         va_start,
1489         val,
1490         values,
1491         var,
1492         variant_count,
1493         vec,
1494         vec_macro,
1495         version,
1496         vfp2,
1497         vis,
1498         visible_private_types,
1499         volatile,
1500         volatile_copy_memory,
1501         volatile_copy_nonoverlapping_memory,
1502         volatile_load,
1503         volatile_set_memory,
1504         volatile_store,
1505         vreg,
1506         vreg_low16,
1507         warn,
1508         wasm_abi,
1509         wasm_import_module,
1510         wasm_target_feature,
1511         while_let,
1512         width,
1513         windows,
1514         windows_subsystem,
1515         with_negative_coherence,
1516         wrapping_add,
1517         wrapping_mul,
1518         wrapping_sub,
1519         wreg,
1520         write_bytes,
1521         write_macro,
1522         write_str,
1523         writeln_macro,
1524         x87_reg,
1525         xer,
1526         xmm_reg,
1527         ymm_reg,
1528         zmm_reg,
1529     }
1530 }
1531
1532 #[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
1533 pub struct Ident {
1534     pub name: Symbol,
1535     pub span: Span,
1536 }
1537
1538 impl Ident {
1539     #[inline]
1540     /// Constructs a new identifier from a symbol and a span.
1541     pub const fn new(name: Symbol, span: Span) -> Ident {
1542         Ident { name, span }
1543     }
1544
1545     /// Constructs a new identifier with a dummy span.
1546     #[inline]
1547     pub const fn with_dummy_span(name: Symbol) -> Ident {
1548         Ident::new(name, DUMMY_SP)
1549     }
1550
1551     #[inline]
1552     pub fn empty() -> Ident {
1553         Ident::with_dummy_span(kw::Empty)
1554     }
1555
1556     /// Maps a string to an identifier with a dummy span.
1557     pub fn from_str(string: &str) -> Ident {
1558         Ident::with_dummy_span(Symbol::intern(string))
1559     }
1560
1561     /// Maps a string and a span to an identifier.
1562     pub fn from_str_and_span(string: &str, span: Span) -> Ident {
1563         Ident::new(Symbol::intern(string), span)
1564     }
1565
1566     /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
1567     pub fn with_span_pos(self, span: Span) -> Ident {
1568         Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
1569     }
1570
1571     pub fn without_first_quote(self) -> Ident {
1572         Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
1573     }
1574
1575     /// "Normalize" ident for use in comparisons using "item hygiene".
1576     /// Identifiers with same string value become same if they came from the same macro 2.0 macro
1577     /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
1578     /// different macro 2.0 macros.
1579     /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
1580     pub fn normalize_to_macros_2_0(self) -> Ident {
1581         Ident::new(self.name, self.span.normalize_to_macros_2_0())
1582     }
1583
1584     /// "Normalize" ident for use in comparisons using "local variable hygiene".
1585     /// Identifiers with same string value become same if they came from the same non-transparent
1586     /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
1587     /// non-transparent macros.
1588     /// Technically, this operation strips all transparent marks from ident's syntactic context.
1589     pub fn normalize_to_macro_rules(self) -> Ident {
1590         Ident::new(self.name, self.span.normalize_to_macro_rules())
1591     }
1592
1593     /// Access the underlying string. This is a slowish operation because it
1594     /// requires locking the symbol interner.
1595     ///
1596     /// Note that the lifetime of the return value is a lie. See
1597     /// `Symbol::as_str()` for details.
1598     pub fn as_str(&self) -> &str {
1599         self.name.as_str()
1600     }
1601 }
1602
1603 impl PartialEq for Ident {
1604     fn eq(&self, rhs: &Self) -> bool {
1605         self.name == rhs.name && self.span.ctxt() == rhs.span.ctxt()
1606     }
1607 }
1608
1609 impl Hash for Ident {
1610     fn hash<H: Hasher>(&self, state: &mut H) {
1611         self.name.hash(state);
1612         self.span.ctxt().hash(state);
1613     }
1614 }
1615
1616 impl fmt::Debug for Ident {
1617     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1618         fmt::Display::fmt(self, f)?;
1619         fmt::Debug::fmt(&self.span.ctxt(), f)
1620     }
1621 }
1622
1623 /// This implementation is supposed to be used in error messages, so it's expected to be identical
1624 /// to printing the original identifier token written in source code (`token_to_string`),
1625 /// except that AST identifiers don't keep the rawness flag, so we have to guess it.
1626 impl fmt::Display for Ident {
1627     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1628         fmt::Display::fmt(&IdentPrinter::new(self.name, self.is_raw_guess(), None), f)
1629     }
1630 }
1631
1632 /// This is the most general way to print identifiers.
1633 /// AST pretty-printer is used as a fallback for turning AST structures into token streams for
1634 /// proc macros. Additionally, proc macros may stringify their input and expect it survive the
1635 /// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
1636 /// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
1637 /// hygiene data, most importantly name of the crate it refers to.
1638 /// As a result we print `$crate` as `crate` if it refers to the local crate
1639 /// and as `::other_crate_name` if it refers to some other crate.
1640 /// Note, that this is only done if the ident token is printed from inside of AST pretty-printing,
1641 /// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
1642 /// so we should not perform this lossy conversion if the top level call to the pretty-printer was
1643 /// done for a token stream or a single token.
1644 pub struct IdentPrinter {
1645     symbol: Symbol,
1646     is_raw: bool,
1647     /// Span used for retrieving the crate name to which `$crate` refers to,
1648     /// if this field is `None` then the `$crate` conversion doesn't happen.
1649     convert_dollar_crate: Option<Span>,
1650 }
1651
1652 impl IdentPrinter {
1653     /// The most general `IdentPrinter` constructor. Do not use this.
1654     pub fn new(symbol: Symbol, is_raw: bool, convert_dollar_crate: Option<Span>) -> IdentPrinter {
1655         IdentPrinter { symbol, is_raw, convert_dollar_crate }
1656     }
1657
1658     /// This implementation is supposed to be used when printing identifiers
1659     /// as a part of pretty-printing for larger AST pieces.
1660     /// Do not use this either.
1661     pub fn for_ast_ident(ident: Ident, is_raw: bool) -> IdentPrinter {
1662         IdentPrinter::new(ident.name, is_raw, Some(ident.span))
1663     }
1664 }
1665
1666 impl fmt::Display for IdentPrinter {
1667     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1668         if self.is_raw {
1669             f.write_str("r#")?;
1670         } else if self.symbol == kw::DollarCrate {
1671             if let Some(span) = self.convert_dollar_crate {
1672                 let converted = span.ctxt().dollar_crate_name();
1673                 if !converted.is_path_segment_keyword() {
1674                     f.write_str("::")?;
1675                 }
1676                 return fmt::Display::fmt(&converted, f);
1677             }
1678         }
1679         fmt::Display::fmt(&self.symbol, f)
1680     }
1681 }
1682
1683 /// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
1684 /// construction.
1685 // FIXME(matthewj, petrochenkov) Use this more often, add a similar
1686 // `ModernIdent` struct and use that as well.
1687 #[derive(Copy, Clone, Eq, PartialEq, Hash)]
1688 pub struct MacroRulesNormalizedIdent(Ident);
1689
1690 impl MacroRulesNormalizedIdent {
1691     pub fn new(ident: Ident) -> Self {
1692         Self(ident.normalize_to_macro_rules())
1693     }
1694 }
1695
1696 impl fmt::Debug for MacroRulesNormalizedIdent {
1697     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1698         fmt::Debug::fmt(&self.0, f)
1699     }
1700 }
1701
1702 impl fmt::Display for MacroRulesNormalizedIdent {
1703     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1704         fmt::Display::fmt(&self.0, f)
1705     }
1706 }
1707
1708 /// An interned string.
1709 ///
1710 /// Internally, a `Symbol` is implemented as an index, and all operations
1711 /// (including hashing, equality, and ordering) operate on that index. The use
1712 /// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
1713 /// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
1714 ///
1715 /// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
1716 /// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
1717 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1718 pub struct Symbol(SymbolIndex);
1719
1720 rustc_index::newtype_index! {
1721     struct SymbolIndex { .. }
1722 }
1723
1724 impl Symbol {
1725     const fn new(n: u32) -> Self {
1726         Symbol(SymbolIndex::from_u32(n))
1727     }
1728
1729     /// Maps a string to its interned representation.
1730     pub fn intern(string: &str) -> Self {
1731         with_session_globals(|session_globals| session_globals.symbol_interner.intern(string))
1732     }
1733
1734     /// Access the underlying string. This is a slowish operation because it
1735     /// requires locking the symbol interner.
1736     ///
1737     /// Note that the lifetime of the return value is a lie. It's not the same
1738     /// as `&self`, but actually tied to the lifetime of the underlying
1739     /// interner. Interners are long-lived, and there are very few of them, and
1740     /// this function is typically used for short-lived things, so in practice
1741     /// it works out ok.
1742     pub fn as_str(&self) -> &str {
1743         with_session_globals(|session_globals| unsafe {
1744             std::mem::transmute::<&str, &str>(session_globals.symbol_interner.get(*self))
1745         })
1746     }
1747
1748     pub fn as_u32(self) -> u32 {
1749         self.0.as_u32()
1750     }
1751
1752     pub fn is_empty(self) -> bool {
1753         self == kw::Empty
1754     }
1755
1756     /// This method is supposed to be used in error messages, so it's expected to be
1757     /// identical to printing the original identifier token written in source code
1758     /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
1759     /// or edition, so we have to guess the rawness using the global edition.
1760     pub fn to_ident_string(self) -> String {
1761         Ident::with_dummy_span(self).to_string()
1762     }
1763 }
1764
1765 impl fmt::Debug for Symbol {
1766     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1767         fmt::Debug::fmt(self.as_str(), f)
1768     }
1769 }
1770
1771 impl fmt::Display for Symbol {
1772     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1773         fmt::Display::fmt(self.as_str(), f)
1774     }
1775 }
1776
1777 impl<S: Encoder> Encodable<S> for Symbol {
1778     fn encode(&self, s: &mut S) -> Result<(), S::Error> {
1779         s.emit_str(self.as_str())
1780     }
1781 }
1782
1783 impl<D: Decoder> Decodable<D> for Symbol {
1784     #[inline]
1785     fn decode(d: &mut D) -> Symbol {
1786         Symbol::intern(&d.read_str())
1787     }
1788 }
1789
1790 impl<CTX> HashStable<CTX> for Symbol {
1791     #[inline]
1792     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1793         self.as_str().hash_stable(hcx, hasher);
1794     }
1795 }
1796
1797 impl<CTX> ToStableHashKey<CTX> for Symbol {
1798     type KeyType = String;
1799     #[inline]
1800     fn to_stable_hash_key(&self, _: &CTX) -> String {
1801         self.as_str().to_string()
1802     }
1803 }
1804
1805 #[derive(Default)]
1806 pub(crate) struct Interner(Lock<InternerInner>);
1807
1808 // The `&'static str`s in this type actually point into the arena.
1809 //
1810 // The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
1811 // found that to regress performance up to 2% in some cases. This might be
1812 // revisited after further improvements to `indexmap`.
1813 //
1814 // This type is private to prevent accidentally constructing more than one
1815 // `Interner` on the same thread, which makes it easy to mix up `Symbol`s
1816 // between `Interner`s.
1817 #[derive(Default)]
1818 struct InternerInner {
1819     arena: DroplessArena,
1820     names: FxHashMap<&'static str, Symbol>,
1821     strings: Vec<&'static str>,
1822 }
1823
1824 impl Interner {
1825     fn prefill(init: &[&'static str]) -> Self {
1826         Interner(Lock::new(InternerInner {
1827             strings: init.into(),
1828             names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
1829             ..Default::default()
1830         }))
1831     }
1832
1833     #[inline]
1834     fn intern(&self, string: &str) -> Symbol {
1835         let mut inner = self.0.lock();
1836         if let Some(&name) = inner.names.get(string) {
1837             return name;
1838         }
1839
1840         let name = Symbol::new(inner.strings.len() as u32);
1841
1842         // SAFETY: we convert from `&str` to `&[u8]`, clone it into the arena,
1843         // and immediately convert the clone back to `&[u8], all because there
1844         // is no `inner.arena.alloc_str()` method. This is clearly safe.
1845         let string: &str =
1846             unsafe { str::from_utf8_unchecked(inner.arena.alloc_slice(string.as_bytes())) };
1847
1848         // SAFETY: we can extend the arena allocation to `'static` because we
1849         // only access these while the arena is still alive.
1850         let string: &'static str = unsafe { &*(string as *const str) };
1851         inner.strings.push(string);
1852
1853         // This second hash table lookup can be avoided by using `RawEntryMut`,
1854         // but this code path isn't hot enough for it to be worth it. See
1855         // #91445 for details.
1856         inner.names.insert(string, name);
1857         name
1858     }
1859
1860     // Get the symbol as a string. `Symbol::as_str()` should be used in
1861     // preference to this function.
1862     fn get(&self, symbol: Symbol) -> &str {
1863         self.0.lock().strings[symbol.0.as_usize()]
1864     }
1865 }
1866
1867 // This module has a very short name because it's used a lot.
1868 /// This module contains all the defined keyword `Symbol`s.
1869 ///
1870 /// Given that `kw` is imported, use them like `kw::keyword_name`.
1871 /// For example `kw::Loop` or `kw::Break`.
1872 pub mod kw {
1873     pub use super::kw_generated::*;
1874 }
1875
1876 // This module has a very short name because it's used a lot.
1877 /// This module contains all the defined non-keyword `Symbol`s.
1878 ///
1879 /// Given that `sym` is imported, use them like `sym::symbol_name`.
1880 /// For example `sym::rustfmt` or `sym::u8`.
1881 pub mod sym {
1882     use super::Symbol;
1883     use std::convert::TryInto;
1884
1885     #[doc(inline)]
1886     pub use super::sym_generated::*;
1887
1888     // Used from a macro in `librustc_feature/accepted.rs`
1889     pub use super::kw::MacroRules as macro_rules;
1890
1891     /// Get the symbol for an integer.
1892     ///
1893     /// The first few non-negative integers each have a static symbol and therefore
1894     /// are fast.
1895     pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
1896         if let Result::Ok(idx) = n.try_into() {
1897             if idx < 10 {
1898                 return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
1899             }
1900         }
1901         Symbol::intern(&n.to_string())
1902     }
1903 }
1904
1905 impl Symbol {
1906     fn is_special(self) -> bool {
1907         self <= kw::Underscore
1908     }
1909
1910     fn is_used_keyword_always(self) -> bool {
1911         self >= kw::As && self <= kw::While
1912     }
1913
1914     fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1915         (self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
1916     }
1917
1918     fn is_unused_keyword_always(self) -> bool {
1919         self >= kw::Abstract && self <= kw::Yield
1920     }
1921
1922     fn is_unused_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1923         self == kw::Try && edition() >= Edition::Edition2018
1924     }
1925
1926     pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
1927         self.is_special()
1928             || self.is_used_keyword_always()
1929             || self.is_unused_keyword_always()
1930             || self.is_used_keyword_conditional(edition)
1931             || self.is_unused_keyword_conditional(edition)
1932     }
1933
1934     /// A keyword or reserved identifier that can be used as a path segment.
1935     pub fn is_path_segment_keyword(self) -> bool {
1936         self == kw::Super
1937             || self == kw::SelfLower
1938             || self == kw::SelfUpper
1939             || self == kw::Crate
1940             || self == kw::PathRoot
1941             || self == kw::DollarCrate
1942     }
1943
1944     /// Returns `true` if the symbol is `true` or `false`.
1945     pub fn is_bool_lit(self) -> bool {
1946         self == kw::True || self == kw::False
1947     }
1948
1949     /// Returns `true` if this symbol can be a raw identifier.
1950     pub fn can_be_raw(self) -> bool {
1951         self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword()
1952     }
1953 }
1954
1955 impl Ident {
1956     // Returns `true` for reserved identifiers used internally for elided lifetimes,
1957     // unnamed method parameters, crate root module, error recovery etc.
1958     pub fn is_special(self) -> bool {
1959         self.name.is_special()
1960     }
1961
1962     /// Returns `true` if the token is a keyword used in the language.
1963     pub fn is_used_keyword(self) -> bool {
1964         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1965         self.name.is_used_keyword_always()
1966             || self.name.is_used_keyword_conditional(|| self.span.edition())
1967     }
1968
1969     /// Returns `true` if the token is a keyword reserved for possible future use.
1970     pub fn is_unused_keyword(self) -> bool {
1971         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1972         self.name.is_unused_keyword_always()
1973             || self.name.is_unused_keyword_conditional(|| self.span.edition())
1974     }
1975
1976     /// Returns `true` if the token is either a special identifier or a keyword.
1977     pub fn is_reserved(self) -> bool {
1978         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1979         self.name.is_reserved(|| self.span.edition())
1980     }
1981
1982     /// A keyword or reserved identifier that can be used as a path segment.
1983     pub fn is_path_segment_keyword(self) -> bool {
1984         self.name.is_path_segment_keyword()
1985     }
1986
1987     /// We see this identifier in a normal identifier position, like variable name or a type.
1988     /// How was it written originally? Did it use the raw form? Let's try to guess.
1989     pub fn is_raw_guess(self) -> bool {
1990         self.name.can_be_raw() && self.is_reserved()
1991     }
1992 }