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