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