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