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