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