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