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