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