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