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