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