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