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