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