]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_span/src/symbol.rs
Add LLVM CFI support to the Rust compiler
[rust.git] / compiler / rustc_span / src / symbol.rs
1 //! An "interner" is a data structure that associates values with usize tags and
2 //! allows bidirectional lookup; i.e., given a value, one can easily find the
3 //! type, and vice versa.
4
5 use rustc_arena::DroplessArena;
6 use rustc_data_structures::fx::FxHashMap;
7 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
8 use rustc_data_structures::sync::Lock;
9 use rustc_macros::HashStable_Generic;
10 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
11
12 use std::cmp::{Ord, PartialEq, PartialOrd};
13 use std::fmt;
14 use std::hash::{Hash, Hasher};
15 use std::str;
16
17 use crate::{with_session_globals, Edition, Span, DUMMY_SP};
18
19 #[cfg(test)]
20 mod tests;
21
22 // The proc macro code for this is in `compiler/rustc_macros/src/symbols.rs`.
23 symbols! {
24     // After modifying this list adjust `is_special`, `is_used_keyword`/`is_unused_keyword`,
25     // this should be rarely necessary though if the keywords are kept in alphabetic order.
26     Keywords {
27         // Special reserved identifiers used internally for elided lifetimes,
28         // unnamed method parameters, crate root module, error recovery etc.
29         Empty:              "",
30         PathRoot:           "{{root}}",
31         DollarCrate:        "$crate",
32         Underscore:         "_",
33
34         // Keywords that are used in stable Rust.
35         As:                 "as",
36         Break:              "break",
37         Const:              "const",
38         Continue:           "continue",
39         Crate:              "crate",
40         Else:               "else",
41         Enum:               "enum",
42         Extern:             "extern",
43         False:              "false",
44         Fn:                 "fn",
45         For:                "for",
46         If:                 "if",
47         Impl:               "impl",
48         In:                 "in",
49         Let:                "let",
50         Loop:               "loop",
51         Match:              "match",
52         Mod:                "mod",
53         Move:               "move",
54         Mut:                "mut",
55         Pub:                "pub",
56         Ref:                "ref",
57         Return:             "return",
58         SelfLower:          "self",
59         SelfUpper:          "Self",
60         Static:             "static",
61         Struct:             "struct",
62         Super:              "super",
63         Trait:              "trait",
64         True:               "true",
65         Type:               "type",
66         Unsafe:             "unsafe",
67         Use:                "use",
68         Where:              "where",
69         While:              "while",
70
71         // Keywords that are used in unstable Rust or reserved for future use.
72         Abstract:           "abstract",
73         Become:             "become",
74         Box:                "box",
75         Do:                 "do",
76         Final:              "final",
77         Macro:              "macro",
78         Override:           "override",
79         Priv:               "priv",
80         Typeof:             "typeof",
81         Unsized:            "unsized",
82         Virtual:            "virtual",
83         Yield:              "yield",
84
85         // Edition-specific keywords that are used in stable Rust.
86         Async:              "async", // >= 2018 Edition only
87         Await:              "await", // >= 2018 Edition only
88         Dyn:                "dyn", // >= 2018 Edition only
89
90         // Edition-specific keywords that are used in unstable Rust or reserved for future use.
91         Try:                "try", // >= 2018 Edition only
92
93         // Special lifetime names
94         UnderscoreLifetime: "'_",
95         StaticLifetime:     "'static",
96
97         // Weak keywords, have special meaning only in specific contexts.
98         Auto:               "auto",
99         Catch:              "catch",
100         Default:            "default",
101         MacroRules:         "macro_rules",
102         Raw:                "raw",
103         Union:              "union",
104     }
105
106     // Pre-interned symbols that can be referred to with `rustc_span::sym::*`.
107     //
108     // The symbol is the stringified identifier unless otherwise specified, in
109     // which case the name should mention the non-identifier punctuation.
110     // E.g. `sym::proc_dash_macro` represents "proc-macro", and it shouldn't be
111     // called `sym::proc_macro` because then it's easy to mistakenly think it
112     // represents "proc_macro".
113     //
114     // As well as the symbols listed, there are symbols for the strings
115     // "0", "1", ..., "9", which are accessible via `sym::integer`.
116     //
117     // The proc macro will abort if symbols are not in alphabetical order (as
118     // defined by `impl Ord for str`) or if any symbols are duplicated. Vim
119     // users can sort the list by selecting it and executing the command
120     // `:'<,'>!LC_ALL=C sort`.
121     //
122     // There is currently no checking that all symbols are used; that would be
123     // nice to have.
124     Symbols {
125         AcqRel,
126         Acquire,
127         Alignment,
128         Any,
129         Arc,
130         Argument,
131         ArgumentV1,
132         Arguments,
133         AsMut,
134         AsRef,
135         AtomicBool,
136         AtomicI128,
137         AtomicI16,
138         AtomicI32,
139         AtomicI64,
140         AtomicI8,
141         AtomicIsize,
142         AtomicPtr,
143         AtomicU128,
144         AtomicU16,
145         AtomicU32,
146         AtomicU64,
147         AtomicU8,
148         AtomicUsize,
149         BTreeEntry,
150         BTreeMap,
151         BTreeSet,
152         BinaryHeap,
153         Borrow,
154         Break,
155         C,
156         CStr,
157         CString,
158         Center,
159         Clone,
160         Continue,
161         Copy,
162         Count,
163         Cow,
164         Debug,
165         DebugStruct,
166         DebugTuple,
167         Decodable,
168         Decoder,
169         Default,
170         Deref,
171         DirBuilder,
172         Display,
173         DoubleEndedIterator,
174         Duration,
175         Encodable,
176         Encoder,
177         Eq,
178         Equal,
179         Err,
180         Error,
181         File,
182         FileType,
183         FormatSpec,
184         Formatter,
185         From,
186         FromIterator,
187         Future,
188         FxHashMap,
189         FxHashSet,
190         GlobalAlloc,
191         Hash,
192         HashMap,
193         HashMapEntry,
194         HashSet,
195         Hasher,
196         Implied,
197         Input,
198         Into,
199         IntoIterator,
200         IoRead,
201         IoWrite,
202         Is,
203         ItemContext,
204         Iterator,
205         Layout,
206         Left,
207         LinkedList,
208         LintPass,
209         Mutex,
210         None,
211         Ok,
212         Option,
213         Ord,
214         Ordering,
215         OsStr,
216         OsString,
217         Output,
218         Param,
219         PartialEq,
220         PartialOrd,
221         Path,
222         PathBuf,
223         Pending,
224         Pin,
225         Pointer,
226         Poll,
227         ProcMacro,
228         ProcMacroHack,
229         ProceduralMasqueradeDummyType,
230         Range,
231         RangeFrom,
232         RangeFull,
233         RangeInclusive,
234         RangeTo,
235         RangeToInclusive,
236         Rc,
237         Ready,
238         Receiver,
239         Relaxed,
240         Release,
241         Result,
242         Return,
243         Right,
244         RustcDecodable,
245         RustcEncodable,
246         Send,
247         SeqCst,
248         Some,
249         String,
250         StructuralEq,
251         StructuralPartialEq,
252         Sync,
253         Target,
254         ToOwned,
255         ToString,
256         Try,
257         TryFrom,
258         TryInto,
259         Ty,
260         TyCtxt,
261         TyKind,
262         Unknown,
263         UnsafeArg,
264         Vec,
265         VecDeque,
266         Yield,
267         _DECLS,
268         _Self,
269         __D,
270         __H,
271         __S,
272         __next,
273         __try_var,
274         _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         assert,
331         assert_inhabited,
332         assert_macro,
333         assert_receiver_is_total_eq,
334         assert_uninit_valid,
335         assert_zero_valid,
336         associated_consts,
337         associated_type_bounds,
338         associated_type_defaults,
339         associated_types,
340         assume,
341         assume_init,
342         async_await,
343         async_closure,
344         atomic,
345         atomic_mod,
346         atomics,
347         att_syntax,
348         attr,
349         attr_literals,
350         attributes,
351         augmented_assignments,
352         auto_traits,
353         automatically_derived,
354         avx512_target_feature,
355         await_macro,
356         bang,
357         begin_panic,
358         begin_panic_fmt,
359         bench,
360         bin,
361         bind_by_move_pattern_guards,
362         bindings_after_at,
363         bitand,
364         bitand_assign,
365         bitor,
366         bitor_assign,
367         bitreverse,
368         bitxor,
369         bitxor_assign,
370         black_box,
371         block,
372         bool,
373         borrowck_graphviz_format,
374         borrowck_graphviz_postflow,
375         borrowck_graphviz_preflow,
376         box_free,
377         box_patterns,
378         box_syntax,
379         bpf_target_feature,
380         braced_empty_structs,
381         branch,
382         breakpoint,
383         bridge,
384         bswap,
385         c_str,
386         c_unwind,
387         c_variadic,
388         call,
389         call_mut,
390         call_once,
391         caller_location,
392         capture_disjoint_fields,
393         cdylib,
394         ceilf32,
395         ceilf64,
396         cfg,
397         cfg_accessible,
398         cfg_attr,
399         cfg_attr_multi,
400         cfg_doctest,
401         cfg_eval,
402         cfg_hide,
403         cfg_panic,
404         cfg_sanitize,
405         cfg_target_abi,
406         cfg_target_feature,
407         cfg_target_has_atomic,
408         cfg_target_thread_local,
409         cfg_target_vendor,
410         cfg_version,
411         cfi,
412         char,
413         client,
414         clippy,
415         clobber_abi,
416         clone,
417         clone_closures,
418         clone_from,
419         closure,
420         closure_to_fn_coercion,
421         closure_track_caller,
422         cmp,
423         cmp_max,
424         cmp_min,
425         cmpxchg16b_target_feature,
426         cmse_nonsecure_entry,
427         coerce_unsized,
428         cold,
429         column,
430         compare_and_swap,
431         compare_exchange,
432         compare_exchange_weak,
433         compile_error,
434         compiler_builtins,
435         compiler_fence,
436         concat,
437         concat_idents,
438         conservative_impl_trait,
439         console,
440         const_allocate,
441         const_async_blocks,
442         const_compare_raw_pointers,
443         const_constructor,
444         const_eval_limit,
445         const_evaluatable_checked,
446         const_extern_fn,
447         const_fn,
448         const_fn_floating_point_arithmetic,
449         const_fn_fn_ptr_basics,
450         const_fn_trait_bound,
451         const_fn_transmute,
452         const_fn_union,
453         const_fn_unsize,
454         const_for,
455         const_format_args,
456         const_generic_defaults,
457         const_generics,
458         const_generics_defaults,
459         const_if_match,
460         const_impl_trait,
461         const_in_array_repeat_expressions,
462         const_indexing,
463         const_let,
464         const_loop,
465         const_mut_refs,
466         const_panic,
467         const_panic_fmt,
468         const_precise_live_drops,
469         const_ptr,
470         const_raw_ptr_deref,
471         const_raw_ptr_to_usize_cast,
472         const_refs_to_cell,
473         const_slice_ptr,
474         const_trait_bound_opt_out,
475         const_trait_impl,
476         const_transmute,
477         const_try,
478         constant,
479         constructor,
480         contents,
481         context,
482         convert,
483         copy,
484         copy_closures,
485         copy_nonoverlapping,
486         copysignf32,
487         copysignf64,
488         core,
489         core_intrinsics,
490         core_panic,
491         core_panic_2015_macro,
492         core_panic_macro,
493         cosf32,
494         cosf64,
495         cr,
496         crate_id,
497         crate_in_paths,
498         crate_local,
499         crate_name,
500         crate_type,
501         crate_visibility_modifier,
502         crt_dash_static: "crt-static",
503         cstring_type,
504         ctlz,
505         ctlz_nonzero,
506         ctpop,
507         cttz,
508         cttz_nonzero,
509         custom_attribute,
510         custom_derive,
511         custom_inner_attributes,
512         custom_test_frameworks,
513         d,
514         dead_code,
515         dealloc,
516         debug,
517         debug_assert_macro,
518         debug_assertions,
519         debug_struct,
520         debug_trait_builder,
521         debug_tuple,
522         decl_macro,
523         declare_lint_pass,
524         decode,
525         default_alloc_error_handler,
526         default_lib_allocator,
527         default_method_body_is_const,
528         default_type_parameter_fallback,
529         default_type_params,
530         delay_span_bug_from_inside_query,
531         deny,
532         deprecated,
533         deref,
534         deref_method,
535         deref_mut,
536         deref_target,
537         derive,
538         derive_default_enum,
539         destructuring_assignment,
540         diagnostic,
541         direct,
542         discriminant_kind,
543         discriminant_type,
544         discriminant_value,
545         dispatch_from_dyn,
546         display_trait,
547         div,
548         div_assign,
549         doc,
550         doc_alias,
551         doc_cfg,
552         doc_cfg_hide,
553         doc_keyword,
554         doc_masked,
555         doc_notable_trait,
556         doc_primitive,
557         doc_spotlight,
558         doctest,
559         document_private_items,
560         dotdot_in_tuple_patterns,
561         dotdoteq_in_patterns,
562         dreg,
563         dreg_low16,
564         dreg_low8,
565         drop,
566         drop_in_place,
567         drop_types_in_const,
568         dropck_eyepatch,
569         dropck_parametricity,
570         dylib,
571         dyn_metadata,
572         dyn_trait,
573         edition_macro_pats,
574         edition_panic,
575         eh_catch_typeinfo,
576         eh_personality,
577         emit_enum,
578         emit_enum_variant,
579         emit_enum_variant_arg,
580         emit_struct,
581         emit_struct_field,
582         enable,
583         enclosing_scope,
584         encode,
585         env,
586         eq,
587         ermsb_target_feature,
588         exact_div,
589         except,
590         exchange_malloc,
591         exclusive_range_pattern,
592         exhaustive_integer_patterns,
593         exhaustive_patterns,
594         existential_type,
595         exp2f32,
596         exp2f64,
597         expect,
598         expected,
599         expf32,
600         expf64,
601         explicit_generic_args_with_impl_trait,
602         export_name,
603         expr,
604         extended_key_value_attributes,
605         extern_absolute_paths,
606         extern_crate_item_prelude,
607         extern_crate_self,
608         extern_in_paths,
609         extern_prelude,
610         extern_types,
611         external_doc,
612         f,
613         f16c_target_feature,
614         f32,
615         f32_runtime,
616         f64,
617         f64_runtime,
618         fabsf32,
619         fabsf64,
620         fadd_fast,
621         fdiv_fast,
622         feature,
623         fence,
624         fetch_update,
625         ffi,
626         ffi_const,
627         ffi_pure,
628         ffi_returns_twice,
629         field,
630         field_init_shorthand,
631         file,
632         fill,
633         finish,
634         flags,
635         float_to_int_unchecked,
636         floorf32,
637         floorf64,
638         fmaf32,
639         fmaf64,
640         fmt,
641         fmt_as_str,
642         fmt_internals,
643         fmul_fast,
644         fn_align,
645         fn_must_use,
646         fn_mut,
647         fn_once,
648         fn_once_output,
649         forbid,
650         forget,
651         format,
652         format_args,
653         format_args_capture,
654         format_args_nl,
655         format_macro,
656         freeze,
657         freg,
658         frem_fast,
659         from,
660         from_desugaring,
661         from_generator,
662         from_iter,
663         from_method,
664         from_output,
665         from_residual,
666         from_size_align_unchecked,
667         from_usize,
668         fsub_fast,
669         fundamental,
670         future,
671         future_trait,
672         ge,
673         gen_future,
674         gen_kill,
675         generator,
676         generator_state,
677         generators,
678         generic_arg_infer,
679         generic_associated_types,
680         generic_const_exprs,
681         generic_param_attrs,
682         get_context,
683         global_allocator,
684         global_asm,
685         globs,
686         gt,
687         half_open_range_patterns,
688         hash,
689         hexagon_target_feature,
690         hidden,
691         homogeneous_aggregate,
692         html_favicon_url,
693         html_logo_url,
694         html_no_source,
695         html_playground_url,
696         html_root_url,
697         hwaddress,
698         i,
699         i128,
700         i128_type,
701         i16,
702         i32,
703         i64,
704         i8,
705         ident,
706         if_let,
707         if_let_guard,
708         if_while_or_patterns,
709         ignore,
710         impl_header_lifetime_elision,
711         impl_lint_pass,
712         impl_macros,
713         impl_trait_in_bindings,
714         import_shadowing,
715         imported_main,
716         in_band_lifetimes,
717         include,
718         include_bytes,
719         include_str,
720         inclusive_range_syntax,
721         index,
722         index_mut,
723         infer_outlives_requirements,
724         infer_static_outlives_requirements,
725         inherent_associated_types,
726         inlateout,
727         inline,
728         inline_const,
729         inout,
730         instruction_set,
731         intel,
732         into_iter,
733         intra_doc_pointers,
734         intrinsics,
735         irrefutable_let_patterns,
736         isa_attribute,
737         isize,
738         issue,
739         issue_5723_bootstrap,
740         issue_tracker_base_url,
741         item,
742         item_like_imports,
743         iter,
744         iter_repeat,
745         keyword,
746         kind,
747         kreg,
748         label,
749         label_break_value,
750         lang,
751         lang_items,
752         large_assignments,
753         lateout,
754         lazy_normalization_consts,
755         le,
756         len,
757         let_chains,
758         let_else,
759         lhs,
760         lib,
761         libc,
762         lifetime,
763         likely,
764         line,
765         link,
766         link_args,
767         link_cfg,
768         link_llvm_intrinsics,
769         link_name,
770         link_ordinal,
771         link_section,
772         linkage,
773         lint_reasons,
774         literal,
775         llvm_asm,
776         load,
777         local,
778         local_inner_macros,
779         log10f32,
780         log10f64,
781         log2f32,
782         log2f64,
783         log_syntax,
784         logf32,
785         logf64,
786         loop_break_value,
787         lt,
788         macro_at_most_once_rep,
789         macro_attributes_in_derive_output,
790         macro_escape,
791         macro_export,
792         macro_lifetime_matcher,
793         macro_literal_matcher,
794         macro_reexport,
795         macro_use,
796         macro_vis_matcher,
797         macros_in_extern,
798         main,
799         managed_boxes,
800         manually_drop,
801         map,
802         marker,
803         marker_trait_attr,
804         masked,
805         match_beginning_vert,
806         match_default_bindings,
807         maxnumf32,
808         maxnumf64,
809         may_dangle,
810         maybe_uninit,
811         maybe_uninit_uninit,
812         maybe_uninit_zeroed,
813         mem_discriminant,
814         mem_drop,
815         mem_forget,
816         mem_replace,
817         mem_size_of,
818         mem_size_of_val,
819         mem_uninitialized,
820         mem_zeroed,
821         member_constraints,
822         memory,
823         message,
824         meta,
825         metadata_type,
826         min_align_of,
827         min_align_of_val,
828         min_const_fn,
829         min_const_generics,
830         min_const_unsafe_fn,
831         min_specialization,
832         min_type_alias_impl_trait,
833         minnumf32,
834         minnumf64,
835         mips_target_feature,
836         misc,
837         mmx_reg,
838         modifiers,
839         module,
840         module_path,
841         more_qualified_paths,
842         more_struct_aliases,
843         movbe_target_feature,
844         move_ref_pattern,
845         move_size_limit,
846         mul,
847         mul_assign,
848         mul_with_overflow,
849         must_not_suspend,
850         must_use,
851         mut_ptr,
852         mut_slice_ptr,
853         naked,
854         naked_functions,
855         name,
856         native_link_modifiers,
857         native_link_modifiers_as_needed,
858         native_link_modifiers_bundle,
859         native_link_modifiers_verbatim,
860         native_link_modifiers_whole_archive,
861         ne,
862         nearbyintf32,
863         nearbyintf64,
864         needs_allocator,
865         needs_drop,
866         needs_panic_runtime,
867         neg,
868         negate_unsigned,
869         negative_impls,
870         never,
871         never_type,
872         never_type_fallback,
873         new,
874         new_unchecked,
875         next,
876         nll,
877         no,
878         no_builtins,
879         no_core,
880         no_coverage,
881         no_crate_inject,
882         no_debug,
883         no_default_passes,
884         no_implicit_prelude,
885         no_inline,
886         no_link,
887         no_main,
888         no_mangle,
889         no_niche,
890         no_sanitize,
891         no_stack_check,
892         no_start,
893         no_std,
894         nomem,
895         non_ascii_idents,
896         non_exhaustive,
897         non_exhaustive_omitted_patterns_lint,
898         non_modrs_mods,
899         none_error,
900         nontemporal_store,
901         noop_method_borrow,
902         noop_method_clone,
903         noop_method_deref,
904         noreturn,
905         nostack,
906         not,
907         notable_trait,
908         note,
909         object_safe_for_dispatch,
910         of,
911         offset,
912         omit_gdb_pretty_printer_section,
913         on,
914         on_unimplemented,
915         oom,
916         opaque,
917         ops,
918         opt_out_copy,
919         optimize,
920         optimize_attribute,
921         optin_builtin_traits,
922         option,
923         option_env,
924         options,
925         or,
926         or_patterns,
927         other,
928         out,
929         overlapping_marker_traits,
930         owned_box,
931         packed,
932         panic,
933         panic_2015,
934         panic_2021,
935         panic_abort,
936         panic_bounds_check,
937         panic_display,
938         panic_fmt,
939         panic_handler,
940         panic_impl,
941         panic_implementation,
942         panic_info,
943         panic_location,
944         panic_runtime,
945         panic_str,
946         panic_unwind,
947         panicking,
948         param_attrs,
949         partial_cmp,
950         partial_ord,
951         passes,
952         pat,
953         pat_param,
954         path,
955         pattern_parentheses,
956         phantom_data,
957         pin,
958         pinned,
959         platform_intrinsics,
960         plugin,
961         plugin_registrar,
962         plugins,
963         pointee_trait,
964         pointer,
965         pointer_trait_fmt,
966         poll,
967         position,
968         post_dash_lto: "post-lto",
969         powerpc_target_feature,
970         powf32,
971         powf64,
972         powif32,
973         powif64,
974         pre_dash_lto: "pre-lto",
975         precise_pointer_size_matching,
976         precision,
977         pref_align_of,
978         prefetch_read_data,
979         prefetch_read_instruction,
980         prefetch_write_data,
981         prefetch_write_instruction,
982         preg,
983         prelude,
984         prelude_import,
985         preserves_flags,
986         primitive,
987         proc_dash_macro: "proc-macro",
988         proc_macro,
989         proc_macro_attribute,
990         proc_macro_def_site,
991         proc_macro_derive,
992         proc_macro_expr,
993         proc_macro_gen,
994         proc_macro_hygiene,
995         proc_macro_internals,
996         proc_macro_mod,
997         proc_macro_non_items,
998         proc_macro_path_invoc,
999         profiler_builtins,
1000         profiler_runtime,
1001         ptr_guaranteed_eq,
1002         ptr_guaranteed_ne,
1003         ptr_null,
1004         ptr_null_mut,
1005         ptr_offset_from,
1006         pub_macro_rules,
1007         pub_restricted,
1008         pure,
1009         pushpop_unsafe,
1010         qreg,
1011         qreg_low4,
1012         qreg_low8,
1013         quad_precision_float,
1014         question_mark,
1015         quote,
1016         range_inclusive_new,
1017         raw_dylib,
1018         raw_eq,
1019         raw_identifiers,
1020         raw_ref_op,
1021         re_rebalance_coherence,
1022         read_enum,
1023         read_enum_variant,
1024         read_enum_variant_arg,
1025         read_struct,
1026         read_struct_field,
1027         readonly,
1028         realloc,
1029         reason,
1030         receiver,
1031         recursion_limit,
1032         reexport_test_harness_main,
1033         ref_unwind_safe_trait,
1034         reference,
1035         reflect,
1036         reg,
1037         reg16,
1038         reg32,
1039         reg64,
1040         reg_abcd,
1041         reg_byte,
1042         reg_nonzero,
1043         reg_thumb,
1044         register_attr,
1045         register_tool,
1046         relaxed_adts,
1047         relaxed_struct_unsize,
1048         rem,
1049         rem_assign,
1050         repr,
1051         repr128,
1052         repr_align,
1053         repr_align_enum,
1054         repr_no_niche,
1055         repr_packed,
1056         repr_simd,
1057         repr_transparent,
1058         residual,
1059         result,
1060         rhs,
1061         rintf32,
1062         rintf64,
1063         riscv_target_feature,
1064         rlib,
1065         rotate_left,
1066         rotate_right,
1067         roundf32,
1068         roundf64,
1069         rt,
1070         rtm_target_feature,
1071         rust,
1072         rust_2015,
1073         rust_2015_preview,
1074         rust_2018,
1075         rust_2018_preview,
1076         rust_2021,
1077         rust_2021_preview,
1078         rust_begin_unwind,
1079         rust_eh_catch_typeinfo,
1080         rust_eh_personality,
1081         rust_eh_register_frames,
1082         rust_eh_unregister_frames,
1083         rust_oom,
1084         rustc,
1085         rustc_allocator,
1086         rustc_allocator_nounwind,
1087         rustc_allow_const_fn_unstable,
1088         rustc_attrs,
1089         rustc_builtin_macro,
1090         rustc_capture_analysis,
1091         rustc_clean,
1092         rustc_const_stable,
1093         rustc_const_unstable,
1094         rustc_conversion_suggestion,
1095         rustc_def_path,
1096         rustc_deprecated,
1097         rustc_diagnostic_item,
1098         rustc_diagnostic_macros,
1099         rustc_dirty,
1100         rustc_dummy,
1101         rustc_dump_env_program_clauses,
1102         rustc_dump_program_clauses,
1103         rustc_dump_user_substs,
1104         rustc_dump_vtable,
1105         rustc_error,
1106         rustc_evaluate_where_clauses,
1107         rustc_expected_cgu_reuse,
1108         rustc_if_this_changed,
1109         rustc_inherit_overflow_checks,
1110         rustc_insignificant_dtor,
1111         rustc_layout,
1112         rustc_layout_scalar_valid_range_end,
1113         rustc_layout_scalar_valid_range_start,
1114         rustc_legacy_const_generics,
1115         rustc_macro_transparency,
1116         rustc_main,
1117         rustc_mir,
1118         rustc_nonnull_optimization_guaranteed,
1119         rustc_object_lifetime_default,
1120         rustc_on_unimplemented,
1121         rustc_outlives,
1122         rustc_paren_sugar,
1123         rustc_partition_codegened,
1124         rustc_partition_reused,
1125         rustc_peek,
1126         rustc_peek_definite_init,
1127         rustc_peek_indirectly_mutable,
1128         rustc_peek_liveness,
1129         rustc_peek_maybe_init,
1130         rustc_peek_maybe_uninit,
1131         rustc_polymorphize_error,
1132         rustc_private,
1133         rustc_proc_macro_decls,
1134         rustc_promotable,
1135         rustc_regions,
1136         rustc_reservation_impl,
1137         rustc_serialize,
1138         rustc_skip_array_during_method_dispatch,
1139         rustc_specialization_trait,
1140         rustc_stable,
1141         rustc_std_internal_symbol,
1142         rustc_symbol_name,
1143         rustc_synthetic,
1144         rustc_test_marker,
1145         rustc_then_this_would_need,
1146         rustc_trivial_field_reads,
1147         rustc_unsafe_specialization_marker,
1148         rustc_variance,
1149         rustdoc,
1150         rustfmt,
1151         rvalue_static_promotion,
1152         s,
1153         sanitize,
1154         sanitizer_runtime,
1155         saturating_add,
1156         saturating_sub,
1157         self_in_typedefs,
1158         self_struct_ctor,
1159         semitransparent,
1160         shl,
1161         shl_assign,
1162         should_panic,
1163         shr,
1164         shr_assign,
1165         simd,
1166         simd_add,
1167         simd_and,
1168         simd_bitmask,
1169         simd_cast,
1170         simd_ceil,
1171         simd_div,
1172         simd_eq,
1173         simd_extract,
1174         simd_fabs,
1175         simd_fcos,
1176         simd_fexp,
1177         simd_fexp2,
1178         simd_ffi,
1179         simd_flog,
1180         simd_flog10,
1181         simd_flog2,
1182         simd_floor,
1183         simd_fma,
1184         simd_fmax,
1185         simd_fmin,
1186         simd_fpow,
1187         simd_fpowi,
1188         simd_fsin,
1189         simd_fsqrt,
1190         simd_gather,
1191         simd_ge,
1192         simd_gt,
1193         simd_insert,
1194         simd_le,
1195         simd_lt,
1196         simd_mul,
1197         simd_ne,
1198         simd_neg,
1199         simd_or,
1200         simd_reduce_add_ordered,
1201         simd_reduce_add_unordered,
1202         simd_reduce_all,
1203         simd_reduce_and,
1204         simd_reduce_any,
1205         simd_reduce_max,
1206         simd_reduce_max_nanless,
1207         simd_reduce_min,
1208         simd_reduce_min_nanless,
1209         simd_reduce_mul_ordered,
1210         simd_reduce_mul_unordered,
1211         simd_reduce_or,
1212         simd_reduce_xor,
1213         simd_rem,
1214         simd_round,
1215         simd_saturating_add,
1216         simd_saturating_sub,
1217         simd_scatter,
1218         simd_select,
1219         simd_select_bitmask,
1220         simd_shl,
1221         simd_shr,
1222         simd_shuffle,
1223         simd_sub,
1224         simd_trunc,
1225         simd_xor,
1226         since,
1227         sinf32,
1228         sinf64,
1229         size,
1230         size_of,
1231         size_of_val,
1232         sized,
1233         skip,
1234         slice,
1235         slice_alloc,
1236         slice_len_fn,
1237         slice_patterns,
1238         slice_u8,
1239         slice_u8_alloc,
1240         slicing_syntax,
1241         soft,
1242         specialization,
1243         speed,
1244         spotlight,
1245         sqrtf32,
1246         sqrtf64,
1247         sreg,
1248         sreg_low16,
1249         sse4a_target_feature,
1250         stable,
1251         staged_api,
1252         start,
1253         state,
1254         static_in_const,
1255         static_nobundle,
1256         static_recursion,
1257         staticlib,
1258         std,
1259         std_inject,
1260         std_panic,
1261         std_panic_2015_macro,
1262         std_panic_macro,
1263         stmt,
1264         stmt_expr_attributes,
1265         stop_after_dataflow,
1266         store,
1267         str,
1268         str_alloc,
1269         stringify,
1270         struct_field_attributes,
1271         struct_inherit,
1272         struct_variant,
1273         structural_match,
1274         structural_peq,
1275         structural_teq,
1276         sty,
1277         sub,
1278         sub_assign,
1279         sub_with_overflow,
1280         suggestion,
1281         sym,
1282         sync,
1283         t32,
1284         target_abi,
1285         target_arch,
1286         target_endian,
1287         target_env,
1288         target_family,
1289         target_feature,
1290         target_feature_11,
1291         target_has_atomic,
1292         target_has_atomic_equal_alignment,
1293         target_has_atomic_load_store,
1294         target_os,
1295         target_pointer_width,
1296         target_target_vendor,
1297         target_thread_local,
1298         target_vendor,
1299         task,
1300         tbm_target_feature,
1301         termination,
1302         termination_trait,
1303         termination_trait_test,
1304         test,
1305         test_2018_feature,
1306         test_accepted_feature,
1307         test_case,
1308         test_removed_feature,
1309         test_runner,
1310         then_with,
1311         thread,
1312         thread_local,
1313         tool_attributes,
1314         tool_lints,
1315         trace_macros,
1316         track_caller,
1317         trait_alias,
1318         trait_upcasting,
1319         transmute,
1320         transparent,
1321         transparent_enums,
1322         transparent_unions,
1323         trivial_bounds,
1324         truncf32,
1325         truncf64,
1326         try_blocks,
1327         try_from,
1328         try_into,
1329         try_trait_v2,
1330         tt,
1331         tuple,
1332         tuple_from_req,
1333         tuple_indexing,
1334         two_phase,
1335         ty,
1336         type_alias_enum_variants,
1337         type_alias_impl_trait,
1338         type_ascription,
1339         type_id,
1340         type_length_limit,
1341         type_macros,
1342         type_name,
1343         u128,
1344         u16,
1345         u32,
1346         u64,
1347         u8,
1348         unaligned_volatile_load,
1349         unaligned_volatile_store,
1350         unboxed_closures,
1351         unchecked_add,
1352         unchecked_div,
1353         unchecked_mul,
1354         unchecked_rem,
1355         unchecked_shl,
1356         unchecked_shr,
1357         unchecked_sub,
1358         underscore_const_names,
1359         underscore_imports,
1360         underscore_lifetimes,
1361         uniform_paths,
1362         unit,
1363         universal_impl_trait,
1364         unix,
1365         unlikely,
1366         unmarked_api,
1367         unpin,
1368         unreachable,
1369         unreachable_code,
1370         unrestricted_attribute_tokens,
1371         unsafe_block_in_unsafe_fn,
1372         unsafe_cell,
1373         unsafe_no_drop_flag,
1374         unsize,
1375         unsized_fn_params,
1376         unsized_locals,
1377         unsized_tuple_coercion,
1378         unstable,
1379         untagged_unions,
1380         unused_qualifications,
1381         unwind,
1382         unwind_attributes,
1383         unwind_safe_trait,
1384         unwrap,
1385         unwrap_or,
1386         use_extern_macros,
1387         use_nested_groups,
1388         used,
1389         usize,
1390         v1,
1391         va_arg,
1392         va_copy,
1393         va_end,
1394         va_list,
1395         va_start,
1396         val,
1397         var,
1398         variant_count,
1399         vec,
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     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 is_empty(self) -> bool {
1646         self == kw::Empty
1647     }
1648
1649     /// This method is supposed to be used in error messages, so it's expected to be
1650     /// identical to printing the original identifier token written in source code
1651     /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
1652     /// or edition, so we have to guess the rawness using the global edition.
1653     pub fn to_ident_string(self) -> String {
1654         Ident::with_dummy_span(self).to_string()
1655     }
1656 }
1657
1658 impl fmt::Debug for Symbol {
1659     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1660         fmt::Debug::fmt(&self.as_str(), f)
1661     }
1662 }
1663
1664 impl fmt::Display for Symbol {
1665     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1666         fmt::Display::fmt(&self.as_str(), f)
1667     }
1668 }
1669
1670 impl<S: Encoder> Encodable<S> for Symbol {
1671     fn encode(&self, s: &mut S) -> Result<(), S::Error> {
1672         s.emit_str(&self.as_str())
1673     }
1674 }
1675
1676 impl<D: Decoder> Decodable<D> for Symbol {
1677     #[inline]
1678     fn decode(d: &mut D) -> Result<Symbol, D::Error> {
1679         Ok(Symbol::intern(&d.read_str()?))
1680     }
1681 }
1682
1683 impl<CTX> HashStable<CTX> for Symbol {
1684     #[inline]
1685     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1686         self.as_str().hash_stable(hcx, hasher);
1687     }
1688 }
1689
1690 impl<CTX> ToStableHashKey<CTX> for Symbol {
1691     type KeyType = SymbolStr;
1692
1693     #[inline]
1694     fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1695         self.as_str()
1696     }
1697 }
1698
1699 #[derive(Default)]
1700 pub(crate) struct Interner(Lock<InternerInner>);
1701
1702 // The `&'static str`s in this type actually point into the arena.
1703 //
1704 // The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
1705 // found that to regress performance up to 2% in some cases. This might be
1706 // revisited after further improvements to `indexmap`.
1707 //
1708 // This type is private to prevent accidentally constructing more than one `Interner` on the same
1709 // thread, which makes it easy to mixup `Symbol`s between `Interner`s.
1710 #[derive(Default)]
1711 struct InternerInner {
1712     arena: DroplessArena,
1713     names: FxHashMap<&'static str, Symbol>,
1714     strings: Vec<&'static str>,
1715 }
1716
1717 impl Interner {
1718     fn prefill(init: &[&'static str]) -> Self {
1719         Interner(Lock::new(InternerInner {
1720             strings: init.into(),
1721             names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
1722             ..Default::default()
1723         }))
1724     }
1725
1726     #[inline]
1727     fn intern(&self, string: &str) -> Symbol {
1728         let mut inner = self.0.lock();
1729         if let Some(&name) = inner.names.get(string) {
1730             return name;
1731         }
1732
1733         let name = Symbol::new(inner.strings.len() as u32);
1734
1735         // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
1736         // UTF-8.
1737         let string: &str =
1738             unsafe { str::from_utf8_unchecked(inner.arena.alloc_slice(string.as_bytes())) };
1739         // It is safe to extend the arena allocation to `'static` because we only access
1740         // these while the arena is still alive.
1741         let string: &'static str = unsafe { &*(string as *const str) };
1742         inner.strings.push(string);
1743         inner.names.insert(string, name);
1744         name
1745     }
1746
1747     // Get the symbol as a string. `Symbol::as_str()` should be used in
1748     // preference to this function.
1749     fn get(&self, symbol: Symbol) -> &str {
1750         self.0.lock().strings[symbol.0.as_usize()]
1751     }
1752 }
1753
1754 // This module has a very short name because it's used a lot.
1755 /// This module contains all the defined keyword `Symbol`s.
1756 ///
1757 /// Given that `kw` is imported, use them like `kw::keyword_name`.
1758 /// For example `kw::Loop` or `kw::Break`.
1759 pub mod kw {
1760     pub use super::kw_generated::*;
1761 }
1762
1763 // This module has a very short name because it's used a lot.
1764 /// This module contains all the defined non-keyword `Symbol`s.
1765 ///
1766 /// Given that `sym` is imported, use them like `sym::symbol_name`.
1767 /// For example `sym::rustfmt` or `sym::u8`.
1768 pub mod sym {
1769     use super::Symbol;
1770     use std::convert::TryInto;
1771
1772     #[doc(inline)]
1773     pub use super::sym_generated::*;
1774
1775     // Used from a macro in `librustc_feature/accepted.rs`
1776     pub use super::kw::MacroRules as macro_rules;
1777
1778     /// Get the symbol for an integer.
1779     ///
1780     /// The first few non-negative integers each have a static symbol and therefore
1781     /// are fast.
1782     pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
1783         if let Result::Ok(idx) = n.try_into() {
1784             if idx < 10 {
1785                 return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
1786             }
1787         }
1788         Symbol::intern(&n.to_string())
1789     }
1790 }
1791
1792 impl Symbol {
1793     fn is_special(self) -> bool {
1794         self <= kw::Underscore
1795     }
1796
1797     fn is_used_keyword_always(self) -> bool {
1798         self >= kw::As && self <= kw::While
1799     }
1800
1801     fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1802         (self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
1803     }
1804
1805     fn is_unused_keyword_always(self) -> bool {
1806         self >= kw::Abstract && self <= kw::Yield
1807     }
1808
1809     fn is_unused_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1810         self == kw::Try && edition() >= Edition::Edition2018
1811     }
1812
1813     pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
1814         self.is_special()
1815             || self.is_used_keyword_always()
1816             || self.is_unused_keyword_always()
1817             || self.is_used_keyword_conditional(edition)
1818             || self.is_unused_keyword_conditional(edition)
1819     }
1820
1821     /// A keyword or reserved identifier that can be used as a path segment.
1822     pub fn is_path_segment_keyword(self) -> bool {
1823         self == kw::Super
1824             || self == kw::SelfLower
1825             || self == kw::SelfUpper
1826             || self == kw::Crate
1827             || self == kw::PathRoot
1828             || self == kw::DollarCrate
1829     }
1830
1831     /// Returns `true` if the symbol is `true` or `false`.
1832     pub fn is_bool_lit(self) -> bool {
1833         self == kw::True || self == kw::False
1834     }
1835
1836     /// Returns `true` if this symbol can be a raw identifier.
1837     pub fn can_be_raw(self) -> bool {
1838         self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword()
1839     }
1840 }
1841
1842 impl Ident {
1843     // Returns `true` for reserved identifiers used internally for elided lifetimes,
1844     // unnamed method parameters, crate root module, error recovery etc.
1845     pub fn is_special(self) -> bool {
1846         self.name.is_special()
1847     }
1848
1849     /// Returns `true` if the token is a keyword used in the language.
1850     pub fn is_used_keyword(self) -> bool {
1851         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1852         self.name.is_used_keyword_always()
1853             || self.name.is_used_keyword_conditional(|| self.span.edition())
1854     }
1855
1856     /// Returns `true` if the token is a keyword reserved for possible future use.
1857     pub fn is_unused_keyword(self) -> bool {
1858         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1859         self.name.is_unused_keyword_always()
1860             || self.name.is_unused_keyword_conditional(|| self.span.edition())
1861     }
1862
1863     /// Returns `true` if the token is either a special identifier or a keyword.
1864     pub fn is_reserved(self) -> bool {
1865         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1866         self.name.is_reserved(|| self.span.edition())
1867     }
1868
1869     /// A keyword or reserved identifier that can be used as a path segment.
1870     pub fn is_path_segment_keyword(self) -> bool {
1871         self.name.is_path_segment_keyword()
1872     }
1873
1874     /// We see this identifier in a normal identifier position, like variable name or a type.
1875     /// How was it written originally? Did it use the raw form? Let's try to guess.
1876     pub fn is_raw_guess(self) -> bool {
1877         self.name.can_be_raw() && self.is_reserved()
1878     }
1879 }
1880
1881 /// An alternative to [`Symbol`], useful when the chars within the symbol need to
1882 /// be accessed. It deliberately has limited functionality and should only be
1883 /// used for temporary values.
1884 ///
1885 /// Because the interner outlives any thread which uses this type, we can
1886 /// safely treat `string` which points to interner data, as an immortal string,
1887 /// as long as this type never crosses between threads.
1888 //
1889 // FIXME: ensure that the interner outlives any thread which uses `SymbolStr`,
1890 // by creating a new thread right after constructing the interner.
1891 #[derive(Clone, Eq, PartialOrd, Ord)]
1892 pub struct SymbolStr {
1893     string: &'static str,
1894 }
1895
1896 // This impl allows a `SymbolStr` to be directly equated with a `String` or
1897 // `&str`.
1898 impl<T: std::ops::Deref<Target = str>> std::cmp::PartialEq<T> for SymbolStr {
1899     fn eq(&self, other: &T) -> bool {
1900         self.string == other.deref()
1901     }
1902 }
1903
1904 impl !Send for SymbolStr {}
1905 impl !Sync for SymbolStr {}
1906
1907 /// This impl means that if `ss` is a `SymbolStr`:
1908 /// - `*ss` is a `str`;
1909 /// - `&*ss` is a `&str` (and `match &*ss { ... }` is a common pattern).
1910 /// - `&ss as &str` is a `&str`, which means that `&ss` can be passed to a
1911 ///   function expecting a `&str`.
1912 impl std::ops::Deref for SymbolStr {
1913     type Target = str;
1914     #[inline]
1915     fn deref(&self) -> &str {
1916         self.string
1917     }
1918 }
1919
1920 impl fmt::Debug for SymbolStr {
1921     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1922         fmt::Debug::fmt(self.string, f)
1923     }
1924 }
1925
1926 impl fmt::Display for SymbolStr {
1927     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1928         fmt::Display::fmt(self.string, f)
1929     }
1930 }
1931
1932 impl<CTX> HashStable<CTX> for SymbolStr {
1933     #[inline]
1934     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1935         self.string.hash_stable(hcx, hasher)
1936     }
1937 }
1938
1939 impl<CTX> ToStableHashKey<CTX> for SymbolStr {
1940     type KeyType = SymbolStr;
1941
1942     #[inline]
1943     fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1944         self.clone()
1945     }
1946 }