]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_span/src/symbol.rs
Auto merge of #86988 - thomcc:chunky-splitz-says-no-checking, r=the8472
[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         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         with_negative_coherence,
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 }