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