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