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