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