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