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