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