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