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