]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_span/src/symbol.rs
Suggestion to wrap inner types using `allocator_api` in tuple
[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         _args,
275         _d,
276         _e,
277         _task_context,
278         a32,
279         aarch64_target_feature,
280         abi,
281         abi_amdgpu_kernel,
282         abi_avr_interrupt,
283         abi_c_cmse_nonsecure_call,
284         abi_efiapi,
285         abi_msp430_interrupt,
286         abi_ptx,
287         abi_sysv64,
288         abi_thiscall,
289         abi_unadjusted,
290         abi_vectorcall,
291         abi_x86_interrupt,
292         abort,
293         aborts,
294         add,
295         add_assign,
296         add_with_overflow,
297         address,
298         adt_const_params,
299         advanced_slice_patterns,
300         adx_target_feature,
301         alias,
302         align,
303         align_offset,
304         alignstack,
305         all,
306         alloc,
307         alloc_error_handler,
308         alloc_layout,
309         alloc_zeroed,
310         allocator,
311         allocator_api,
312         allocator_internals,
313         allow,
314         allow_fail,
315         allow_internal_unsafe,
316         allow_internal_unstable,
317         allowed,
318         always,
319         and,
320         and_then,
321         any,
322         arbitrary_enum_discriminant,
323         arbitrary_self_types,
324         arith_offset,
325         arm,
326         arm_target_feature,
327         array,
328         arrays,
329         as_ptr,
330         as_str,
331         asm,
332         asm_const,
333         asm_experimental_arch,
334         asm_sym,
335         assert,
336         assert_inhabited,
337         assert_macro,
338         assert_receiver_is_total_eq,
339         assert_uninit_valid,
340         assert_zero_valid,
341         associated_consts,
342         associated_type_bounds,
343         associated_type_defaults,
344         associated_types,
345         assume,
346         assume_init,
347         async_await,
348         async_closure,
349         atomic,
350         atomic_mod,
351         atomics,
352         att_syntax,
353         attr,
354         attr_literals,
355         attributes,
356         augmented_assignments,
357         auto_traits,
358         automatically_derived,
359         avx512_target_feature,
360         await_macro,
361         bang,
362         begin_panic,
363         bench,
364         bin,
365         bind_by_move_pattern_guards,
366         bindings_after_at,
367         bitand,
368         bitand_assign,
369         bitor,
370         bitor_assign,
371         bitreverse,
372         bitxor,
373         bitxor_assign,
374         black_box,
375         block,
376         bool,
377         borrowck_graphviz_format,
378         borrowck_graphviz_postflow,
379         borrowck_graphviz_preflow,
380         box_free,
381         box_patterns,
382         box_syntax,
383         bpf_target_feature,
384         braced_empty_structs,
385         branch,
386         breakpoint,
387         bridge,
388         bswap,
389         c_str,
390         c_unwind,
391         c_variadic,
392         call,
393         call_mut,
394         call_once,
395         caller_location,
396         capture_disjoint_fields,
397         cdylib,
398         ceilf32,
399         ceilf64,
400         cfg,
401         cfg_accessible,
402         cfg_attr,
403         cfg_attr_multi,
404         cfg_doctest,
405         cfg_eval,
406         cfg_hide,
407         cfg_panic,
408         cfg_sanitize,
409         cfg_target_abi,
410         cfg_target_feature,
411         cfg_target_has_atomic,
412         cfg_target_thread_local,
413         cfg_target_vendor,
414         cfg_version,
415         cfi,
416         char,
417         client,
418         clippy,
419         clobber_abi,
420         clone,
421         clone_closures,
422         clone_from,
423         closure,
424         closure_to_fn_coercion,
425         closure_track_caller,
426         cmp,
427         cmp_max,
428         cmp_min,
429         cmpxchg16b_target_feature,
430         cmse_nonsecure_entry,
431         coerce_unsized,
432         cold,
433         column,
434         compare_and_swap,
435         compare_exchange,
436         compare_exchange_weak,
437         compile_error,
438         compiler_builtins,
439         compiler_fence,
440         concat,
441         concat_idents,
442         conservative_impl_trait,
443         console,
444         const_allocate,
445         const_async_blocks,
446         const_compare_raw_pointers,
447         const_constructor,
448         const_eval_limit,
449         const_eval_select,
450         const_eval_select_ct,
451         const_evaluatable_checked,
452         const_extern_fn,
453         const_fn,
454         const_fn_floating_point_arithmetic,
455         const_fn_fn_ptr_basics,
456         const_fn_trait_bound,
457         const_fn_transmute,
458         const_fn_union,
459         const_fn_unsize,
460         const_for,
461         const_format_args,
462         const_generic_defaults,
463         const_generics,
464         const_generics_defaults,
465         const_if_match,
466         const_impl_trait,
467         const_in_array_repeat_expressions,
468         const_indexing,
469         const_let,
470         const_loop,
471         const_mut_refs,
472         const_panic,
473         const_panic_fmt,
474         const_precise_live_drops,
475         const_ptr,
476         const_raw_ptr_deref,
477         const_raw_ptr_to_usize_cast,
478         const_refs_to_cell,
479         const_slice_ptr,
480         const_trait_bound_opt_out,
481         const_trait_impl,
482         const_transmute,
483         const_try,
484         constant,
485         constructor,
486         contents,
487         context,
488         convert,
489         copy,
490         copy_closures,
491         copy_nonoverlapping,
492         copysignf32,
493         copysignf64,
494         core,
495         core_intrinsics,
496         core_panic,
497         core_panic_2015_macro,
498         core_panic_macro,
499         cosf32,
500         cosf64,
501         cr,
502         crate_id,
503         crate_in_paths,
504         crate_local,
505         crate_name,
506         crate_type,
507         crate_visibility_modifier,
508         crt_dash_static: "crt-static",
509         cstring_type,
510         ctlz,
511         ctlz_nonzero,
512         ctpop,
513         cttz,
514         cttz_nonzero,
515         custom_attribute,
516         custom_derive,
517         custom_inner_attributes,
518         custom_test_frameworks,
519         d,
520         dead_code,
521         dealloc,
522         debug,
523         debug_assert_macro,
524         debug_assertions,
525         debug_struct,
526         debug_trait_builder,
527         debug_tuple,
528         decl_macro,
529         declare_lint_pass,
530         decode,
531         default_alloc_error_handler,
532         default_lib_allocator,
533         default_method_body_is_const,
534         default_type_parameter_fallback,
535         default_type_params,
536         delay_span_bug_from_inside_query,
537         deny,
538         deprecated,
539         deref,
540         deref_method,
541         deref_mut,
542         deref_target,
543         derive,
544         derive_default_enum,
545         destructuring_assignment,
546         diagnostic,
547         direct,
548         discriminant_kind,
549         discriminant_type,
550         discriminant_value,
551         dispatch_from_dyn,
552         display_trait,
553         div,
554         div_assign,
555         doc,
556         doc_alias,
557         doc_auto_cfg,
558         doc_cfg,
559         doc_cfg_hide,
560         doc_keyword,
561         doc_masked,
562         doc_notable_trait,
563         doc_primitive,
564         doc_spotlight,
565         doctest,
566         document_private_items,
567         dotdot_in_tuple_patterns,
568         dotdoteq_in_patterns,
569         dreg,
570         dreg_low16,
571         dreg_low8,
572         drop,
573         drop_in_place,
574         drop_types_in_const,
575         dropck_eyepatch,
576         dropck_parametricity,
577         dylib,
578         dyn_metadata,
579         dyn_trait,
580         edition_macro_pats,
581         edition_panic,
582         eh_catch_typeinfo,
583         eh_personality,
584         emit_enum,
585         emit_enum_variant,
586         emit_enum_variant_arg,
587         emit_struct,
588         emit_struct_field,
589         enable,
590         enclosing_scope,
591         encode,
592         env,
593         eq,
594         ermsb_target_feature,
595         exact_div,
596         except,
597         exchange_malloc,
598         exclusive_range_pattern,
599         exhaustive_integer_patterns,
600         exhaustive_patterns,
601         existential_type,
602         exp2f32,
603         exp2f64,
604         expect,
605         expected,
606         expf32,
607         expf64,
608         explicit_generic_args_with_impl_trait,
609         export_name,
610         expr,
611         extended_key_value_attributes,
612         extern_absolute_paths,
613         extern_crate_item_prelude,
614         extern_crate_self,
615         extern_in_paths,
616         extern_prelude,
617         extern_types,
618         external_doc,
619         f,
620         f16c_target_feature,
621         f32,
622         f32_runtime,
623         f64,
624         f64_runtime,
625         fabsf32,
626         fabsf64,
627         fadd_fast,
628         fdiv_fast,
629         feature,
630         fence,
631         fetch_update,
632         ffi,
633         ffi_const,
634         ffi_pure,
635         ffi_returns_twice,
636         field,
637         field_init_shorthand,
638         file,
639         fill,
640         finish,
641         flags,
642         float_to_int_unchecked,
643         floorf32,
644         floorf64,
645         fmaf32,
646         fmaf64,
647         fmt,
648         fmt_as_str,
649         fmt_internals,
650         fmul_fast,
651         fn_align,
652         fn_must_use,
653         fn_mut,
654         fn_once,
655         fn_once_output,
656         forbid,
657         forget,
658         format,
659         format_args,
660         format_args_capture,
661         format_args_nl,
662         format_macro,
663         freeze,
664         freg,
665         frem_fast,
666         from,
667         from_desugaring,
668         from_generator,
669         from_iter,
670         from_method,
671         from_output,
672         from_residual,
673         from_size_align_unchecked,
674         from_usize,
675         fsub_fast,
676         fundamental,
677         future,
678         future_trait,
679         ge,
680         gen_future,
681         gen_kill,
682         generator,
683         generator_state,
684         generators,
685         generic_arg_infer,
686         generic_associated_types,
687         generic_const_exprs,
688         generic_param_attrs,
689         get_context,
690         global_allocator,
691         global_asm,
692         globs,
693         gt,
694         half_open_range_patterns,
695         hash,
696         hexagon_target_feature,
697         hidden,
698         homogeneous_aggregate,
699         html_favicon_url,
700         html_logo_url,
701         html_no_source,
702         html_playground_url,
703         html_root_url,
704         hwaddress,
705         i,
706         i128,
707         i128_type,
708         i16,
709         i32,
710         i64,
711         i8,
712         ident,
713         if_let,
714         if_let_guard,
715         if_while_or_patterns,
716         ignore,
717         impl_header_lifetime_elision,
718         impl_lint_pass,
719         impl_macros,
720         impl_trait_in_bindings,
721         import_shadowing,
722         imported_main,
723         in_band_lifetimes,
724         include,
725         include_bytes,
726         include_str,
727         inclusive_range_syntax,
728         index,
729         index_mut,
730         infer_outlives_requirements,
731         infer_static_outlives_requirements,
732         inherent_associated_types,
733         inlateout,
734         inline,
735         inline_const,
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_synthetic,
1153         rustc_test_marker,
1154         rustc_then_this_would_need,
1155         rustc_trivial_field_reads,
1156         rustc_unsafe_specialization_marker,
1157         rustc_variance,
1158         rustdoc,
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 }