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