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