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