]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_span/src/symbol.rs
Rollup merge of #81465 - joshtriplett:duration-formatting-documentation, r=m-ou-se
[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         minnumf32,
740         minnumf64,
741         mips_target_feature,
742         misc,
743         module,
744         module_path,
745         more_struct_aliases,
746         movbe_target_feature,
747         move_ref_pattern,
748         mul,
749         mul_assign,
750         mul_with_overflow,
751         must_use,
752         mut_ptr,
753         mut_slice_ptr,
754         naked,
755         naked_functions,
756         name,
757         ne,
758         nearbyintf32,
759         nearbyintf64,
760         needs_allocator,
761         needs_drop,
762         needs_panic_runtime,
763         neg,
764         negate_unsigned,
765         negative_impls,
766         never,
767         never_type,
768         never_type_fallback,
769         new,
770         new_unchecked,
771         next,
772         nll,
773         no,
774         no_builtins,
775         no_core,
776         no_crate_inject,
777         no_debug,
778         no_default_passes,
779         no_implicit_prelude,
780         no_inline,
781         no_link,
782         no_main,
783         no_mangle,
784         no_niche,
785         no_sanitize,
786         no_stack_check,
787         no_start,
788         no_std,
789         nomem,
790         non_ascii_idents,
791         non_exhaustive,
792         non_modrs_mods,
793         none_error,
794         nontemporal_store,
795         nontrapping_dash_fptoint: "nontrapping-fptoint",
796         noop_method_borrow,
797         noop_method_clone,
798         noop_method_deref,
799         noreturn,
800         nostack,
801         not,
802         note,
803         object_safe_for_dispatch,
804         of,
805         offset,
806         omit_gdb_pretty_printer_section,
807         on,
808         on_unimplemented,
809         oom,
810         opaque,
811         ops,
812         opt_out_copy,
813         optimize,
814         optimize_attribute,
815         optin_builtin_traits,
816         option,
817         option_env,
818         option_type,
819         options,
820         or,
821         or_patterns,
822         other,
823         out,
824         overlapping_marker_traits,
825         owned_box,
826         packed,
827         panic,
828         panic_2015,
829         panic_2021,
830         panic_abort,
831         panic_bounds_check,
832         panic_handler,
833         panic_impl,
834         panic_implementation,
835         panic_info,
836         panic_location,
837         panic_runtime,
838         panic_str,
839         panic_unwind,
840         panicking,
841         param_attrs,
842         parent_trait,
843         partial_cmp,
844         partial_ord,
845         passes,
846         pat,
847         pat2018,
848         pat2021,
849         path,
850         pattern_parentheses,
851         phantom_data,
852         pin,
853         pinned,
854         platform_intrinsics,
855         plugin,
856         plugin_registrar,
857         plugins,
858         pointee_trait,
859         pointer,
860         pointer_trait,
861         pointer_trait_fmt,
862         poll,
863         position,
864         post_dash_lto: "post-lto",
865         powerpc_target_feature,
866         powf32,
867         powf64,
868         powif32,
869         powif64,
870         pre_dash_lto: "pre-lto",
871         precise_pointer_size_matching,
872         precision,
873         pref_align_of,
874         prefetch_read_data,
875         prefetch_read_instruction,
876         prefetch_write_data,
877         prefetch_write_instruction,
878         prelude,
879         prelude_import,
880         preserves_flags,
881         primitive,
882         proc_dash_macro: "proc-macro",
883         proc_macro,
884         proc_macro_attribute,
885         proc_macro_def_site,
886         proc_macro_derive,
887         proc_macro_expr,
888         proc_macro_gen,
889         proc_macro_hygiene,
890         proc_macro_internals,
891         proc_macro_mod,
892         proc_macro_non_items,
893         proc_macro_path_invoc,
894         profiler_builtins,
895         profiler_runtime,
896         ptr_guaranteed_eq,
897         ptr_guaranteed_ne,
898         ptr_offset_from,
899         pub_macro_rules,
900         pub_restricted,
901         pure,
902         pushpop_unsafe,
903         qreg,
904         qreg_low4,
905         qreg_low8,
906         quad_precision_float,
907         question_mark,
908         quote,
909         range_inclusive_new,
910         raw_dylib,
911         raw_identifiers,
912         raw_ref_op,
913         re_rebalance_coherence,
914         read_enum,
915         read_enum_variant,
916         read_enum_variant_arg,
917         read_struct,
918         read_struct_field,
919         readonly,
920         realloc,
921         reason,
922         receiver,
923         recursion_limit,
924         reexport_test_harness_main,
925         reference,
926         reflect,
927         reg,
928         reg16,
929         reg32,
930         reg64,
931         reg_abcd,
932         reg_byte,
933         reg_thumb,
934         register_attr,
935         register_tool,
936         relaxed_adts,
937         relaxed_struct_unsize,
938         rem,
939         rem_assign,
940         repr,
941         repr128,
942         repr_align,
943         repr_align_enum,
944         repr_no_niche,
945         repr_packed,
946         repr_simd,
947         repr_transparent,
948         result,
949         result_type,
950         rhs,
951         rintf32,
952         rintf64,
953         riscv_target_feature,
954         rlib,
955         rotate_left,
956         rotate_right,
957         roundf32,
958         roundf64,
959         rt,
960         rtm_target_feature,
961         rust,
962         rust_2015,
963         rust_2015_preview,
964         rust_2018,
965         rust_2018_preview,
966         rust_2021,
967         rust_2021_preview,
968         rust_begin_unwind,
969         rust_eh_catch_typeinfo,
970         rust_eh_personality,
971         rust_eh_register_frames,
972         rust_eh_unregister_frames,
973         rust_oom,
974         rustc,
975         rustc_allocator,
976         rustc_allocator_nounwind,
977         rustc_allow_const_fn_unstable,
978         rustc_args_required_const,
979         rustc_attrs,
980         rustc_builtin_macro,
981         rustc_capture_analysis,
982         rustc_clean,
983         rustc_const_stable,
984         rustc_const_unstable,
985         rustc_conversion_suggestion,
986         rustc_def_path,
987         rustc_deprecated,
988         rustc_diagnostic_item,
989         rustc_diagnostic_macros,
990         rustc_dirty,
991         rustc_dummy,
992         rustc_dump_env_program_clauses,
993         rustc_dump_program_clauses,
994         rustc_dump_user_substs,
995         rustc_error,
996         rustc_expected_cgu_reuse,
997         rustc_if_this_changed,
998         rustc_inherit_overflow_checks,
999         rustc_layout,
1000         rustc_layout_scalar_valid_range_end,
1001         rustc_layout_scalar_valid_range_start,
1002         rustc_legacy_const_generics,
1003         rustc_macro_transparency,
1004         rustc_mir,
1005         rustc_nonnull_optimization_guaranteed,
1006         rustc_object_lifetime_default,
1007         rustc_on_unimplemented,
1008         rustc_outlives,
1009         rustc_paren_sugar,
1010         rustc_partition_codegened,
1011         rustc_partition_reused,
1012         rustc_peek,
1013         rustc_peek_definite_init,
1014         rustc_peek_indirectly_mutable,
1015         rustc_peek_liveness,
1016         rustc_peek_maybe_init,
1017         rustc_peek_maybe_uninit,
1018         rustc_polymorphize_error,
1019         rustc_private,
1020         rustc_proc_macro_decls,
1021         rustc_promotable,
1022         rustc_regions,
1023         rustc_reservation_impl,
1024         rustc_serialize,
1025         rustc_specialization_trait,
1026         rustc_stable,
1027         rustc_std_internal_symbol,
1028         rustc_symbol_name,
1029         rustc_synthetic,
1030         rustc_test_marker,
1031         rustc_then_this_would_need,
1032         rustc_unsafe_specialization_marker,
1033         rustc_variance,
1034         rustdoc,
1035         rustfmt,
1036         rvalue_static_promotion,
1037         sanitize,
1038         sanitizer_runtime,
1039         saturating_add,
1040         saturating_sub,
1041         self_in_typedefs,
1042         self_struct_ctor,
1043         semitransparent,
1044         send_trait,
1045         shl,
1046         shl_assign,
1047         should_panic,
1048         shr,
1049         shr_assign,
1050         simd,
1051         simd_add,
1052         simd_and,
1053         simd_bitmask,
1054         simd_cast,
1055         simd_ceil,
1056         simd_div,
1057         simd_eq,
1058         simd_extract,
1059         simd_fabs,
1060         simd_fcos,
1061         simd_fexp,
1062         simd_fexp2,
1063         simd_ffi,
1064         simd_flog,
1065         simd_flog10,
1066         simd_flog2,
1067         simd_floor,
1068         simd_fma,
1069         simd_fmax,
1070         simd_fmin,
1071         simd_fpow,
1072         simd_fpowi,
1073         simd_fsin,
1074         simd_fsqrt,
1075         simd_gather,
1076         simd_ge,
1077         simd_gt,
1078         simd_insert,
1079         simd_le,
1080         simd_lt,
1081         simd_mul,
1082         simd_ne,
1083         simd_or,
1084         simd_reduce_add_ordered,
1085         simd_reduce_add_unordered,
1086         simd_reduce_all,
1087         simd_reduce_and,
1088         simd_reduce_any,
1089         simd_reduce_max,
1090         simd_reduce_max_nanless,
1091         simd_reduce_min,
1092         simd_reduce_min_nanless,
1093         simd_reduce_mul_ordered,
1094         simd_reduce_mul_unordered,
1095         simd_reduce_or,
1096         simd_reduce_xor,
1097         simd_rem,
1098         simd_saturating_add,
1099         simd_saturating_sub,
1100         simd_scatter,
1101         simd_select,
1102         simd_select_bitmask,
1103         simd_shl,
1104         simd_shr,
1105         simd_sub,
1106         simd_xor,
1107         since,
1108         sinf32,
1109         sinf64,
1110         size,
1111         size_of,
1112         size_of_val,
1113         sized,
1114         slice,
1115         slice_alloc,
1116         slice_patterns,
1117         slice_u8,
1118         slice_u8_alloc,
1119         slicing_syntax,
1120         soft,
1121         specialization,
1122         speed,
1123         spotlight,
1124         sqrtf32,
1125         sqrtf64,
1126         sreg,
1127         sreg_low16,
1128         sse4a_target_feature,
1129         stable,
1130         staged_api,
1131         start,
1132         state,
1133         static_in_const,
1134         static_nobundle,
1135         static_recursion,
1136         staticlib,
1137         std,
1138         std_inject,
1139         std_panic,
1140         std_panic_2015_macro,
1141         std_panic_macro,
1142         stmt,
1143         stmt_expr_attributes,
1144         stop_after_dataflow,
1145         str,
1146         str_alloc,
1147         string_type,
1148         stringify,
1149         struct_field_attributes,
1150         struct_inherit,
1151         struct_variant,
1152         structural_match,
1153         structural_peq,
1154         structural_teq,
1155         sty,
1156         sub,
1157         sub_assign,
1158         sub_with_overflow,
1159         suggestion,
1160         sym,
1161         sync,
1162         sync_trait,
1163         t32,
1164         target_arch,
1165         target_endian,
1166         target_env,
1167         target_family,
1168         target_feature,
1169         target_feature_11,
1170         target_has_atomic,
1171         target_has_atomic_equal_alignment,
1172         target_has_atomic_load_store,
1173         target_os,
1174         target_pointer_width,
1175         target_target_vendor,
1176         target_thread_local,
1177         target_vendor,
1178         task,
1179         tbm_target_feature,
1180         termination,
1181         termination_trait,
1182         termination_trait_test,
1183         test,
1184         test_2018_feature,
1185         test_accepted_feature,
1186         test_case,
1187         test_removed_feature,
1188         test_runner,
1189         then_with,
1190         thread,
1191         thread_local,
1192         tool_attributes,
1193         tool_lints,
1194         trace_macros,
1195         track_caller,
1196         trait_alias,
1197         transmute,
1198         transparent,
1199         transparent_enums,
1200         transparent_unions,
1201         trivial_bounds,
1202         truncf32,
1203         truncf64,
1204         try_blocks,
1205         try_from_trait,
1206         try_into_trait,
1207         try_trait,
1208         tt,
1209         tuple,
1210         tuple_from_req,
1211         tuple_indexing,
1212         two_phase,
1213         ty,
1214         type_alias_enum_variants,
1215         type_alias_impl_trait,
1216         type_ascription,
1217         type_id,
1218         type_length_limit,
1219         type_macros,
1220         type_name,
1221         u128,
1222         u16,
1223         u32,
1224         u64,
1225         u8,
1226         unaligned_volatile_load,
1227         unaligned_volatile_store,
1228         unboxed_closures,
1229         unchecked_add,
1230         unchecked_div,
1231         unchecked_mul,
1232         unchecked_rem,
1233         unchecked_shl,
1234         unchecked_shr,
1235         unchecked_sub,
1236         underscore_const_names,
1237         underscore_imports,
1238         underscore_lifetimes,
1239         uniform_paths,
1240         unit,
1241         universal_impl_trait,
1242         unix,
1243         unlikely,
1244         unmarked_api,
1245         unpin,
1246         unreachable,
1247         unreachable_code,
1248         unrestricted_attribute_tokens,
1249         unsafe_block_in_unsafe_fn,
1250         unsafe_cell,
1251         unsafe_no_drop_flag,
1252         unsize,
1253         unsized_fn_params,
1254         unsized_locals,
1255         unsized_tuple_coercion,
1256         unstable,
1257         untagged_unions,
1258         unused_qualifications,
1259         unwind,
1260         unwind_attributes,
1261         unwrap,
1262         unwrap_or,
1263         use_extern_macros,
1264         use_nested_groups,
1265         used,
1266         usize,
1267         v1,
1268         va_arg,
1269         va_copy,
1270         va_end,
1271         va_list,
1272         va_start,
1273         val,
1274         var,
1275         variant_count,
1276         vec,
1277         vec_type,
1278         vecdeque_type,
1279         version,
1280         vis,
1281         visible_private_types,
1282         volatile,
1283         volatile_copy_memory,
1284         volatile_copy_nonoverlapping_memory,
1285         volatile_load,
1286         volatile_set_memory,
1287         volatile_store,
1288         vreg,
1289         vreg_low16,
1290         warn,
1291         wasm_import_module,
1292         wasm_target_feature,
1293         while_let,
1294         width,
1295         windows,
1296         windows_subsystem,
1297         wrapping_add,
1298         wrapping_mul,
1299         wrapping_sub,
1300         write_bytes,
1301         xmm_reg,
1302         ymm_reg,
1303         zmm_reg,
1304     }
1305 }
1306
1307 #[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
1308 pub struct Ident {
1309     pub name: Symbol,
1310     pub span: Span,
1311 }
1312
1313 impl Ident {
1314     #[inline]
1315     /// Constructs a new identifier from a symbol and a span.
1316     pub const fn new(name: Symbol, span: Span) -> Ident {
1317         Ident { name, span }
1318     }
1319
1320     /// Constructs a new identifier with a dummy span.
1321     #[inline]
1322     pub const fn with_dummy_span(name: Symbol) -> Ident {
1323         Ident::new(name, DUMMY_SP)
1324     }
1325
1326     #[inline]
1327     pub fn invalid() -> Ident {
1328         Ident::with_dummy_span(kw::Empty)
1329     }
1330
1331     /// Maps a string to an identifier with a dummy span.
1332     pub fn from_str(string: &str) -> Ident {
1333         Ident::with_dummy_span(Symbol::intern(string))
1334     }
1335
1336     /// Maps a string and a span to an identifier.
1337     pub fn from_str_and_span(string: &str, span: Span) -> Ident {
1338         Ident::new(Symbol::intern(string), span)
1339     }
1340
1341     /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
1342     pub fn with_span_pos(self, span: Span) -> Ident {
1343         Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
1344     }
1345
1346     pub fn without_first_quote(self) -> Ident {
1347         Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
1348     }
1349
1350     /// "Normalize" ident for use in comparisons using "item hygiene".
1351     /// Identifiers with same string value become same if they came from the same macro 2.0 macro
1352     /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
1353     /// different macro 2.0 macros.
1354     /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
1355     pub fn normalize_to_macros_2_0(self) -> Ident {
1356         Ident::new(self.name, self.span.normalize_to_macros_2_0())
1357     }
1358
1359     /// "Normalize" ident for use in comparisons using "local variable hygiene".
1360     /// Identifiers with same string value become same if they came from the same non-transparent
1361     /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
1362     /// non-transparent macros.
1363     /// Technically, this operation strips all transparent marks from ident's syntactic context.
1364     pub fn normalize_to_macro_rules(self) -> Ident {
1365         Ident::new(self.name, self.span.normalize_to_macro_rules())
1366     }
1367
1368     /// Convert the name to a `SymbolStr`. This is a slowish operation because
1369     /// it requires locking the symbol interner.
1370     pub fn as_str(self) -> SymbolStr {
1371         self.name.as_str()
1372     }
1373 }
1374
1375 impl PartialEq for Ident {
1376     fn eq(&self, rhs: &Self) -> bool {
1377         self.name == rhs.name && self.span.ctxt() == rhs.span.ctxt()
1378     }
1379 }
1380
1381 impl Hash for Ident {
1382     fn hash<H: Hasher>(&self, state: &mut H) {
1383         self.name.hash(state);
1384         self.span.ctxt().hash(state);
1385     }
1386 }
1387
1388 impl fmt::Debug for Ident {
1389     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1390         fmt::Display::fmt(self, f)?;
1391         fmt::Debug::fmt(&self.span.ctxt(), f)
1392     }
1393 }
1394
1395 /// This implementation is supposed to be used in error messages, so it's expected to be identical
1396 /// to printing the original identifier token written in source code (`token_to_string`),
1397 /// except that AST identifiers don't keep the rawness flag, so we have to guess it.
1398 impl fmt::Display for Ident {
1399     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1400         fmt::Display::fmt(&IdentPrinter::new(self.name, self.is_raw_guess(), None), f)
1401     }
1402 }
1403
1404 /// This is the most general way to print identifiers.
1405 /// AST pretty-printer is used as a fallback for turning AST structures into token streams for
1406 /// proc macros. Additionally, proc macros may stringify their input and expect it survive the
1407 /// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
1408 /// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
1409 /// hygiene data, most importantly name of the crate it refers to.
1410 /// As a result we print `$crate` as `crate` if it refers to the local crate
1411 /// and as `::other_crate_name` if it refers to some other crate.
1412 /// Note, that this is only done if the ident token is printed from inside of AST pretty-pringing,
1413 /// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
1414 /// so we should not perform this lossy conversion if the top level call to the pretty-printer was
1415 /// done for a token stream or a single token.
1416 pub struct IdentPrinter {
1417     symbol: Symbol,
1418     is_raw: bool,
1419     /// Span used for retrieving the crate name to which `$crate` refers to,
1420     /// if this field is `None` then the `$crate` conversion doesn't happen.
1421     convert_dollar_crate: Option<Span>,
1422 }
1423
1424 impl IdentPrinter {
1425     /// The most general `IdentPrinter` constructor. Do not use this.
1426     pub fn new(symbol: Symbol, is_raw: bool, convert_dollar_crate: Option<Span>) -> IdentPrinter {
1427         IdentPrinter { symbol, is_raw, convert_dollar_crate }
1428     }
1429
1430     /// This implementation is supposed to be used when printing identifiers
1431     /// as a part of pretty-printing for larger AST pieces.
1432     /// Do not use this either.
1433     pub fn for_ast_ident(ident: Ident, is_raw: bool) -> IdentPrinter {
1434         IdentPrinter::new(ident.name, is_raw, Some(ident.span))
1435     }
1436 }
1437
1438 impl fmt::Display for IdentPrinter {
1439     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1440         if self.is_raw {
1441             f.write_str("r#")?;
1442         } else if self.symbol == kw::DollarCrate {
1443             if let Some(span) = self.convert_dollar_crate {
1444                 let converted = span.ctxt().dollar_crate_name();
1445                 if !converted.is_path_segment_keyword() {
1446                     f.write_str("::")?;
1447                 }
1448                 return fmt::Display::fmt(&converted, f);
1449             }
1450         }
1451         fmt::Display::fmt(&self.symbol, f)
1452     }
1453 }
1454
1455 /// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
1456 /// construction.
1457 // FIXME(matthewj, petrochenkov) Use this more often, add a similar
1458 // `ModernIdent` struct and use that as well.
1459 #[derive(Copy, Clone, Eq, PartialEq, Hash)]
1460 pub struct MacroRulesNormalizedIdent(Ident);
1461
1462 impl MacroRulesNormalizedIdent {
1463     pub fn new(ident: Ident) -> Self {
1464         Self(ident.normalize_to_macro_rules())
1465     }
1466 }
1467
1468 impl fmt::Debug for MacroRulesNormalizedIdent {
1469     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1470         fmt::Debug::fmt(&self.0, f)
1471     }
1472 }
1473
1474 impl fmt::Display for MacroRulesNormalizedIdent {
1475     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1476         fmt::Display::fmt(&self.0, f)
1477     }
1478 }
1479
1480 /// An interned string.
1481 ///
1482 /// Internally, a `Symbol` is implemented as an index, and all operations
1483 /// (including hashing, equality, and ordering) operate on that index. The use
1484 /// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
1485 /// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
1486 ///
1487 /// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
1488 /// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
1489 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1490 pub struct Symbol(SymbolIndex);
1491
1492 rustc_index::newtype_index! {
1493     pub struct SymbolIndex { .. }
1494 }
1495
1496 impl Symbol {
1497     const fn new(n: u32) -> Self {
1498         Symbol(SymbolIndex::from_u32(n))
1499     }
1500
1501     /// Maps a string to its interned representation.
1502     pub fn intern(string: &str) -> Self {
1503         with_interner(|interner| interner.intern(string))
1504     }
1505
1506     /// Convert to a `SymbolStr`. This is a slowish operation because it
1507     /// requires locking the symbol interner.
1508     pub fn as_str(self) -> SymbolStr {
1509         with_interner(|interner| unsafe {
1510             SymbolStr { string: std::mem::transmute::<&str, &str>(interner.get(self)) }
1511         })
1512     }
1513
1514     pub fn as_u32(self) -> u32 {
1515         self.0.as_u32()
1516     }
1517
1518     pub fn is_empty(self) -> bool {
1519         self == kw::Empty
1520     }
1521
1522     /// This method is supposed to be used in error messages, so it's expected to be
1523     /// identical to printing the original identifier token written in source code
1524     /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
1525     /// or edition, so we have to guess the rawness using the global edition.
1526     pub fn to_ident_string(self) -> String {
1527         Ident::with_dummy_span(self).to_string()
1528     }
1529 }
1530
1531 impl fmt::Debug for Symbol {
1532     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1533         fmt::Debug::fmt(&self.as_str(), f)
1534     }
1535 }
1536
1537 impl fmt::Display for Symbol {
1538     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1539         fmt::Display::fmt(&self.as_str(), f)
1540     }
1541 }
1542
1543 impl<S: Encoder> Encodable<S> for Symbol {
1544     fn encode(&self, s: &mut S) -> Result<(), S::Error> {
1545         s.emit_str(&self.as_str())
1546     }
1547 }
1548
1549 impl<D: Decoder> Decodable<D> for Symbol {
1550     #[inline]
1551     fn decode(d: &mut D) -> Result<Symbol, D::Error> {
1552         Ok(Symbol::intern(&d.read_str()?))
1553     }
1554 }
1555
1556 impl<CTX> HashStable<CTX> for Symbol {
1557     #[inline]
1558     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1559         self.as_str().hash_stable(hcx, hasher);
1560     }
1561 }
1562
1563 impl<CTX> ToStableHashKey<CTX> for Symbol {
1564     type KeyType = SymbolStr;
1565
1566     #[inline]
1567     fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1568         self.as_str()
1569     }
1570 }
1571
1572 // The `&'static str`s in this type actually point into the arena.
1573 //
1574 // The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
1575 // found that to regress performance up to 2% in some cases. This might be
1576 // revisited after further improvements to `indexmap`.
1577 #[derive(Default)]
1578 pub struct Interner {
1579     arena: DroplessArena,
1580     names: FxHashMap<&'static str, Symbol>,
1581     strings: Vec<&'static str>,
1582 }
1583
1584 impl Interner {
1585     fn prefill(init: &[&'static str]) -> Self {
1586         Interner {
1587             strings: init.into(),
1588             names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
1589             ..Default::default()
1590         }
1591     }
1592
1593     #[inline]
1594     pub fn intern(&mut self, string: &str) -> Symbol {
1595         if let Some(&name) = self.names.get(string) {
1596             return name;
1597         }
1598
1599         let name = Symbol::new(self.strings.len() as u32);
1600
1601         // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
1602         // UTF-8.
1603         let string: &str =
1604             unsafe { str::from_utf8_unchecked(self.arena.alloc_slice(string.as_bytes())) };
1605         // It is safe to extend the arena allocation to `'static` because we only access
1606         // these while the arena is still alive.
1607         let string: &'static str = unsafe { &*(string as *const str) };
1608         self.strings.push(string);
1609         self.names.insert(string, name);
1610         name
1611     }
1612
1613     // Get the symbol as a string. `Symbol::as_str()` should be used in
1614     // preference to this function.
1615     pub fn get(&self, symbol: Symbol) -> &str {
1616         self.strings[symbol.0.as_usize()]
1617     }
1618 }
1619
1620 // This module has a very short name because it's used a lot.
1621 /// This module contains all the defined keyword `Symbol`s.
1622 ///
1623 /// Given that `kw` is imported, use them like `kw::keyword_name`.
1624 /// For example `kw::Loop` or `kw::Break`.
1625 pub mod kw {
1626     pub use super::kw_generated::*;
1627 }
1628
1629 // This module has a very short name because it's used a lot.
1630 /// This module contains all the defined non-keyword `Symbol`s.
1631 ///
1632 /// Given that `sym` is imported, use them like `sym::symbol_name`.
1633 /// For example `sym::rustfmt` or `sym::u8`.
1634 pub mod sym {
1635     use super::Symbol;
1636     use std::convert::TryInto;
1637
1638     #[doc(inline)]
1639     pub use super::sym_generated::*;
1640
1641     // Used from a macro in `librustc_feature/accepted.rs`
1642     pub use super::kw::MacroRules as macro_rules;
1643
1644     /// Get the symbol for an integer.
1645     ///
1646     /// The first few non-negative integers each have a static symbol and therefore
1647     /// are fast.
1648     pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
1649         if let Result::Ok(idx) = n.try_into() {
1650             if idx < 10 {
1651                 return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
1652             }
1653         }
1654         Symbol::intern(&n.to_string())
1655     }
1656 }
1657
1658 impl Symbol {
1659     fn is_special(self) -> bool {
1660         self <= kw::Underscore
1661     }
1662
1663     fn is_used_keyword_always(self) -> bool {
1664         self >= kw::As && self <= kw::While
1665     }
1666
1667     fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1668         (self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
1669     }
1670
1671     fn is_unused_keyword_always(self) -> bool {
1672         self >= kw::Abstract && self <= kw::Yield
1673     }
1674
1675     fn is_unused_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1676         self == kw::Try && edition() >= Edition::Edition2018
1677     }
1678
1679     pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
1680         self.is_special()
1681             || self.is_used_keyword_always()
1682             || self.is_unused_keyword_always()
1683             || self.is_used_keyword_conditional(edition)
1684             || self.is_unused_keyword_conditional(edition)
1685     }
1686
1687     /// A keyword or reserved identifier that can be used as a path segment.
1688     pub fn is_path_segment_keyword(self) -> bool {
1689         self == kw::Super
1690             || self == kw::SelfLower
1691             || self == kw::SelfUpper
1692             || self == kw::Crate
1693             || self == kw::PathRoot
1694             || self == kw::DollarCrate
1695     }
1696
1697     /// Returns `true` if the symbol is `true` or `false`.
1698     pub fn is_bool_lit(self) -> bool {
1699         self == kw::True || self == kw::False
1700     }
1701
1702     /// Returns `true` if this symbol can be a raw identifier.
1703     pub fn can_be_raw(self) -> bool {
1704         self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword()
1705     }
1706 }
1707
1708 impl Ident {
1709     // Returns `true` for reserved identifiers used internally for elided lifetimes,
1710     // unnamed method parameters, crate root module, error recovery etc.
1711     pub fn is_special(self) -> bool {
1712         self.name.is_special()
1713     }
1714
1715     /// Returns `true` if the token is a keyword used in the language.
1716     pub fn is_used_keyword(self) -> bool {
1717         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1718         self.name.is_used_keyword_always()
1719             || self.name.is_used_keyword_conditional(|| self.span.edition())
1720     }
1721
1722     /// Returns `true` if the token is a keyword reserved for possible future use.
1723     pub fn is_unused_keyword(self) -> bool {
1724         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1725         self.name.is_unused_keyword_always()
1726             || self.name.is_unused_keyword_conditional(|| self.span.edition())
1727     }
1728
1729     /// Returns `true` if the token is either a special identifier or a keyword.
1730     pub fn is_reserved(self) -> bool {
1731         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1732         self.name.is_reserved(|| self.span.edition())
1733     }
1734
1735     /// A keyword or reserved identifier that can be used as a path segment.
1736     pub fn is_path_segment_keyword(self) -> bool {
1737         self.name.is_path_segment_keyword()
1738     }
1739
1740     /// We see this identifier in a normal identifier position, like variable name or a type.
1741     /// How was it written originally? Did it use the raw form? Let's try to guess.
1742     pub fn is_raw_guess(self) -> bool {
1743         self.name.can_be_raw() && self.is_reserved()
1744     }
1745 }
1746
1747 #[inline]
1748 fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
1749     SESSION_GLOBALS.with(|session_globals| f(&mut *session_globals.symbol_interner.lock()))
1750 }
1751
1752 /// An alternative to [`Symbol`], useful when the chars within the symbol need to
1753 /// be accessed. It deliberately has limited functionality and should only be
1754 /// used for temporary values.
1755 ///
1756 /// Because the interner outlives any thread which uses this type, we can
1757 /// safely treat `string` which points to interner data, as an immortal string,
1758 /// as long as this type never crosses between threads.
1759 //
1760 // FIXME: ensure that the interner outlives any thread which uses `SymbolStr`,
1761 // by creating a new thread right after constructing the interner.
1762 #[derive(Clone, Eq, PartialOrd, Ord)]
1763 pub struct SymbolStr {
1764     string: &'static str,
1765 }
1766
1767 // This impl allows a `SymbolStr` to be directly equated with a `String` or
1768 // `&str`.
1769 impl<T: std::ops::Deref<Target = str>> std::cmp::PartialEq<T> for SymbolStr {
1770     fn eq(&self, other: &T) -> bool {
1771         self.string == other.deref()
1772     }
1773 }
1774
1775 impl !Send for SymbolStr {}
1776 impl !Sync for SymbolStr {}
1777
1778 /// This impl means that if `ss` is a `SymbolStr`:
1779 /// - `*ss` is a `str`;
1780 /// - `&*ss` is a `&str` (and `match &*ss { ... }` is a common pattern).
1781 /// - `&ss as &str` is a `&str`, which means that `&ss` can be passed to a
1782 ///   function expecting a `&str`.
1783 impl std::ops::Deref for SymbolStr {
1784     type Target = str;
1785     #[inline]
1786     fn deref(&self) -> &str {
1787         self.string
1788     }
1789 }
1790
1791 impl fmt::Debug for SymbolStr {
1792     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1793         fmt::Debug::fmt(self.string, f)
1794     }
1795 }
1796
1797 impl fmt::Display for SymbolStr {
1798     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1799         fmt::Display::fmt(self.string, f)
1800     }
1801 }
1802
1803 impl<CTX> HashStable<CTX> for SymbolStr {
1804     #[inline]
1805     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1806         self.string.hash_stable(hcx, hasher)
1807     }
1808 }
1809
1810 impl<CTX> ToStableHashKey<CTX> for SymbolStr {
1811     type KeyType = SymbolStr;
1812
1813     #[inline]
1814     fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1815         self.clone()
1816     }
1817 }