]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_span/src/symbol.rs
Rollup merge of #90575 - m-ou-se:compatible-variant-improvements, r=estebank
[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         __next,
273         __try_var,
274         _args,
275         _d,
276         _e,
277         _task_context,
278         a32,
279         aarch64_target_feature,
280         abi,
281         abi_amdgpu_kernel,
282         abi_avr_interrupt,
283         abi_c_cmse_nonsecure_call,
284         abi_efiapi,
285         abi_msp430_interrupt,
286         abi_ptx,
287         abi_sysv64,
288         abi_thiscall,
289         abi_unadjusted,
290         abi_vectorcall,
291         abi_x86_interrupt,
292         abort,
293         aborts,
294         add,
295         add_assign,
296         add_with_overflow,
297         address,
298         adt_const_params,
299         advanced_slice_patterns,
300         adx_target_feature,
301         alias,
302         align,
303         align_offset,
304         alignstack,
305         all,
306         alloc,
307         alloc_error_handler,
308         alloc_layout,
309         alloc_zeroed,
310         allocator,
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_state,
683         generators,
684         generic_arg_infer,
685         generic_associated_types,
686         generic_const_exprs,
687         generic_param_attrs,
688         get_context,
689         global_allocator,
690         global_asm,
691         globs,
692         gt,
693         half_open_range_patterns,
694         hash,
695         hexagon_target_feature,
696         hidden,
697         homogeneous_aggregate,
698         html_favicon_url,
699         html_logo_url,
700         html_no_source,
701         html_playground_url,
702         html_root_url,
703         hwaddress,
704         i,
705         i128,
706         i128_type,
707         i16,
708         i32,
709         i64,
710         i8,
711         ident,
712         if_let,
713         if_let_guard,
714         if_while_or_patterns,
715         ignore,
716         impl_header_lifetime_elision,
717         impl_lint_pass,
718         impl_macros,
719         impl_trait_in_bindings,
720         import_shadowing,
721         imported_main,
722         in_band_lifetimes,
723         include,
724         include_bytes,
725         include_str,
726         inclusive_range_syntax,
727         index,
728         index_mut,
729         infer_outlives_requirements,
730         infer_static_outlives_requirements,
731         inherent_associated_types,
732         inlateout,
733         inline,
734         inline_const,
735         inout,
736         instruction_set,
737         intel,
738         into_iter,
739         intra_doc_pointers,
740         intrinsics,
741         irrefutable_let_patterns,
742         isa_attribute,
743         isize,
744         issue,
745         issue_5723_bootstrap,
746         issue_tracker_base_url,
747         item,
748         item_like_imports,
749         iter,
750         iter_repeat,
751         keyword,
752         kind,
753         kreg,
754         label,
755         label_break_value,
756         lang,
757         lang_items,
758         large_assignments,
759         lateout,
760         lazy_normalization_consts,
761         le,
762         len,
763         let_chains,
764         let_else,
765         lhs,
766         lib,
767         libc,
768         lifetime,
769         likely,
770         line,
771         link,
772         link_args,
773         link_cfg,
774         link_llvm_intrinsics,
775         link_name,
776         link_ordinal,
777         link_section,
778         linkage,
779         lint_reasons,
780         literal,
781         llvm_asm,
782         load,
783         local,
784         local_inner_macros,
785         log10f32,
786         log10f64,
787         log2f32,
788         log2f64,
789         log_syntax,
790         logf32,
791         logf64,
792         loop_break_value,
793         lt,
794         macro_at_most_once_rep,
795         macro_attributes_in_derive_output,
796         macro_escape,
797         macro_export,
798         macro_lifetime_matcher,
799         macro_literal_matcher,
800         macro_reexport,
801         macro_use,
802         macro_vis_matcher,
803         macros_in_extern,
804         main,
805         managed_boxes,
806         manually_drop,
807         map,
808         marker,
809         marker_trait_attr,
810         masked,
811         match_beginning_vert,
812         match_default_bindings,
813         maxnumf32,
814         maxnumf64,
815         may_dangle,
816         maybe_uninit,
817         maybe_uninit_uninit,
818         maybe_uninit_zeroed,
819         mem_discriminant,
820         mem_drop,
821         mem_forget,
822         mem_replace,
823         mem_size_of,
824         mem_size_of_val,
825         mem_uninitialized,
826         mem_variant_count,
827         mem_zeroed,
828         member_constraints,
829         memory,
830         message,
831         meta,
832         metadata_type,
833         min_align_of,
834         min_align_of_val,
835         min_const_fn,
836         min_const_generics,
837         min_const_unsafe_fn,
838         min_specialization,
839         min_type_alias_impl_trait,
840         minnumf32,
841         minnumf64,
842         mips_target_feature,
843         misc,
844         mmx_reg,
845         modifiers,
846         module,
847         module_path,
848         more_qualified_paths,
849         more_struct_aliases,
850         movbe_target_feature,
851         move_ref_pattern,
852         move_size_limit,
853         mul,
854         mul_assign,
855         mul_with_overflow,
856         must_not_suspend,
857         must_use,
858         mut_ptr,
859         mut_slice_ptr,
860         naked,
861         naked_functions,
862         name,
863         native_link_modifiers,
864         native_link_modifiers_as_needed,
865         native_link_modifiers_bundle,
866         native_link_modifiers_verbatim,
867         native_link_modifiers_whole_archive,
868         ne,
869         nearbyintf32,
870         nearbyintf64,
871         needs_allocator,
872         needs_drop,
873         needs_panic_runtime,
874         neg,
875         negate_unsigned,
876         negative_impls,
877         never,
878         never_type,
879         never_type_fallback,
880         new,
881         new_unchecked,
882         next,
883         nll,
884         no,
885         no_builtins,
886         no_core,
887         no_coverage,
888         no_crate_inject,
889         no_debug,
890         no_default_passes,
891         no_implicit_prelude,
892         no_inline,
893         no_link,
894         no_main,
895         no_mangle,
896         no_niche,
897         no_sanitize,
898         no_stack_check,
899         no_start,
900         no_std,
901         nomem,
902         non_ascii_idents,
903         non_exhaustive,
904         non_exhaustive_omitted_patterns_lint,
905         non_modrs_mods,
906         none_error,
907         nontemporal_store,
908         noop_method_borrow,
909         noop_method_clone,
910         noop_method_deref,
911         noreturn,
912         nostack,
913         not,
914         notable_trait,
915         note,
916         object_safe_for_dispatch,
917         of,
918         offset,
919         omit_gdb_pretty_printer_section,
920         on,
921         on_unimplemented,
922         oom,
923         opaque,
924         ops,
925         opt_out_copy,
926         optimize,
927         optimize_attribute,
928         optin_builtin_traits,
929         option,
930         option_env,
931         options,
932         or,
933         or_patterns,
934         other,
935         out,
936         overlapping_marker_traits,
937         owned_box,
938         packed,
939         panic,
940         panic_2015,
941         panic_2021,
942         panic_abort,
943         panic_bounds_check,
944         panic_display,
945         panic_fmt,
946         panic_handler,
947         panic_impl,
948         panic_implementation,
949         panic_info,
950         panic_location,
951         panic_runtime,
952         panic_str,
953         panic_unwind,
954         panicking,
955         param_attrs,
956         partial_cmp,
957         partial_ord,
958         passes,
959         pat,
960         pat_param,
961         path,
962         pattern_parentheses,
963         phantom_data,
964         pin,
965         pinned,
966         platform_intrinsics,
967         plugin,
968         plugin_registrar,
969         plugins,
970         pointee_trait,
971         pointer,
972         pointer_trait_fmt,
973         poll,
974         position,
975         post_dash_lto: "post-lto",
976         powerpc_target_feature,
977         powf32,
978         powf64,
979         powif32,
980         powif64,
981         pre_dash_lto: "pre-lto",
982         precise_pointer_size_matching,
983         precision,
984         pref_align_of,
985         prefetch_read_data,
986         prefetch_read_instruction,
987         prefetch_write_data,
988         prefetch_write_instruction,
989         preg,
990         prelude,
991         prelude_import,
992         preserves_flags,
993         primitive,
994         proc_dash_macro: "proc-macro",
995         proc_macro,
996         proc_macro_attribute,
997         proc_macro_def_site,
998         proc_macro_derive,
999         proc_macro_expr,
1000         proc_macro_gen,
1001         proc_macro_hygiene,
1002         proc_macro_internals,
1003         proc_macro_mod,
1004         proc_macro_non_items,
1005         proc_macro_path_invoc,
1006         profiler_builtins,
1007         profiler_runtime,
1008         ptr_guaranteed_eq,
1009         ptr_guaranteed_ne,
1010         ptr_null,
1011         ptr_null_mut,
1012         ptr_offset_from,
1013         pub_macro_rules,
1014         pub_restricted,
1015         pure,
1016         pushpop_unsafe,
1017         qreg,
1018         qreg_low4,
1019         qreg_low8,
1020         quad_precision_float,
1021         question_mark,
1022         quote,
1023         range_inclusive_new,
1024         raw_dylib,
1025         raw_eq,
1026         raw_identifiers,
1027         raw_ref_op,
1028         re_rebalance_coherence,
1029         read_enum,
1030         read_enum_variant,
1031         read_enum_variant_arg,
1032         read_struct,
1033         read_struct_field,
1034         readonly,
1035         realloc,
1036         reason,
1037         receiver,
1038         recursion_limit,
1039         reexport_test_harness_main,
1040         ref_unwind_safe_trait,
1041         reference,
1042         reflect,
1043         reg,
1044         reg16,
1045         reg32,
1046         reg64,
1047         reg_abcd,
1048         reg_byte,
1049         reg_nonzero,
1050         reg_thumb,
1051         register_attr,
1052         register_tool,
1053         relaxed_adts,
1054         relaxed_struct_unsize,
1055         rem,
1056         rem_assign,
1057         repr,
1058         repr128,
1059         repr_align,
1060         repr_align_enum,
1061         repr_no_niche,
1062         repr_packed,
1063         repr_simd,
1064         repr_transparent,
1065         residual,
1066         result,
1067         rhs,
1068         rintf32,
1069         rintf64,
1070         riscv_target_feature,
1071         rlib,
1072         rotate_left,
1073         rotate_right,
1074         roundf32,
1075         roundf64,
1076         rt,
1077         rtm_target_feature,
1078         rust,
1079         rust_2015,
1080         rust_2015_preview,
1081         rust_2018,
1082         rust_2018_preview,
1083         rust_2021,
1084         rust_2021_preview,
1085         rust_begin_unwind,
1086         rust_eh_catch_typeinfo,
1087         rust_eh_personality,
1088         rust_eh_register_frames,
1089         rust_eh_unregister_frames,
1090         rust_oom,
1091         rustc,
1092         rustc_allocator,
1093         rustc_allocator_nounwind,
1094         rustc_allow_const_fn_unstable,
1095         rustc_attrs,
1096         rustc_builtin_macro,
1097         rustc_capture_analysis,
1098         rustc_clean,
1099         rustc_const_stable,
1100         rustc_const_unstable,
1101         rustc_conversion_suggestion,
1102         rustc_def_path,
1103         rustc_deprecated,
1104         rustc_diagnostic_item,
1105         rustc_diagnostic_macros,
1106         rustc_dirty,
1107         rustc_do_not_const_check,
1108         rustc_dummy,
1109         rustc_dump_env_program_clauses,
1110         rustc_dump_program_clauses,
1111         rustc_dump_user_substs,
1112         rustc_dump_vtable,
1113         rustc_error,
1114         rustc_evaluate_where_clauses,
1115         rustc_expected_cgu_reuse,
1116         rustc_if_this_changed,
1117         rustc_inherit_overflow_checks,
1118         rustc_insignificant_dtor,
1119         rustc_layout,
1120         rustc_layout_scalar_valid_range_end,
1121         rustc_layout_scalar_valid_range_start,
1122         rustc_legacy_const_generics,
1123         rustc_macro_transparency,
1124         rustc_main,
1125         rustc_mir,
1126         rustc_nonnull_optimization_guaranteed,
1127         rustc_object_lifetime_default,
1128         rustc_on_unimplemented,
1129         rustc_outlives,
1130         rustc_paren_sugar,
1131         rustc_partition_codegened,
1132         rustc_partition_reused,
1133         rustc_peek,
1134         rustc_peek_definite_init,
1135         rustc_peek_liveness,
1136         rustc_peek_maybe_init,
1137         rustc_peek_maybe_uninit,
1138         rustc_polymorphize_error,
1139         rustc_private,
1140         rustc_proc_macro_decls,
1141         rustc_promotable,
1142         rustc_regions,
1143         rustc_reservation_impl,
1144         rustc_serialize,
1145         rustc_skip_array_during_method_dispatch,
1146         rustc_specialization_trait,
1147         rustc_stable,
1148         rustc_std_internal_symbol,
1149         rustc_strict_coherence,
1150         rustc_symbol_name,
1151         rustc_test_marker,
1152         rustc_then_this_would_need,
1153         rustc_trivial_field_reads,
1154         rustc_unsafe_specialization_marker,
1155         rustc_variance,
1156         rustdoc,
1157         rustfmt,
1158         rvalue_static_promotion,
1159         s,
1160         sanitize,
1161         sanitizer_runtime,
1162         saturating_add,
1163         saturating_sub,
1164         self_in_typedefs,
1165         self_struct_ctor,
1166         semitransparent,
1167         shl,
1168         shl_assign,
1169         should_panic,
1170         shr,
1171         shr_assign,
1172         simd,
1173         simd_add,
1174         simd_and,
1175         simd_bitmask,
1176         simd_cast,
1177         simd_ceil,
1178         simd_div,
1179         simd_eq,
1180         simd_extract,
1181         simd_fabs,
1182         simd_fcos,
1183         simd_fexp,
1184         simd_fexp2,
1185         simd_ffi,
1186         simd_flog,
1187         simd_flog10,
1188         simd_flog2,
1189         simd_floor,
1190         simd_fma,
1191         simd_fmax,
1192         simd_fmin,
1193         simd_fpow,
1194         simd_fpowi,
1195         simd_fsin,
1196         simd_fsqrt,
1197         simd_gather,
1198         simd_ge,
1199         simd_gt,
1200         simd_insert,
1201         simd_le,
1202         simd_lt,
1203         simd_mul,
1204         simd_ne,
1205         simd_neg,
1206         simd_or,
1207         simd_reduce_add_ordered,
1208         simd_reduce_add_unordered,
1209         simd_reduce_all,
1210         simd_reduce_and,
1211         simd_reduce_any,
1212         simd_reduce_max,
1213         simd_reduce_max_nanless,
1214         simd_reduce_min,
1215         simd_reduce_min_nanless,
1216         simd_reduce_mul_ordered,
1217         simd_reduce_mul_unordered,
1218         simd_reduce_or,
1219         simd_reduce_xor,
1220         simd_rem,
1221         simd_round,
1222         simd_saturating_add,
1223         simd_saturating_sub,
1224         simd_scatter,
1225         simd_select,
1226         simd_select_bitmask,
1227         simd_shl,
1228         simd_shr,
1229         simd_shuffle,
1230         simd_sub,
1231         simd_trunc,
1232         simd_xor,
1233         since,
1234         sinf32,
1235         sinf64,
1236         size,
1237         size_of,
1238         size_of_val,
1239         sized,
1240         skip,
1241         slice,
1242         slice_alloc,
1243         slice_len_fn,
1244         slice_patterns,
1245         slice_u8,
1246         slice_u8_alloc,
1247         slicing_syntax,
1248         soft,
1249         specialization,
1250         speed,
1251         spotlight,
1252         sqrtf32,
1253         sqrtf64,
1254         sreg,
1255         sreg_low16,
1256         sse4a_target_feature,
1257         stable,
1258         staged_api,
1259         start,
1260         state,
1261         static_in_const,
1262         static_nobundle,
1263         static_recursion,
1264         staticlib,
1265         std,
1266         std_inject,
1267         std_panic,
1268         std_panic_2015_macro,
1269         std_panic_macro,
1270         stmt,
1271         stmt_expr_attributes,
1272         stop_after_dataflow,
1273         store,
1274         str,
1275         str_alloc,
1276         stringify,
1277         struct_field_attributes,
1278         struct_inherit,
1279         struct_variant,
1280         structural_match,
1281         structural_peq,
1282         structural_teq,
1283         sty,
1284         sub,
1285         sub_assign,
1286         sub_with_overflow,
1287         suggestion,
1288         sym,
1289         sync,
1290         t32,
1291         target_abi,
1292         target_arch,
1293         target_endian,
1294         target_env,
1295         target_family,
1296         target_feature,
1297         target_feature_11,
1298         target_has_atomic,
1299         target_has_atomic_equal_alignment,
1300         target_has_atomic_load_store,
1301         target_os,
1302         target_pointer_width,
1303         target_target_vendor,
1304         target_thread_local,
1305         target_vendor,
1306         task,
1307         tbm_target_feature,
1308         termination,
1309         termination_trait,
1310         termination_trait_test,
1311         test,
1312         test_2018_feature,
1313         test_accepted_feature,
1314         test_case,
1315         test_removed_feature,
1316         test_runner,
1317         then_with,
1318         thread,
1319         thread_local,
1320         tool_attributes,
1321         tool_lints,
1322         trace_macros,
1323         track_caller,
1324         trait_alias,
1325         trait_upcasting,
1326         transmute,
1327         transparent,
1328         transparent_enums,
1329         transparent_unions,
1330         trivial_bounds,
1331         truncf32,
1332         truncf64,
1333         try_blocks,
1334         try_from,
1335         try_into,
1336         try_trait_v2,
1337         tt,
1338         tuple,
1339         tuple_from_req,
1340         tuple_indexing,
1341         two_phase,
1342         ty,
1343         type_alias_enum_variants,
1344         type_alias_impl_trait,
1345         type_ascription,
1346         type_changing_struct_update,
1347         type_id,
1348         type_length_limit,
1349         type_macros,
1350         type_name,
1351         u128,
1352         u16,
1353         u32,
1354         u64,
1355         u8,
1356         unaligned_volatile_load,
1357         unaligned_volatile_store,
1358         unboxed_closures,
1359         unchecked_add,
1360         unchecked_div,
1361         unchecked_mul,
1362         unchecked_rem,
1363         unchecked_shl,
1364         unchecked_shr,
1365         unchecked_sub,
1366         underscore_const_names,
1367         underscore_imports,
1368         underscore_lifetimes,
1369         uniform_paths,
1370         unit,
1371         universal_impl_trait,
1372         unix,
1373         unlikely,
1374         unmarked_api,
1375         unpin,
1376         unreachable,
1377         unreachable_code,
1378         unrestricted_attribute_tokens,
1379         unsafe_block_in_unsafe_fn,
1380         unsafe_cell,
1381         unsafe_no_drop_flag,
1382         unsize,
1383         unsized_fn_params,
1384         unsized_locals,
1385         unsized_tuple_coercion,
1386         unstable,
1387         untagged_unions,
1388         unused_qualifications,
1389         unwind,
1390         unwind_attributes,
1391         unwind_safe_trait,
1392         unwrap,
1393         unwrap_or,
1394         use_extern_macros,
1395         use_nested_groups,
1396         used,
1397         usize,
1398         v1,
1399         va_arg,
1400         va_copy,
1401         va_end,
1402         va_list,
1403         va_start,
1404         val,
1405         var,
1406         variant_count,
1407         vec,
1408         version,
1409         vis,
1410         visible_private_types,
1411         volatile,
1412         volatile_copy_memory,
1413         volatile_copy_nonoverlapping_memory,
1414         volatile_load,
1415         volatile_set_memory,
1416         volatile_store,
1417         vreg,
1418         vreg_low16,
1419         warn,
1420         wasm_abi,
1421         wasm_import_module,
1422         wasm_target_feature,
1423         while_let,
1424         width,
1425         windows,
1426         windows_subsystem,
1427         wrapping_add,
1428         wrapping_mul,
1429         wrapping_sub,
1430         wreg,
1431         write_bytes,
1432         write_str,
1433         x87_reg,
1434         xer,
1435         xmm_reg,
1436         ymm_reg,
1437         zmm_reg,
1438     }
1439 }
1440
1441 #[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
1442 pub struct Ident {
1443     pub name: Symbol,
1444     pub span: Span,
1445 }
1446
1447 impl Ident {
1448     #[inline]
1449     /// Constructs a new identifier from a symbol and a span.
1450     pub const fn new(name: Symbol, span: Span) -> Ident {
1451         Ident { name, span }
1452     }
1453
1454     /// Constructs a new identifier with a dummy span.
1455     #[inline]
1456     pub const fn with_dummy_span(name: Symbol) -> Ident {
1457         Ident::new(name, DUMMY_SP)
1458     }
1459
1460     #[inline]
1461     pub fn empty() -> Ident {
1462         Ident::with_dummy_span(kw::Empty)
1463     }
1464
1465     /// Maps a string to an identifier with a dummy span.
1466     pub fn from_str(string: &str) -> Ident {
1467         Ident::with_dummy_span(Symbol::intern(string))
1468     }
1469
1470     /// Maps a string and a span to an identifier.
1471     pub fn from_str_and_span(string: &str, span: Span) -> Ident {
1472         Ident::new(Symbol::intern(string), span)
1473     }
1474
1475     /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
1476     pub fn with_span_pos(self, span: Span) -> Ident {
1477         Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
1478     }
1479
1480     pub fn without_first_quote(self) -> Ident {
1481         Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
1482     }
1483
1484     /// "Normalize" ident for use in comparisons using "item hygiene".
1485     /// Identifiers with same string value become same if they came from the same macro 2.0 macro
1486     /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
1487     /// different macro 2.0 macros.
1488     /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
1489     pub fn normalize_to_macros_2_0(self) -> Ident {
1490         Ident::new(self.name, self.span.normalize_to_macros_2_0())
1491     }
1492
1493     /// "Normalize" ident for use in comparisons using "local variable hygiene".
1494     /// Identifiers with same string value become same if they came from the same non-transparent
1495     /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
1496     /// non-transparent macros.
1497     /// Technically, this operation strips all transparent marks from ident's syntactic context.
1498     pub fn normalize_to_macro_rules(self) -> Ident {
1499         Ident::new(self.name, self.span.normalize_to_macro_rules())
1500     }
1501
1502     /// Convert the name to a `SymbolStr`. This is a slowish operation because
1503     /// it requires locking the symbol interner.
1504     pub fn as_str(self) -> SymbolStr {
1505         self.name.as_str()
1506     }
1507 }
1508
1509 impl PartialEq for Ident {
1510     fn eq(&self, rhs: &Self) -> bool {
1511         self.name == rhs.name && self.span.ctxt() == rhs.span.ctxt()
1512     }
1513 }
1514
1515 impl Hash for Ident {
1516     fn hash<H: Hasher>(&self, state: &mut H) {
1517         self.name.hash(state);
1518         self.span.ctxt().hash(state);
1519     }
1520 }
1521
1522 impl fmt::Debug for Ident {
1523     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1524         fmt::Display::fmt(self, f)?;
1525         fmt::Debug::fmt(&self.span.ctxt(), f)
1526     }
1527 }
1528
1529 /// This implementation is supposed to be used in error messages, so it's expected to be identical
1530 /// to printing the original identifier token written in source code (`token_to_string`),
1531 /// except that AST identifiers don't keep the rawness flag, so we have to guess it.
1532 impl fmt::Display for Ident {
1533     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1534         fmt::Display::fmt(&IdentPrinter::new(self.name, self.is_raw_guess(), None), f)
1535     }
1536 }
1537
1538 /// This is the most general way to print identifiers.
1539 /// AST pretty-printer is used as a fallback for turning AST structures into token streams for
1540 /// proc macros. Additionally, proc macros may stringify their input and expect it survive the
1541 /// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
1542 /// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
1543 /// hygiene data, most importantly name of the crate it refers to.
1544 /// As a result we print `$crate` as `crate` if it refers to the local crate
1545 /// and as `::other_crate_name` if it refers to some other crate.
1546 /// Note, that this is only done if the ident token is printed from inside of AST pretty-pringing,
1547 /// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
1548 /// so we should not perform this lossy conversion if the top level call to the pretty-printer was
1549 /// done for a token stream or a single token.
1550 pub struct IdentPrinter {
1551     symbol: Symbol,
1552     is_raw: bool,
1553     /// Span used for retrieving the crate name to which `$crate` refers to,
1554     /// if this field is `None` then the `$crate` conversion doesn't happen.
1555     convert_dollar_crate: Option<Span>,
1556 }
1557
1558 impl IdentPrinter {
1559     /// The most general `IdentPrinter` constructor. Do not use this.
1560     pub fn new(symbol: Symbol, is_raw: bool, convert_dollar_crate: Option<Span>) -> IdentPrinter {
1561         IdentPrinter { symbol, is_raw, convert_dollar_crate }
1562     }
1563
1564     /// This implementation is supposed to be used when printing identifiers
1565     /// as a part of pretty-printing for larger AST pieces.
1566     /// Do not use this either.
1567     pub fn for_ast_ident(ident: Ident, is_raw: bool) -> IdentPrinter {
1568         IdentPrinter::new(ident.name, is_raw, Some(ident.span))
1569     }
1570 }
1571
1572 impl fmt::Display for IdentPrinter {
1573     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1574         if self.is_raw {
1575             f.write_str("r#")?;
1576         } else if self.symbol == kw::DollarCrate {
1577             if let Some(span) = self.convert_dollar_crate {
1578                 let converted = span.ctxt().dollar_crate_name();
1579                 if !converted.is_path_segment_keyword() {
1580                     f.write_str("::")?;
1581                 }
1582                 return fmt::Display::fmt(&converted, f);
1583             }
1584         }
1585         fmt::Display::fmt(&self.symbol, f)
1586     }
1587 }
1588
1589 /// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
1590 /// construction.
1591 // FIXME(matthewj, petrochenkov) Use this more often, add a similar
1592 // `ModernIdent` struct and use that as well.
1593 #[derive(Copy, Clone, Eq, PartialEq, Hash)]
1594 pub struct MacroRulesNormalizedIdent(Ident);
1595
1596 impl MacroRulesNormalizedIdent {
1597     pub fn new(ident: Ident) -> Self {
1598         Self(ident.normalize_to_macro_rules())
1599     }
1600 }
1601
1602 impl fmt::Debug for MacroRulesNormalizedIdent {
1603     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1604         fmt::Debug::fmt(&self.0, f)
1605     }
1606 }
1607
1608 impl fmt::Display for MacroRulesNormalizedIdent {
1609     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1610         fmt::Display::fmt(&self.0, f)
1611     }
1612 }
1613
1614 /// An interned string.
1615 ///
1616 /// Internally, a `Symbol` is implemented as an index, and all operations
1617 /// (including hashing, equality, and ordering) operate on that index. The use
1618 /// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
1619 /// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
1620 ///
1621 /// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
1622 /// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
1623 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1624 pub struct Symbol(SymbolIndex);
1625
1626 rustc_index::newtype_index! {
1627     struct SymbolIndex { .. }
1628 }
1629
1630 impl Symbol {
1631     const fn new(n: u32) -> Self {
1632         Symbol(SymbolIndex::from_u32(n))
1633     }
1634
1635     /// Maps a string to its interned representation.
1636     pub fn intern(string: &str) -> Self {
1637         with_session_globals(|session_globals| session_globals.symbol_interner.intern(string))
1638     }
1639
1640     /// Convert to a `SymbolStr`. This is a slowish operation because it
1641     /// requires locking the symbol interner.
1642     pub fn as_str(self) -> SymbolStr {
1643         with_session_globals(|session_globals| {
1644             let symbol_str = session_globals.symbol_interner.get(self);
1645             unsafe { SymbolStr { string: std::mem::transmute::<&str, &str>(symbol_str) } }
1646         })
1647     }
1648
1649     pub fn as_u32(self) -> u32 {
1650         self.0.as_u32()
1651     }
1652
1653     pub fn is_empty(self) -> bool {
1654         self == kw::Empty
1655     }
1656
1657     /// This method is supposed to be used in error messages, so it's expected to be
1658     /// identical to printing the original identifier token written in source code
1659     /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
1660     /// or edition, so we have to guess the rawness using the global edition.
1661     pub fn to_ident_string(self) -> String {
1662         Ident::with_dummy_span(self).to_string()
1663     }
1664 }
1665
1666 impl fmt::Debug for Symbol {
1667     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1668         fmt::Debug::fmt(&self.as_str(), f)
1669     }
1670 }
1671
1672 impl fmt::Display for Symbol {
1673     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1674         fmt::Display::fmt(&self.as_str(), f)
1675     }
1676 }
1677
1678 impl<S: Encoder> Encodable<S> for Symbol {
1679     fn encode(&self, s: &mut S) -> Result<(), S::Error> {
1680         s.emit_str(&self.as_str())
1681     }
1682 }
1683
1684 impl<D: Decoder> Decodable<D> for Symbol {
1685     #[inline]
1686     fn decode(d: &mut D) -> Result<Symbol, D::Error> {
1687         Ok(Symbol::intern(&d.read_str()?))
1688     }
1689 }
1690
1691 impl<CTX> HashStable<CTX> for Symbol {
1692     #[inline]
1693     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1694         self.as_str().hash_stable(hcx, hasher);
1695     }
1696 }
1697
1698 impl<CTX> ToStableHashKey<CTX> for Symbol {
1699     type KeyType = SymbolStr;
1700
1701     #[inline]
1702     fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1703         self.as_str()
1704     }
1705 }
1706
1707 #[derive(Default)]
1708 pub(crate) struct Interner(Lock<InternerInner>);
1709
1710 // The `&'static str`s in this type actually point into the arena.
1711 //
1712 // The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
1713 // found that to regress performance up to 2% in some cases. This might be
1714 // revisited after further improvements to `indexmap`.
1715 //
1716 // This type is private to prevent accidentally constructing more than one `Interner` on the same
1717 // thread, which makes it easy to mixup `Symbol`s between `Interner`s.
1718 #[derive(Default)]
1719 struct InternerInner {
1720     arena: DroplessArena,
1721     names: FxHashMap<&'static str, Symbol>,
1722     strings: Vec<&'static str>,
1723 }
1724
1725 impl Interner {
1726     fn prefill(init: &[&'static str]) -> Self {
1727         Interner(Lock::new(InternerInner {
1728             strings: init.into(),
1729             names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
1730             ..Default::default()
1731         }))
1732     }
1733
1734     #[inline]
1735     fn intern(&self, string: &str) -> Symbol {
1736         let mut inner = self.0.lock();
1737         if let Some(&name) = inner.names.get(string) {
1738             return name;
1739         }
1740
1741         let name = Symbol::new(inner.strings.len() as u32);
1742
1743         // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
1744         // UTF-8.
1745         let string: &str =
1746             unsafe { str::from_utf8_unchecked(inner.arena.alloc_slice(string.as_bytes())) };
1747         // It is safe to extend the arena allocation to `'static` because we only access
1748         // these while the arena is still alive.
1749         let string: &'static str = unsafe { &*(string as *const str) };
1750         inner.strings.push(string);
1751         inner.names.insert(string, name);
1752         name
1753     }
1754
1755     // Get the symbol as a string. `Symbol::as_str()` should be used in
1756     // preference to this function.
1757     fn get(&self, symbol: Symbol) -> &str {
1758         self.0.lock().strings[symbol.0.as_usize()]
1759     }
1760 }
1761
1762 // This module has a very short name because it's used a lot.
1763 /// This module contains all the defined keyword `Symbol`s.
1764 ///
1765 /// Given that `kw` is imported, use them like `kw::keyword_name`.
1766 /// For example `kw::Loop` or `kw::Break`.
1767 pub mod kw {
1768     pub use super::kw_generated::*;
1769 }
1770
1771 // This module has a very short name because it's used a lot.
1772 /// This module contains all the defined non-keyword `Symbol`s.
1773 ///
1774 /// Given that `sym` is imported, use them like `sym::symbol_name`.
1775 /// For example `sym::rustfmt` or `sym::u8`.
1776 pub mod sym {
1777     use super::Symbol;
1778     use std::convert::TryInto;
1779
1780     #[doc(inline)]
1781     pub use super::sym_generated::*;
1782
1783     // Used from a macro in `librustc_feature/accepted.rs`
1784     pub use super::kw::MacroRules as macro_rules;
1785
1786     /// Get the symbol for an integer.
1787     ///
1788     /// The first few non-negative integers each have a static symbol and therefore
1789     /// are fast.
1790     pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
1791         if let Result::Ok(idx) = n.try_into() {
1792             if idx < 10 {
1793                 return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
1794             }
1795         }
1796         Symbol::intern(&n.to_string())
1797     }
1798 }
1799
1800 impl Symbol {
1801     fn is_special(self) -> bool {
1802         self <= kw::Underscore
1803     }
1804
1805     fn is_used_keyword_always(self) -> bool {
1806         self >= kw::As && self <= kw::While
1807     }
1808
1809     fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1810         (self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
1811     }
1812
1813     fn is_unused_keyword_always(self) -> bool {
1814         self >= kw::Abstract && self <= kw::Yield
1815     }
1816
1817     fn is_unused_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1818         self == kw::Try && edition() >= Edition::Edition2018
1819     }
1820
1821     pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
1822         self.is_special()
1823             || self.is_used_keyword_always()
1824             || self.is_unused_keyword_always()
1825             || self.is_used_keyword_conditional(edition)
1826             || self.is_unused_keyword_conditional(edition)
1827     }
1828
1829     /// A keyword or reserved identifier that can be used as a path segment.
1830     pub fn is_path_segment_keyword(self) -> bool {
1831         self == kw::Super
1832             || self == kw::SelfLower
1833             || self == kw::SelfUpper
1834             || self == kw::Crate
1835             || self == kw::PathRoot
1836             || self == kw::DollarCrate
1837     }
1838
1839     /// Returns `true` if the symbol is `true` or `false`.
1840     pub fn is_bool_lit(self) -> bool {
1841         self == kw::True || self == kw::False
1842     }
1843
1844     /// Returns `true` if this symbol can be a raw identifier.
1845     pub fn can_be_raw(self) -> bool {
1846         self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword()
1847     }
1848 }
1849
1850 impl Ident {
1851     // Returns `true` for reserved identifiers used internally for elided lifetimes,
1852     // unnamed method parameters, crate root module, error recovery etc.
1853     pub fn is_special(self) -> bool {
1854         self.name.is_special()
1855     }
1856
1857     /// Returns `true` if the token is a keyword used in the language.
1858     pub fn is_used_keyword(self) -> bool {
1859         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1860         self.name.is_used_keyword_always()
1861             || self.name.is_used_keyword_conditional(|| self.span.edition())
1862     }
1863
1864     /// Returns `true` if the token is a keyword reserved for possible future use.
1865     pub fn is_unused_keyword(self) -> bool {
1866         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1867         self.name.is_unused_keyword_always()
1868             || self.name.is_unused_keyword_conditional(|| self.span.edition())
1869     }
1870
1871     /// Returns `true` if the token is either a special identifier or a keyword.
1872     pub fn is_reserved(self) -> bool {
1873         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1874         self.name.is_reserved(|| self.span.edition())
1875     }
1876
1877     /// A keyword or reserved identifier that can be used as a path segment.
1878     pub fn is_path_segment_keyword(self) -> bool {
1879         self.name.is_path_segment_keyword()
1880     }
1881
1882     /// We see this identifier in a normal identifier position, like variable name or a type.
1883     /// How was it written originally? Did it use the raw form? Let's try to guess.
1884     pub fn is_raw_guess(self) -> bool {
1885         self.name.can_be_raw() && self.is_reserved()
1886     }
1887 }
1888
1889 /// An alternative to [`Symbol`], useful when the chars within the symbol need to
1890 /// be accessed. It deliberately has limited functionality and should only be
1891 /// used for temporary values.
1892 ///
1893 /// Because the interner outlives any thread which uses this type, we can
1894 /// safely treat `string` which points to interner data, as an immortal string,
1895 /// as long as this type never crosses between threads.
1896 //
1897 // FIXME: ensure that the interner outlives any thread which uses `SymbolStr`,
1898 // by creating a new thread right after constructing the interner.
1899 #[derive(Clone, Eq, PartialOrd, Ord)]
1900 pub struct SymbolStr {
1901     string: &'static str,
1902 }
1903
1904 // This impl allows a `SymbolStr` to be directly equated with a `String` or
1905 // `&str`.
1906 impl<T: std::ops::Deref<Target = str>> std::cmp::PartialEq<T> for SymbolStr {
1907     fn eq(&self, other: &T) -> bool {
1908         self.string == other.deref()
1909     }
1910 }
1911
1912 impl !Send for SymbolStr {}
1913 impl !Sync for SymbolStr {}
1914
1915 /// This impl means that if `ss` is a `SymbolStr`:
1916 /// - `*ss` is a `str`;
1917 /// - `&*ss` is a `&str` (and `match &*ss { ... }` is a common pattern).
1918 /// - `&ss as &str` is a `&str`, which means that `&ss` can be passed to a
1919 ///   function expecting a `&str`.
1920 impl std::ops::Deref for SymbolStr {
1921     type Target = str;
1922     #[inline]
1923     fn deref(&self) -> &str {
1924         self.string
1925     }
1926 }
1927
1928 impl fmt::Debug for SymbolStr {
1929     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1930         fmt::Debug::fmt(self.string, f)
1931     }
1932 }
1933
1934 impl fmt::Display for SymbolStr {
1935     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1936         fmt::Display::fmt(self.string, f)
1937     }
1938 }
1939
1940 impl<CTX> HashStable<CTX> for SymbolStr {
1941     #[inline]
1942     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1943         self.string.hash_stable(hcx, hasher)
1944     }
1945 }
1946
1947 impl<CTX> ToStableHashKey<CTX> for SymbolStr {
1948     type KeyType = SymbolStr;
1949
1950     #[inline]
1951     fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1952         self.clone()
1953     }
1954 }