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