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