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