]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_span/src/symbol.rs
Rollup merge of #91153 - birkenfeld:kernel_copy_fallback, r=the8472
[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         rustfmt,
1159         rvalue_static_promotion,
1160         s,
1161         sanitize,
1162         sanitizer_runtime,
1163         saturating_add,
1164         saturating_sub,
1165         self_in_typedefs,
1166         self_struct_ctor,
1167         semitransparent,
1168         shl,
1169         shl_assign,
1170         should_panic,
1171         shr,
1172         shr_assign,
1173         simd,
1174         simd_add,
1175         simd_and,
1176         simd_bitmask,
1177         simd_cast,
1178         simd_ceil,
1179         simd_div,
1180         simd_eq,
1181         simd_extract,
1182         simd_fabs,
1183         simd_fcos,
1184         simd_fexp,
1185         simd_fexp2,
1186         simd_ffi,
1187         simd_flog,
1188         simd_flog10,
1189         simd_flog2,
1190         simd_floor,
1191         simd_fma,
1192         simd_fmax,
1193         simd_fmin,
1194         simd_fpow,
1195         simd_fpowi,
1196         simd_fsin,
1197         simd_fsqrt,
1198         simd_gather,
1199         simd_ge,
1200         simd_gt,
1201         simd_insert,
1202         simd_le,
1203         simd_lt,
1204         simd_mul,
1205         simd_ne,
1206         simd_neg,
1207         simd_or,
1208         simd_reduce_add_ordered,
1209         simd_reduce_add_unordered,
1210         simd_reduce_all,
1211         simd_reduce_and,
1212         simd_reduce_any,
1213         simd_reduce_max,
1214         simd_reduce_max_nanless,
1215         simd_reduce_min,
1216         simd_reduce_min_nanless,
1217         simd_reduce_mul_ordered,
1218         simd_reduce_mul_unordered,
1219         simd_reduce_or,
1220         simd_reduce_xor,
1221         simd_rem,
1222         simd_round,
1223         simd_saturating_add,
1224         simd_saturating_sub,
1225         simd_scatter,
1226         simd_select,
1227         simd_select_bitmask,
1228         simd_shl,
1229         simd_shr,
1230         simd_shuffle,
1231         simd_sub,
1232         simd_trunc,
1233         simd_xor,
1234         since,
1235         sinf32,
1236         sinf64,
1237         size,
1238         size_of,
1239         size_of_val,
1240         sized,
1241         skip,
1242         slice,
1243         slice_alloc,
1244         slice_len_fn,
1245         slice_patterns,
1246         slice_u8,
1247         slice_u8_alloc,
1248         slicing_syntax,
1249         soft,
1250         specialization,
1251         speed,
1252         spotlight,
1253         sqrtf32,
1254         sqrtf64,
1255         sreg,
1256         sreg_low16,
1257         sse4a_target_feature,
1258         stable,
1259         staged_api,
1260         start,
1261         state,
1262         static_in_const,
1263         static_nobundle,
1264         static_recursion,
1265         staticlib,
1266         std,
1267         std_inject,
1268         std_panic,
1269         std_panic_2015_macro,
1270         std_panic_macro,
1271         stmt,
1272         stmt_expr_attributes,
1273         stop_after_dataflow,
1274         store,
1275         str,
1276         str_alloc,
1277         stringify,
1278         struct_field_attributes,
1279         struct_inherit,
1280         struct_variant,
1281         structural_match,
1282         structural_peq,
1283         structural_teq,
1284         sty,
1285         sub,
1286         sub_assign,
1287         sub_with_overflow,
1288         suggestion,
1289         sym,
1290         sync,
1291         t32,
1292         target_abi,
1293         target_arch,
1294         target_endian,
1295         target_env,
1296         target_family,
1297         target_feature,
1298         target_feature_11,
1299         target_has_atomic,
1300         target_has_atomic_equal_alignment,
1301         target_has_atomic_load_store,
1302         target_os,
1303         target_pointer_width,
1304         target_target_vendor,
1305         target_thread_local,
1306         target_vendor,
1307         task,
1308         tbm_target_feature,
1309         termination,
1310         termination_trait,
1311         termination_trait_test,
1312         test,
1313         test_2018_feature,
1314         test_accepted_feature,
1315         test_case,
1316         test_removed_feature,
1317         test_runner,
1318         then_with,
1319         thread,
1320         thread_local,
1321         tool_attributes,
1322         tool_lints,
1323         trace_macros,
1324         track_caller,
1325         trait_alias,
1326         trait_upcasting,
1327         transmute,
1328         transparent,
1329         transparent_enums,
1330         transparent_unions,
1331         trivial_bounds,
1332         truncf32,
1333         truncf64,
1334         try_blocks,
1335         try_from,
1336         try_into,
1337         try_trait_v2,
1338         tt,
1339         tuple,
1340         tuple_from_req,
1341         tuple_indexing,
1342         two_phase,
1343         ty,
1344         type_alias_enum_variants,
1345         type_alias_impl_trait,
1346         type_ascription,
1347         type_changing_struct_update,
1348         type_id,
1349         type_length_limit,
1350         type_macros,
1351         type_name,
1352         u128,
1353         u16,
1354         u32,
1355         u64,
1356         u8,
1357         unaligned_volatile_load,
1358         unaligned_volatile_store,
1359         unboxed_closures,
1360         unchecked_add,
1361         unchecked_div,
1362         unchecked_mul,
1363         unchecked_rem,
1364         unchecked_shl,
1365         unchecked_shr,
1366         unchecked_sub,
1367         underscore_const_names,
1368         underscore_imports,
1369         underscore_lifetimes,
1370         uniform_paths,
1371         unit,
1372         universal_impl_trait,
1373         unix,
1374         unlikely,
1375         unmarked_api,
1376         unpin,
1377         unreachable,
1378         unreachable_code,
1379         unrestricted_attribute_tokens,
1380         unsafe_block_in_unsafe_fn,
1381         unsafe_cell,
1382         unsafe_no_drop_flag,
1383         unsize,
1384         unsized_fn_params,
1385         unsized_locals,
1386         unsized_tuple_coercion,
1387         unstable,
1388         untagged_unions,
1389         unused_qualifications,
1390         unwind,
1391         unwind_attributes,
1392         unwind_safe_trait,
1393         unwrap,
1394         unwrap_or,
1395         use_extern_macros,
1396         use_nested_groups,
1397         used,
1398         usize,
1399         v1,
1400         va_arg,
1401         va_copy,
1402         va_end,
1403         va_list,
1404         va_start,
1405         val,
1406         var,
1407         variant_count,
1408         vec,
1409         version,
1410         vis,
1411         visible_private_types,
1412         volatile,
1413         volatile_copy_memory,
1414         volatile_copy_nonoverlapping_memory,
1415         volatile_load,
1416         volatile_set_memory,
1417         volatile_store,
1418         vreg,
1419         vreg_low16,
1420         warn,
1421         wasm_abi,
1422         wasm_import_module,
1423         wasm_target_feature,
1424         while_let,
1425         width,
1426         windows,
1427         windows_subsystem,
1428         wrapping_add,
1429         wrapping_mul,
1430         wrapping_sub,
1431         wreg,
1432         write_bytes,
1433         write_str,
1434         x87_reg,
1435         xer,
1436         xmm_reg,
1437         ymm_reg,
1438         zmm_reg,
1439     }
1440 }
1441
1442 #[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
1443 pub struct Ident {
1444     pub name: Symbol,
1445     pub span: Span,
1446 }
1447
1448 impl Ident {
1449     #[inline]
1450     /// Constructs a new identifier from a symbol and a span.
1451     pub const fn new(name: Symbol, span: Span) -> Ident {
1452         Ident { name, span }
1453     }
1454
1455     /// Constructs a new identifier with a dummy span.
1456     #[inline]
1457     pub const fn with_dummy_span(name: Symbol) -> Ident {
1458         Ident::new(name, DUMMY_SP)
1459     }
1460
1461     #[inline]
1462     pub fn empty() -> Ident {
1463         Ident::with_dummy_span(kw::Empty)
1464     }
1465
1466     /// Maps a string to an identifier with a dummy span.
1467     pub fn from_str(string: &str) -> Ident {
1468         Ident::with_dummy_span(Symbol::intern(string))
1469     }
1470
1471     /// Maps a string and a span to an identifier.
1472     pub fn from_str_and_span(string: &str, span: Span) -> Ident {
1473         Ident::new(Symbol::intern(string), span)
1474     }
1475
1476     /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
1477     pub fn with_span_pos(self, span: Span) -> Ident {
1478         Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
1479     }
1480
1481     pub fn without_first_quote(self) -> Ident {
1482         Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
1483     }
1484
1485     /// "Normalize" ident for use in comparisons using "item hygiene".
1486     /// Identifiers with same string value become same if they came from the same macro 2.0 macro
1487     /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
1488     /// different macro 2.0 macros.
1489     /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
1490     pub fn normalize_to_macros_2_0(self) -> Ident {
1491         Ident::new(self.name, self.span.normalize_to_macros_2_0())
1492     }
1493
1494     /// "Normalize" ident for use in comparisons using "local variable hygiene".
1495     /// Identifiers with same string value become same if they came from the same non-transparent
1496     /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
1497     /// non-transparent macros.
1498     /// Technically, this operation strips all transparent marks from ident's syntactic context.
1499     pub fn normalize_to_macro_rules(self) -> Ident {
1500         Ident::new(self.name, self.span.normalize_to_macro_rules())
1501     }
1502
1503     /// Convert the name to a `SymbolStr`. This is a slowish operation because
1504     /// it requires locking the symbol interner.
1505     pub fn as_str(self) -> SymbolStr {
1506         self.name.as_str()
1507     }
1508 }
1509
1510 impl PartialEq for Ident {
1511     fn eq(&self, rhs: &Self) -> bool {
1512         self.name == rhs.name && self.span.ctxt() == rhs.span.ctxt()
1513     }
1514 }
1515
1516 impl Hash for Ident {
1517     fn hash<H: Hasher>(&self, state: &mut H) {
1518         self.name.hash(state);
1519         self.span.ctxt().hash(state);
1520     }
1521 }
1522
1523 impl fmt::Debug for Ident {
1524     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1525         fmt::Display::fmt(self, f)?;
1526         fmt::Debug::fmt(&self.span.ctxt(), f)
1527     }
1528 }
1529
1530 /// This implementation is supposed to be used in error messages, so it's expected to be identical
1531 /// to printing the original identifier token written in source code (`token_to_string`),
1532 /// except that AST identifiers don't keep the rawness flag, so we have to guess it.
1533 impl fmt::Display for Ident {
1534     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1535         fmt::Display::fmt(&IdentPrinter::new(self.name, self.is_raw_guess(), None), f)
1536     }
1537 }
1538
1539 /// This is the most general way to print identifiers.
1540 /// AST pretty-printer is used as a fallback for turning AST structures into token streams for
1541 /// proc macros. Additionally, proc macros may stringify their input and expect it survive the
1542 /// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
1543 /// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
1544 /// hygiene data, most importantly name of the crate it refers to.
1545 /// As a result we print `$crate` as `crate` if it refers to the local crate
1546 /// and as `::other_crate_name` if it refers to some other crate.
1547 /// Note, that this is only done if the ident token is printed from inside of AST pretty-pringing,
1548 /// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
1549 /// so we should not perform this lossy conversion if the top level call to the pretty-printer was
1550 /// done for a token stream or a single token.
1551 pub struct IdentPrinter {
1552     symbol: Symbol,
1553     is_raw: bool,
1554     /// Span used for retrieving the crate name to which `$crate` refers to,
1555     /// if this field is `None` then the `$crate` conversion doesn't happen.
1556     convert_dollar_crate: Option<Span>,
1557 }
1558
1559 impl IdentPrinter {
1560     /// The most general `IdentPrinter` constructor. Do not use this.
1561     pub fn new(symbol: Symbol, is_raw: bool, convert_dollar_crate: Option<Span>) -> IdentPrinter {
1562         IdentPrinter { symbol, is_raw, convert_dollar_crate }
1563     }
1564
1565     /// This implementation is supposed to be used when printing identifiers
1566     /// as a part of pretty-printing for larger AST pieces.
1567     /// Do not use this either.
1568     pub fn for_ast_ident(ident: Ident, is_raw: bool) -> IdentPrinter {
1569         IdentPrinter::new(ident.name, is_raw, Some(ident.span))
1570     }
1571 }
1572
1573 impl fmt::Display for IdentPrinter {
1574     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1575         if self.is_raw {
1576             f.write_str("r#")?;
1577         } else if self.symbol == kw::DollarCrate {
1578             if let Some(span) = self.convert_dollar_crate {
1579                 let converted = span.ctxt().dollar_crate_name();
1580                 if !converted.is_path_segment_keyword() {
1581                     f.write_str("::")?;
1582                 }
1583                 return fmt::Display::fmt(&converted, f);
1584             }
1585         }
1586         fmt::Display::fmt(&self.symbol, f)
1587     }
1588 }
1589
1590 /// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
1591 /// construction.
1592 // FIXME(matthewj, petrochenkov) Use this more often, add a similar
1593 // `ModernIdent` struct and use that as well.
1594 #[derive(Copy, Clone, Eq, PartialEq, Hash)]
1595 pub struct MacroRulesNormalizedIdent(Ident);
1596
1597 impl MacroRulesNormalizedIdent {
1598     pub fn new(ident: Ident) -> Self {
1599         Self(ident.normalize_to_macro_rules())
1600     }
1601 }
1602
1603 impl fmt::Debug for MacroRulesNormalizedIdent {
1604     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1605         fmt::Debug::fmt(&self.0, f)
1606     }
1607 }
1608
1609 impl fmt::Display for MacroRulesNormalizedIdent {
1610     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1611         fmt::Display::fmt(&self.0, f)
1612     }
1613 }
1614
1615 /// An interned string.
1616 ///
1617 /// Internally, a `Symbol` is implemented as an index, and all operations
1618 /// (including hashing, equality, and ordering) operate on that index. The use
1619 /// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
1620 /// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
1621 ///
1622 /// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
1623 /// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
1624 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1625 pub struct Symbol(SymbolIndex);
1626
1627 rustc_index::newtype_index! {
1628     struct SymbolIndex { .. }
1629 }
1630
1631 impl Symbol {
1632     const fn new(n: u32) -> Self {
1633         Symbol(SymbolIndex::from_u32(n))
1634     }
1635
1636     /// Maps a string to its interned representation.
1637     pub fn intern(string: &str) -> Self {
1638         with_session_globals(|session_globals| session_globals.symbol_interner.intern(string))
1639     }
1640
1641     /// Convert to a `SymbolStr`. This is a slowish operation because it
1642     /// requires locking the symbol interner.
1643     pub fn as_str(self) -> SymbolStr {
1644         with_session_globals(|session_globals| {
1645             let symbol_str = session_globals.symbol_interner.get(self);
1646             unsafe { SymbolStr { string: std::mem::transmute::<&str, &str>(symbol_str) } }
1647         })
1648     }
1649
1650     pub fn as_u32(self) -> u32 {
1651         self.0.as_u32()
1652     }
1653
1654     pub fn is_empty(self) -> bool {
1655         self == kw::Empty
1656     }
1657
1658     /// This method is supposed to be used in error messages, so it's expected to be
1659     /// identical to printing the original identifier token written in source code
1660     /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
1661     /// or edition, so we have to guess the rawness using the global edition.
1662     pub fn to_ident_string(self) -> String {
1663         Ident::with_dummy_span(self).to_string()
1664     }
1665 }
1666
1667 impl fmt::Debug for Symbol {
1668     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1669         fmt::Debug::fmt(&self.as_str(), f)
1670     }
1671 }
1672
1673 impl fmt::Display for Symbol {
1674     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1675         fmt::Display::fmt(&self.as_str(), f)
1676     }
1677 }
1678
1679 impl<S: Encoder> Encodable<S> for Symbol {
1680     fn encode(&self, s: &mut S) -> Result<(), S::Error> {
1681         s.emit_str(&self.as_str())
1682     }
1683 }
1684
1685 impl<D: Decoder> Decodable<D> for Symbol {
1686     #[inline]
1687     fn decode(d: &mut D) -> Result<Symbol, D::Error> {
1688         Ok(Symbol::intern(&d.read_str()?))
1689     }
1690 }
1691
1692 impl<CTX> HashStable<CTX> for Symbol {
1693     #[inline]
1694     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1695         self.as_str().hash_stable(hcx, hasher);
1696     }
1697 }
1698
1699 impl<CTX> ToStableHashKey<CTX> for Symbol {
1700     type KeyType = SymbolStr;
1701
1702     #[inline]
1703     fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1704         self.as_str()
1705     }
1706 }
1707
1708 #[derive(Default)]
1709 pub(crate) struct Interner(Lock<InternerInner>);
1710
1711 // The `&'static str`s in this type actually point into the arena.
1712 //
1713 // The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
1714 // found that to regress performance up to 2% in some cases. This might be
1715 // revisited after further improvements to `indexmap`.
1716 //
1717 // This type is private to prevent accidentally constructing more than one `Interner` on the same
1718 // thread, which makes it easy to mixup `Symbol`s between `Interner`s.
1719 #[derive(Default)]
1720 struct InternerInner {
1721     arena: DroplessArena,
1722     names: FxHashMap<&'static str, Symbol>,
1723     strings: Vec<&'static str>,
1724 }
1725
1726 impl Interner {
1727     fn prefill(init: &[&'static str]) -> Self {
1728         Interner(Lock::new(InternerInner {
1729             strings: init.into(),
1730             names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
1731             ..Default::default()
1732         }))
1733     }
1734
1735     #[inline]
1736     fn intern(&self, string: &str) -> Symbol {
1737         let mut inner = self.0.lock();
1738         if let Some(&name) = inner.names.get(string) {
1739             return name;
1740         }
1741
1742         let name = Symbol::new(inner.strings.len() as u32);
1743
1744         // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
1745         // UTF-8.
1746         let string: &str =
1747             unsafe { str::from_utf8_unchecked(inner.arena.alloc_slice(string.as_bytes())) };
1748         // It is safe to extend the arena allocation to `'static` because we only access
1749         // these while the arena is still alive.
1750         let string: &'static str = unsafe { &*(string as *const str) };
1751         inner.strings.push(string);
1752         inner.names.insert(string, name);
1753         name
1754     }
1755
1756     // Get the symbol as a string. `Symbol::as_str()` should be used in
1757     // preference to this function.
1758     fn get(&self, symbol: Symbol) -> &str {
1759         self.0.lock().strings[symbol.0.as_usize()]
1760     }
1761 }
1762
1763 // This module has a very short name because it's used a lot.
1764 /// This module contains all the defined keyword `Symbol`s.
1765 ///
1766 /// Given that `kw` is imported, use them like `kw::keyword_name`.
1767 /// For example `kw::Loop` or `kw::Break`.
1768 pub mod kw {
1769     pub use super::kw_generated::*;
1770 }
1771
1772 // This module has a very short name because it's used a lot.
1773 /// This module contains all the defined non-keyword `Symbol`s.
1774 ///
1775 /// Given that `sym` is imported, use them like `sym::symbol_name`.
1776 /// For example `sym::rustfmt` or `sym::u8`.
1777 pub mod sym {
1778     use super::Symbol;
1779     use std::convert::TryInto;
1780
1781     #[doc(inline)]
1782     pub use super::sym_generated::*;
1783
1784     // Used from a macro in `librustc_feature/accepted.rs`
1785     pub use super::kw::MacroRules as macro_rules;
1786
1787     /// Get the symbol for an integer.
1788     ///
1789     /// The first few non-negative integers each have a static symbol and therefore
1790     /// are fast.
1791     pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
1792         if let Result::Ok(idx) = n.try_into() {
1793             if idx < 10 {
1794                 return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
1795             }
1796         }
1797         Symbol::intern(&n.to_string())
1798     }
1799 }
1800
1801 impl Symbol {
1802     fn is_special(self) -> bool {
1803         self <= kw::Underscore
1804     }
1805
1806     fn is_used_keyword_always(self) -> bool {
1807         self >= kw::As && self <= kw::While
1808     }
1809
1810     fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1811         (self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
1812     }
1813
1814     fn is_unused_keyword_always(self) -> bool {
1815         self >= kw::Abstract && self <= kw::Yield
1816     }
1817
1818     fn is_unused_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1819         self == kw::Try && edition() >= Edition::Edition2018
1820     }
1821
1822     pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
1823         self.is_special()
1824             || self.is_used_keyword_always()
1825             || self.is_unused_keyword_always()
1826             || self.is_used_keyword_conditional(edition)
1827             || self.is_unused_keyword_conditional(edition)
1828     }
1829
1830     /// A keyword or reserved identifier that can be used as a path segment.
1831     pub fn is_path_segment_keyword(self) -> bool {
1832         self == kw::Super
1833             || self == kw::SelfLower
1834             || self == kw::SelfUpper
1835             || self == kw::Crate
1836             || self == kw::PathRoot
1837             || self == kw::DollarCrate
1838     }
1839
1840     /// Returns `true` if the symbol is `true` or `false`.
1841     pub fn is_bool_lit(self) -> bool {
1842         self == kw::True || self == kw::False
1843     }
1844
1845     /// Returns `true` if this symbol can be a raw identifier.
1846     pub fn can_be_raw(self) -> bool {
1847         self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword()
1848     }
1849 }
1850
1851 impl Ident {
1852     // Returns `true` for reserved identifiers used internally for elided lifetimes,
1853     // unnamed method parameters, crate root module, error recovery etc.
1854     pub fn is_special(self) -> bool {
1855         self.name.is_special()
1856     }
1857
1858     /// Returns `true` if the token is a keyword used in the language.
1859     pub fn is_used_keyword(self) -> bool {
1860         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1861         self.name.is_used_keyword_always()
1862             || self.name.is_used_keyword_conditional(|| self.span.edition())
1863     }
1864
1865     /// Returns `true` if the token is a keyword reserved for possible future use.
1866     pub fn is_unused_keyword(self) -> bool {
1867         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1868         self.name.is_unused_keyword_always()
1869             || self.name.is_unused_keyword_conditional(|| self.span.edition())
1870     }
1871
1872     /// Returns `true` if the token is either a special identifier or a keyword.
1873     pub fn is_reserved(self) -> bool {
1874         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1875         self.name.is_reserved(|| self.span.edition())
1876     }
1877
1878     /// A keyword or reserved identifier that can be used as a path segment.
1879     pub fn is_path_segment_keyword(self) -> bool {
1880         self.name.is_path_segment_keyword()
1881     }
1882
1883     /// We see this identifier in a normal identifier position, like variable name or a type.
1884     /// How was it written originally? Did it use the raw form? Let's try to guess.
1885     pub fn is_raw_guess(self) -> bool {
1886         self.name.can_be_raw() && self.is_reserved()
1887     }
1888 }
1889
1890 /// An alternative to [`Symbol`], useful when the chars within the symbol need to
1891 /// be accessed. It deliberately has limited functionality and should only be
1892 /// used for temporary values.
1893 ///
1894 /// Because the interner outlives any thread which uses this type, we can
1895 /// safely treat `string` which points to interner data, as an immortal string,
1896 /// as long as this type never crosses between threads.
1897 //
1898 // FIXME: ensure that the interner outlives any thread which uses `SymbolStr`,
1899 // by creating a new thread right after constructing the interner.
1900 #[derive(Clone, Eq, PartialOrd, Ord)]
1901 pub struct SymbolStr {
1902     string: &'static str,
1903 }
1904
1905 // This impl allows a `SymbolStr` to be directly equated with a `String` or
1906 // `&str`.
1907 impl<T: std::ops::Deref<Target = str>> std::cmp::PartialEq<T> for SymbolStr {
1908     fn eq(&self, other: &T) -> bool {
1909         self.string == other.deref()
1910     }
1911 }
1912
1913 impl !Send for SymbolStr {}
1914 impl !Sync for SymbolStr {}
1915
1916 /// This impl means that if `ss` is a `SymbolStr`:
1917 /// - `*ss` is a `str`;
1918 /// - `&*ss` is a `&str` (and `match &*ss { ... }` is a common pattern).
1919 /// - `&ss as &str` is a `&str`, which means that `&ss` can be passed to a
1920 ///   function expecting a `&str`.
1921 impl std::ops::Deref for SymbolStr {
1922     type Target = str;
1923     #[inline]
1924     fn deref(&self) -> &str {
1925         self.string
1926     }
1927 }
1928
1929 impl fmt::Debug for SymbolStr {
1930     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1931         fmt::Debug::fmt(self.string, f)
1932     }
1933 }
1934
1935 impl fmt::Display for SymbolStr {
1936     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1937         fmt::Display::fmt(self.string, f)
1938     }
1939 }
1940
1941 impl<CTX> HashStable<CTX> for SymbolStr {
1942     #[inline]
1943     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1944         self.string.hash_stable(hcx, hasher)
1945     }
1946 }
1947
1948 impl<CTX> ToStableHashKey<CTX> for SymbolStr {
1949     type KeyType = SymbolStr;
1950
1951     #[inline]
1952     fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1953         self.clone()
1954     }
1955 }