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