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