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