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