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