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