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