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