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