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