]> git.lizzy.rs Git - rust.git/blob - src/librustc_span/symbol.rs
Rollup merge of #75892 - ArekPiekarz:unstable_book_tls_model_typo, 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::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 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         aarch64_target_feature,
216         abi,
217         abi_amdgpu_kernel,
218         abi_avr_interrupt,
219         abi_efiapi,
220         abi_msp430_interrupt,
221         abi_ptx,
222         abi_sysv64,
223         abi_thiscall,
224         abi_unadjusted,
225         abi_vectorcall,
226         abi_x86_interrupt,
227         abort,
228         aborts,
229         add,
230         add_assign,
231         add_with_overflow,
232         address,
233         advanced_slice_patterns,
234         adx_target_feature,
235         alias,
236         align,
237         align_offset,
238         alignstack,
239         all,
240         alloc,
241         alloc_error_handler,
242         alloc_layout,
243         alloc_zeroed,
244         allocator,
245         allocator_internals,
246         allow,
247         allow_fail,
248         allow_internal_unsafe,
249         allow_internal_unstable,
250         allow_internal_unstable_backcompat_hack,
251         allowed,
252         always,
253         and,
254         and_then,
255         any,
256         arbitrary_enum_discriminant,
257         arbitrary_self_types,
258         arith_offset,
259         arm_target_feature,
260         array,
261         arrays,
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         crate_id,
384         crate_in_paths,
385         crate_local,
386         crate_name,
387         crate_type,
388         crate_visibility_modifier,
389         crt_dash_static: "crt-static",
390         ctlz,
391         ctlz_nonzero,
392         ctpop,
393         cttz,
394         cttz_nonzero,
395         custom_attribute,
396         custom_derive,
397         custom_inner_attributes,
398         custom_test_frameworks,
399         d,
400         dead_code,
401         dealloc,
402         debug,
403         debug_assertions,
404         debug_struct,
405         debug_trait,
406         debug_trait_builder,
407         debug_tuple,
408         decl_macro,
409         declare_lint_pass,
410         decode,
411         default_lib_allocator,
412         default_type_parameter_fallback,
413         default_type_params,
414         delay_span_bug_from_inside_query,
415         deny,
416         deprecated,
417         deref,
418         deref_mut,
419         derive,
420         diagnostic,
421         direct,
422         discriminant_kind,
423         discriminant_type,
424         discriminant_value,
425         dispatch_from_dyn,
426         div,
427         div_assign,
428         doc,
429         doc_alias,
430         doc_cfg,
431         doc_keyword,
432         doc_masked,
433         doc_spotlight,
434         doctest,
435         document_private_items,
436         dotdot_in_tuple_patterns,
437         dotdoteq_in_patterns,
438         double_braced_closure: "{{closure}}",
439         double_braced_constant: "{{constant}}",
440         double_braced_constructor: "{{constructor}}",
441         double_braced_crate: "{{crate}}",
442         double_braced_impl: "{{impl}}",
443         double_braced_misc: "{{misc}}",
444         double_braced_opaque: "{{opaque}}",
445         drop,
446         drop_in_place,
447         drop_types_in_const,
448         dropck_eyepatch,
449         dropck_parametricity,
450         dylib,
451         dyn_trait,
452         eh_catch_typeinfo,
453         eh_personality,
454         emit_enum,
455         emit_enum_variant,
456         emit_enum_variant_arg,
457         emit_struct,
458         emit_struct_field,
459         enable,
460         enclosing_scope,
461         encode,
462         env,
463         eq,
464         err,
465         exact_div,
466         except,
467         exchange_malloc,
468         exclusive_range_pattern,
469         exhaustive_integer_patterns,
470         exhaustive_patterns,
471         existential_type,
472         exp2f32,
473         exp2f64,
474         expected,
475         expf32,
476         expf64,
477         export_name,
478         expr,
479         extern_absolute_paths,
480         extern_crate_item_prelude,
481         extern_crate_self,
482         extern_in_paths,
483         extern_prelude,
484         extern_types,
485         external_doc,
486         f,
487         f16c_target_feature,
488         f32,
489         f32_runtime,
490         f64,
491         f64_runtime,
492         fabsf32,
493         fabsf64,
494         fadd_fast,
495         fdiv_fast,
496         feature,
497         ffi_const,
498         ffi_pure,
499         ffi_returns_twice,
500         field,
501         field_init_shorthand,
502         file,
503         fill,
504         finish,
505         flags,
506         float_to_int_unchecked,
507         floorf32,
508         floorf64,
509         fmaf32,
510         fmaf64,
511         fmt,
512         fmt_internals,
513         fmul_fast,
514         fn_must_use,
515         fn_mut,
516         fn_once,
517         fn_once_output,
518         forbid,
519         forget,
520         format,
521         format_args,
522         format_args_capture,
523         format_args_nl,
524         freeze,
525         frem_fast,
526         from,
527         from_desugaring,
528         from_error,
529         from_generator,
530         from_method,
531         from_ok,
532         from_size_align_unchecked,
533         from_trait,
534         from_usize,
535         fsub_fast,
536         fundamental,
537         future,
538         future_trait,
539         ge,
540         gen_future,
541         gen_kill,
542         generator,
543         generator_state,
544         generators,
545         generic_associated_types,
546         generic_param_attrs,
547         get_context,
548         global_allocator,
549         global_asm,
550         globs,
551         gt,
552         half_open_range_patterns,
553         hash,
554         hexagon_target_feature,
555         hidden,
556         homogeneous_aggregate,
557         html_favicon_url,
558         html_logo_url,
559         html_no_source,
560         html_playground_url,
561         html_root_url,
562         i,
563         i128,
564         i128_type,
565         i16,
566         i32,
567         i64,
568         i8,
569         ident,
570         if_let,
571         if_let_guard,
572         if_while_or_patterns,
573         ignore,
574         impl_header_lifetime_elision,
575         impl_lint_pass,
576         impl_macros,
577         impl_trait_in_bindings,
578         import_shadowing,
579         in_band_lifetimes,
580         include,
581         include_bytes,
582         include_str,
583         inclusive_range_syntax,
584         index,
585         index_mut,
586         infer_outlives_requirements,
587         infer_static_outlives_requirements,
588         inlateout,
589         inline,
590         inout,
591         intel,
592         into_iter,
593         into_result,
594         intrinsics,
595         irrefutable_let_patterns,
596         isize,
597         issue,
598         issue_5723_bootstrap,
599         issue_tracker_base_url,
600         item,
601         item_like_imports,
602         iter,
603         keyword,
604         kind,
605         label,
606         label_break_value,
607         lang,
608         lang_items,
609         lateout,
610         lazy_normalization_consts,
611         le,
612         let_chains,
613         lhs,
614         lib,
615         libc,
616         lifetime,
617         likely,
618         line,
619         link,
620         link_args,
621         link_cfg,
622         link_llvm_intrinsics,
623         link_name,
624         link_ordinal,
625         link_section,
626         linkage,
627         lint_reasons,
628         literal,
629         llvm_asm,
630         local_inner_macros,
631         log10f32,
632         log10f64,
633         log2f32,
634         log2f64,
635         log_syntax,
636         logf32,
637         logf64,
638         loop_break_value,
639         lt,
640         macro_at_most_once_rep,
641         macro_escape,
642         macro_export,
643         macro_lifetime_matcher,
644         macro_literal_matcher,
645         macro_reexport,
646         macro_use,
647         macro_vis_matcher,
648         macros_in_extern,
649         main,
650         managed_boxes,
651         manually_drop,
652         map,
653         marker,
654         marker_trait_attr,
655         masked,
656         match_beginning_vert,
657         match_default_bindings,
658         maxnumf32,
659         maxnumf64,
660         may_dangle,
661         maybe_uninit,
662         maybe_uninit_uninit,
663         maybe_uninit_zeroed,
664         mem_uninitialized,
665         mem_zeroed,
666         member_constraints,
667         memory,
668         message,
669         meta,
670         min_align_of,
671         min_align_of_val,
672         min_const_fn,
673         min_const_generics,
674         min_const_unsafe_fn,
675         min_specialization,
676         minnumf32,
677         minnumf64,
678         mips_target_feature,
679         mmx_target_feature,
680         module,
681         module_path,
682         more_struct_aliases,
683         movbe_target_feature,
684         move_ref_pattern,
685         move_val_init,
686         mul,
687         mul_assign,
688         mul_with_overflow,
689         must_use,
690         mut_ptr,
691         mut_slice_ptr,
692         naked,
693         naked_functions,
694         name,
695         ne,
696         nearbyintf32,
697         nearbyintf64,
698         needs_allocator,
699         needs_drop,
700         needs_panic_runtime,
701         neg,
702         negate_unsigned,
703         negative_impls,
704         never,
705         never_type,
706         never_type_fallback,
707         new,
708         new_unchecked,
709         next,
710         nll,
711         no,
712         no_builtins,
713         no_core,
714         no_crate_inject,
715         no_debug,
716         no_default_passes,
717         no_implicit_prelude,
718         no_inline,
719         no_link,
720         no_main,
721         no_mangle,
722         no_niche,
723         no_sanitize,
724         no_stack_check,
725         no_start,
726         no_std,
727         nomem,
728         non_ascii_idents,
729         non_exhaustive,
730         non_modrs_mods,
731         none_error,
732         nontemporal_store,
733         nontrapping_dash_fptoint: "nontrapping-fptoint",
734         noreturn,
735         nostack,
736         not,
737         note,
738         object_safe_for_dispatch,
739         of,
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         range_inclusive_new,
832         raw_dylib,
833         raw_identifiers,
834         raw_ref_op,
835         re_rebalance_coherence,
836         read_enum,
837         read_enum_variant,
838         read_enum_variant_arg,
839         read_struct,
840         read_struct_field,
841         readonly,
842         realloc,
843         reason,
844         receiver,
845         recursion_limit,
846         reexport_test_harness_main,
847         reference,
848         reflect,
849         register_attr,
850         register_tool,
851         relaxed_adts,
852         rem,
853         rem_assign,
854         repr,
855         repr128,
856         repr_align,
857         repr_align_enum,
858         repr_no_niche,
859         repr_packed,
860         repr_simd,
861         repr_transparent,
862         result,
863         result_type,
864         rhs,
865         rintf32,
866         rintf64,
867         riscv_target_feature,
868         rlib,
869         rotate_left,
870         rotate_right,
871         roundf32,
872         roundf64,
873         rt,
874         rtm_target_feature,
875         rust,
876         rust_2015_preview,
877         rust_2018_preview,
878         rust_begin_unwind,
879         rust_eh_catch_typeinfo,
880         rust_eh_personality,
881         rust_eh_register_frames,
882         rust_eh_unregister_frames,
883         rust_oom,
884         rustc,
885         rustc_allocator,
886         rustc_allocator_nounwind,
887         rustc_allow_const_fn_ptr,
888         rustc_args_required_const,
889         rustc_attrs,
890         rustc_builtin_macro,
891         rustc_clean,
892         rustc_const_stable,
893         rustc_const_unstable,
894         rustc_conversion_suggestion,
895         rustc_def_path,
896         rustc_deprecated,
897         rustc_diagnostic_item,
898         rustc_diagnostic_macros,
899         rustc_dirty,
900         rustc_dummy,
901         rustc_dump_env_program_clauses,
902         rustc_dump_program_clauses,
903         rustc_dump_user_substs,
904         rustc_error,
905         rustc_expected_cgu_reuse,
906         rustc_if_this_changed,
907         rustc_inherit_overflow_checks,
908         rustc_layout,
909         rustc_layout_scalar_valid_range_end,
910         rustc_layout_scalar_valid_range_start,
911         rustc_macro_transparency,
912         rustc_mir,
913         rustc_nonnull_optimization_guaranteed,
914         rustc_object_lifetime_default,
915         rustc_on_unimplemented,
916         rustc_outlives,
917         rustc_paren_sugar,
918         rustc_partition_codegened,
919         rustc_partition_reused,
920         rustc_peek,
921         rustc_peek_definite_init,
922         rustc_peek_indirectly_mutable,
923         rustc_peek_liveness,
924         rustc_peek_maybe_init,
925         rustc_peek_maybe_uninit,
926         rustc_polymorphize_error,
927         rustc_private,
928         rustc_proc_macro_decls,
929         rustc_promotable,
930         rustc_regions,
931         rustc_reservation_impl,
932         rustc_serialize,
933         rustc_specialization_trait,
934         rustc_stable,
935         rustc_std_internal_symbol,
936         rustc_symbol_name,
937         rustc_synthetic,
938         rustc_test_marker,
939         rustc_then_this_would_need,
940         rustc_unsafe_specialization_marker,
941         rustc_variance,
942         rustfmt,
943         rvalue_static_promotion,
944         sanitize,
945         sanitizer_runtime,
946         saturating_add,
947         saturating_sub,
948         self_in_typedefs,
949         self_struct_ctor,
950         semitransparent,
951         send_trait,
952         shl,
953         shl_assign,
954         should_panic,
955         shr,
956         shr_assign,
957         simd,
958         simd_add,
959         simd_and,
960         simd_bitmask,
961         simd_cast,
962         simd_ceil,
963         simd_div,
964         simd_eq,
965         simd_extract,
966         simd_fabs,
967         simd_fcos,
968         simd_fexp,
969         simd_fexp2,
970         simd_ffi,
971         simd_flog,
972         simd_flog10,
973         simd_flog2,
974         simd_floor,
975         simd_fma,
976         simd_fmax,
977         simd_fmin,
978         simd_fpow,
979         simd_fpowi,
980         simd_fsin,
981         simd_fsqrt,
982         simd_gather,
983         simd_ge,
984         simd_gt,
985         simd_insert,
986         simd_le,
987         simd_lt,
988         simd_mul,
989         simd_ne,
990         simd_or,
991         simd_reduce_add_ordered,
992         simd_reduce_add_unordered,
993         simd_reduce_all,
994         simd_reduce_and,
995         simd_reduce_any,
996         simd_reduce_max,
997         simd_reduce_max_nanless,
998         simd_reduce_min,
999         simd_reduce_min_nanless,
1000         simd_reduce_mul_ordered,
1001         simd_reduce_mul_unordered,
1002         simd_reduce_or,
1003         simd_reduce_xor,
1004         simd_rem,
1005         simd_saturating_add,
1006         simd_saturating_sub,
1007         simd_scatter,
1008         simd_select,
1009         simd_select_bitmask,
1010         simd_shl,
1011         simd_shr,
1012         simd_sub,
1013         simd_xor,
1014         since,
1015         sinf32,
1016         sinf64,
1017         size,
1018         size_of,
1019         size_of_val,
1020         sized,
1021         slice,
1022         slice_alloc,
1023         slice_patterns,
1024         slice_u8,
1025         slice_u8_alloc,
1026         slicing_syntax,
1027         soft,
1028         specialization,
1029         speed,
1030         spotlight,
1031         sqrtf32,
1032         sqrtf64,
1033         sse4a_target_feature,
1034         stable,
1035         staged_api,
1036         start,
1037         state,
1038         static_in_const,
1039         static_nobundle,
1040         static_recursion,
1041         staticlib,
1042         std,
1043         std_inject,
1044         stmt,
1045         stmt_expr_attributes,
1046         stop_after_dataflow,
1047         str,
1048         str_alloc,
1049         string_type,
1050         stringify,
1051         struct_field_attributes,
1052         struct_inherit,
1053         struct_variant,
1054         structural_match,
1055         structural_peq,
1056         structural_teq,
1057         sty,
1058         sub,
1059         sub_assign,
1060         sub_with_overflow,
1061         suggestion,
1062         sym,
1063         sync,
1064         sync_trait,
1065         target_arch,
1066         target_endian,
1067         target_env,
1068         target_family,
1069         target_feature,
1070         target_feature_11,
1071         target_has_atomic,
1072         target_has_atomic_load_store,
1073         target_os,
1074         target_pointer_width,
1075         target_target_vendor,
1076         target_thread_local,
1077         target_vendor,
1078         task,
1079         tbm_target_feature,
1080         termination,
1081         termination_trait,
1082         termination_trait_test,
1083         test,
1084         test_2018_feature,
1085         test_accepted_feature,
1086         test_case,
1087         test_removed_feature,
1088         test_runner,
1089         then_with,
1090         thread,
1091         thread_local,
1092         tool_attributes,
1093         tool_lints,
1094         trace_macros,
1095         track_caller,
1096         trait_alias,
1097         transmute,
1098         transparent,
1099         transparent_enums,
1100         transparent_unions,
1101         trivial_bounds,
1102         truncf32,
1103         truncf64,
1104         try_blocks,
1105         try_trait,
1106         tt,
1107         tuple,
1108         tuple_indexing,
1109         two_phase,
1110         ty,
1111         type_alias_enum_variants,
1112         type_alias_impl_trait,
1113         type_ascription,
1114         type_id,
1115         type_length_limit,
1116         type_macros,
1117         type_name,
1118         u128,
1119         u16,
1120         u32,
1121         u64,
1122         u8,
1123         unaligned_volatile_load,
1124         unaligned_volatile_store,
1125         unboxed_closures,
1126         unchecked_add,
1127         unchecked_div,
1128         unchecked_mul,
1129         unchecked_rem,
1130         unchecked_shl,
1131         unchecked_shr,
1132         unchecked_sub,
1133         underscore_const_names,
1134         underscore_imports,
1135         underscore_lifetimes,
1136         uniform_paths,
1137         unit,
1138         universal_impl_trait,
1139         unix,
1140         unlikely,
1141         unmarked_api,
1142         unpin,
1143         unreachable,
1144         unreachable_code,
1145         unrestricted_attribute_tokens,
1146         unsafe_block_in_unsafe_fn,
1147         unsafe_cell,
1148         unsafe_no_drop_flag,
1149         unsize,
1150         unsized_locals,
1151         unsized_tuple_coercion,
1152         unstable,
1153         untagged_unions,
1154         unused_qualifications,
1155         unwind,
1156         unwind_attributes,
1157         unwrap_or,
1158         use_extern_macros,
1159         use_nested_groups,
1160         used,
1161         usize,
1162         v1,
1163         va_arg,
1164         va_copy,
1165         va_end,
1166         va_list,
1167         va_start,
1168         val,
1169         var,
1170         variant_count,
1171         vec,
1172         vec_type,
1173         version,
1174         vis,
1175         visible_private_types,
1176         volatile,
1177         volatile_copy_memory,
1178         volatile_copy_nonoverlapping_memory,
1179         volatile_load,
1180         volatile_set_memory,
1181         volatile_store,
1182         warn,
1183         wasm_import_module,
1184         wasm_target_feature,
1185         while_let,
1186         width,
1187         windows,
1188         windows_subsystem,
1189         wrapping_add,
1190         wrapping_mul,
1191         wrapping_sub,
1192         write_bytes,
1193     }
1194 }
1195
1196 #[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
1197 pub struct Ident {
1198     pub name: Symbol,
1199     pub span: Span,
1200 }
1201
1202 impl Ident {
1203     #[inline]
1204     /// Constructs a new identifier from a symbol and a span.
1205     pub const fn new(name: Symbol, span: Span) -> Ident {
1206         Ident { name, span }
1207     }
1208
1209     /// Constructs a new identifier with a dummy span.
1210     #[inline]
1211     pub const fn with_dummy_span(name: Symbol) -> Ident {
1212         Ident::new(name, DUMMY_SP)
1213     }
1214
1215     #[inline]
1216     pub fn invalid() -> Ident {
1217         Ident::with_dummy_span(kw::Invalid)
1218     }
1219
1220     /// Maps a string to an identifier with a dummy span.
1221     pub fn from_str(string: &str) -> Ident {
1222         Ident::with_dummy_span(Symbol::intern(string))
1223     }
1224
1225     /// Maps a string and a span to an identifier.
1226     pub fn from_str_and_span(string: &str, span: Span) -> Ident {
1227         Ident::new(Symbol::intern(string), span)
1228     }
1229
1230     /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
1231     pub fn with_span_pos(self, span: Span) -> Ident {
1232         Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
1233     }
1234
1235     pub fn without_first_quote(self) -> Ident {
1236         Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
1237     }
1238
1239     /// "Normalize" ident for use in comparisons using "item hygiene".
1240     /// Identifiers with same string value become same if they came from the same macro 2.0 macro
1241     /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
1242     /// different macro 2.0 macros.
1243     /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
1244     pub fn normalize_to_macros_2_0(self) -> Ident {
1245         Ident::new(self.name, self.span.normalize_to_macros_2_0())
1246     }
1247
1248     /// "Normalize" ident for use in comparisons using "local variable hygiene".
1249     /// Identifiers with same string value become same if they came from the same non-transparent
1250     /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
1251     /// non-transparent macros.
1252     /// Technically, this operation strips all transparent marks from ident's syntactic context.
1253     pub fn normalize_to_macro_rules(self) -> Ident {
1254         Ident::new(self.name, self.span.normalize_to_macro_rules())
1255     }
1256
1257     /// Convert the name to a `SymbolStr`. This is a slowish operation because
1258     /// it requires locking the symbol interner.
1259     pub fn as_str(self) -> SymbolStr {
1260         self.name.as_str()
1261     }
1262 }
1263
1264 impl PartialEq for Ident {
1265     fn eq(&self, rhs: &Self) -> bool {
1266         self.name == rhs.name && self.span.ctxt() == rhs.span.ctxt()
1267     }
1268 }
1269
1270 impl Hash for Ident {
1271     fn hash<H: Hasher>(&self, state: &mut H) {
1272         self.name.hash(state);
1273         self.span.ctxt().hash(state);
1274     }
1275 }
1276
1277 impl fmt::Debug for Ident {
1278     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1279         fmt::Display::fmt(self, f)?;
1280         fmt::Debug::fmt(&self.span.ctxt(), f)
1281     }
1282 }
1283
1284 /// This implementation is supposed to be used in error messages, so it's expected to be identical
1285 /// to printing the original identifier token written in source code (`token_to_string`),
1286 /// except that AST identifiers don't keep the rawness flag, so we have to guess it.
1287 impl fmt::Display for Ident {
1288     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1289         fmt::Display::fmt(&IdentPrinter::new(self.name, self.is_raw_guess(), None), f)
1290     }
1291 }
1292
1293 /// This is the most general way to print identifiers.
1294 /// AST pretty-printer is used as a fallback for turning AST structures into token streams for
1295 /// proc macros. Additionally, proc macros may stringify their input and expect it survive the
1296 /// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
1297 /// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
1298 /// hygiene data, most importantly name of the crate it refers to.
1299 /// As a result we print `$crate` as `crate` if it refers to the local crate
1300 /// and as `::other_crate_name` if it refers to some other crate.
1301 /// Note, that this is only done if the ident token is printed from inside of AST pretty-pringing,
1302 /// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
1303 /// so we should not perform this lossy conversion if the top level call to the pretty-printer was
1304 /// done for a token stream or a single token.
1305 pub struct IdentPrinter {
1306     symbol: Symbol,
1307     is_raw: bool,
1308     /// Span used for retrieving the crate name to which `$crate` refers to,
1309     /// if this field is `None` then the `$crate` conversion doesn't happen.
1310     convert_dollar_crate: Option<Span>,
1311 }
1312
1313 impl IdentPrinter {
1314     /// The most general `IdentPrinter` constructor. Do not use this.
1315     pub fn new(symbol: Symbol, is_raw: bool, convert_dollar_crate: Option<Span>) -> IdentPrinter {
1316         IdentPrinter { symbol, is_raw, convert_dollar_crate }
1317     }
1318
1319     /// This implementation is supposed to be used when printing identifiers
1320     /// as a part of pretty-printing for larger AST pieces.
1321     /// Do not use this either.
1322     pub fn for_ast_ident(ident: Ident, is_raw: bool) -> IdentPrinter {
1323         IdentPrinter::new(ident.name, is_raw, Some(ident.span))
1324     }
1325 }
1326
1327 impl fmt::Display for IdentPrinter {
1328     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1329         if self.is_raw {
1330             f.write_str("r#")?;
1331         } else {
1332             if self.symbol == kw::DollarCrate {
1333                 if let Some(span) = self.convert_dollar_crate {
1334                     let converted = span.ctxt().dollar_crate_name();
1335                     if !converted.is_path_segment_keyword() {
1336                         f.write_str("::")?;
1337                     }
1338                     return fmt::Display::fmt(&converted, f);
1339                 }
1340             }
1341         }
1342         fmt::Display::fmt(&self.symbol, f)
1343     }
1344 }
1345
1346 /// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
1347 /// construction.
1348 // FIXME(matthewj, petrochenkov) Use this more often, add a similar
1349 // `ModernIdent` struct and use that as well.
1350 #[derive(Copy, Clone, Eq, PartialEq, Hash)]
1351 pub struct MacroRulesNormalizedIdent(Ident);
1352
1353 impl MacroRulesNormalizedIdent {
1354     pub fn new(ident: Ident) -> Self {
1355         Self(ident.normalize_to_macro_rules())
1356     }
1357 }
1358
1359 impl fmt::Debug for MacroRulesNormalizedIdent {
1360     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1361         fmt::Debug::fmt(&self.0, f)
1362     }
1363 }
1364
1365 impl fmt::Display for MacroRulesNormalizedIdent {
1366     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1367         fmt::Display::fmt(&self.0, f)
1368     }
1369 }
1370
1371 /// An interned string.
1372 ///
1373 /// Internally, a `Symbol` is implemented as an index, and all operations
1374 /// (including hashing, equality, and ordering) operate on that index. The use
1375 /// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
1376 /// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
1377 ///
1378 /// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
1379 /// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
1380 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1381 pub struct Symbol(SymbolIndex);
1382
1383 rustc_index::newtype_index! {
1384     pub struct SymbolIndex { .. }
1385 }
1386
1387 impl Symbol {
1388     const fn new(n: u32) -> Self {
1389         Symbol(SymbolIndex::from_u32(n))
1390     }
1391
1392     /// Maps a string to its interned representation.
1393     pub fn intern(string: &str) -> Self {
1394         with_interner(|interner| interner.intern(string))
1395     }
1396
1397     /// Access the symbol's chars. This is a slowish operation because it
1398     /// requires locking the symbol interner.
1399     pub fn with<F: FnOnce(&str) -> R, R>(self, f: F) -> R {
1400         with_interner(|interner| f(interner.get(self)))
1401     }
1402
1403     /// Convert to a `SymbolStr`. This is a slowish operation because it
1404     /// requires locking the symbol interner.
1405     pub fn as_str(self) -> SymbolStr {
1406         with_interner(|interner| unsafe {
1407             SymbolStr { string: std::mem::transmute::<&str, &str>(interner.get(self)) }
1408         })
1409     }
1410
1411     pub fn as_u32(self) -> u32 {
1412         self.0.as_u32()
1413     }
1414
1415     /// This method is supposed to be used in error messages, so it's expected to be
1416     /// identical to printing the original identifier token written in source code
1417     /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
1418     /// or edition, so we have to guess the rawness using the global edition.
1419     pub fn to_ident_string(self) -> String {
1420         Ident::with_dummy_span(self).to_string()
1421     }
1422 }
1423
1424 impl fmt::Debug for Symbol {
1425     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1426         self.with(|str| fmt::Debug::fmt(&str, f))
1427     }
1428 }
1429
1430 impl fmt::Display for Symbol {
1431     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1432         self.with(|str| fmt::Display::fmt(&str, f))
1433     }
1434 }
1435
1436 impl<S: Encoder> Encodable<S> for Symbol {
1437     fn encode(&self, s: &mut S) -> Result<(), S::Error> {
1438         self.with(|string| s.emit_str(string))
1439     }
1440 }
1441
1442 impl<D: Decoder> Decodable<D> for Symbol {
1443     #[inline]
1444     fn decode(d: &mut D) -> Result<Symbol, D::Error> {
1445         Ok(Symbol::intern(&d.read_str()?))
1446     }
1447 }
1448
1449 impl<CTX> HashStable<CTX> for Symbol {
1450     #[inline]
1451     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1452         self.as_str().hash_stable(hcx, hasher);
1453     }
1454 }
1455
1456 impl<CTX> ToStableHashKey<CTX> for Symbol {
1457     type KeyType = SymbolStr;
1458
1459     #[inline]
1460     fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1461         self.as_str()
1462     }
1463 }
1464
1465 // The `&'static str`s in this type actually point into the arena.
1466 //
1467 // The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
1468 // found that to regress performance up to 2% in some cases. This might be
1469 // revisited after further improvements to `indexmap`.
1470 #[derive(Default)]
1471 pub struct Interner {
1472     arena: DroplessArena,
1473     names: FxHashMap<&'static str, Symbol>,
1474     strings: Vec<&'static str>,
1475 }
1476
1477 impl Interner {
1478     fn prefill(init: &[&'static str]) -> Self {
1479         Interner {
1480             strings: init.into(),
1481             names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
1482             ..Default::default()
1483         }
1484     }
1485
1486     #[inline]
1487     pub fn intern(&mut self, string: &str) -> Symbol {
1488         if let Some(&name) = self.names.get(string) {
1489             return name;
1490         }
1491
1492         let name = Symbol::new(self.strings.len() as u32);
1493
1494         // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
1495         // UTF-8.
1496         let string: &str =
1497             unsafe { str::from_utf8_unchecked(self.arena.alloc_slice(string.as_bytes())) };
1498         // It is safe to extend the arena allocation to `'static` because we only access
1499         // these while the arena is still alive.
1500         let string: &'static str = unsafe { &*(string as *const str) };
1501         self.strings.push(string);
1502         self.names.insert(string, name);
1503         name
1504     }
1505
1506     // Get the symbol as a string. `Symbol::as_str()` should be used in
1507     // preference to this function.
1508     pub fn get(&self, symbol: Symbol) -> &str {
1509         self.strings[symbol.0.as_usize()]
1510     }
1511 }
1512
1513 // This module has a very short name because it's used a lot.
1514 /// This module contains all the defined keyword `Symbol`s.
1515 ///
1516 /// Given that `kw` is imported, use them like `kw::keyword_name`.
1517 /// For example `kw::Loop` or `kw::Break`.
1518 pub mod kw {
1519     use super::Symbol;
1520     keywords!();
1521 }
1522
1523 // This module has a very short name because it's used a lot.
1524 /// This module contains all the defined non-keyword `Symbol`s.
1525 ///
1526 /// Given that `sym` is imported, use them like `sym::symbol_name`.
1527 /// For example `sym::rustfmt` or `sym::u8`.
1528 #[allow(rustc::default_hash_types)]
1529 pub mod sym {
1530     use super::Symbol;
1531     use std::convert::TryInto;
1532
1533     define_symbols!();
1534
1535     // Used from a macro in `librustc_feature/accepted.rs`
1536     pub use super::kw::MacroRules as macro_rules;
1537
1538     // Get the symbol for an integer. The first few non-negative integers each
1539     // have a static symbol and therefore are fast.
1540     pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
1541         if let Result::Ok(idx) = n.try_into() {
1542             if let Option::Some(&sym_) = digits_array.get(idx) {
1543                 return sym_;
1544             }
1545         }
1546         Symbol::intern(&n.to_string())
1547     }
1548 }
1549
1550 impl Symbol {
1551     fn is_used_keyword_2018(self) -> bool {
1552         self >= kw::Async && self <= kw::Dyn
1553     }
1554
1555     fn is_unused_keyword_2018(self) -> bool {
1556         self == kw::Try
1557     }
1558
1559     /// Used for sanity checking rustdoc keyword sections.
1560     pub fn is_doc_keyword(self) -> bool {
1561         self <= kw::Union
1562     }
1563
1564     /// A keyword or reserved identifier that can be used as a path segment.
1565     pub fn is_path_segment_keyword(self) -> bool {
1566         self == kw::Super
1567             || self == kw::SelfLower
1568             || self == kw::SelfUpper
1569             || self == kw::Crate
1570             || self == kw::PathRoot
1571             || self == kw::DollarCrate
1572     }
1573
1574     /// Returns `true` if the symbol is `true` or `false`.
1575     pub fn is_bool_lit(self) -> bool {
1576         self == kw::True || self == kw::False
1577     }
1578
1579     /// This symbol can be a raw identifier.
1580     pub fn can_be_raw(self) -> bool {
1581         self != kw::Invalid && self != kw::Underscore && !self.is_path_segment_keyword()
1582     }
1583 }
1584
1585 impl Ident {
1586     // Returns `true` for reserved identifiers used internally for elided lifetimes,
1587     // unnamed method parameters, crate root module, error recovery etc.
1588     pub fn is_special(self) -> bool {
1589         self.name <= kw::Underscore
1590     }
1591
1592     /// Returns `true` if the token is a keyword used in the language.
1593     pub fn is_used_keyword(self) -> bool {
1594         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1595         self.name >= kw::As && self.name <= kw::While
1596             || self.name.is_used_keyword_2018() && self.span.rust_2018()
1597     }
1598
1599     /// Returns `true` if the token is a keyword reserved for possible future use.
1600     pub fn is_unused_keyword(self) -> bool {
1601         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1602         self.name >= kw::Abstract && self.name <= kw::Yield
1603             || self.name.is_unused_keyword_2018() && self.span.rust_2018()
1604     }
1605
1606     /// Returns `true` if the token is either a special identifier or a keyword.
1607     pub fn is_reserved(self) -> bool {
1608         self.is_special() || self.is_used_keyword() || self.is_unused_keyword()
1609     }
1610
1611     /// A keyword or reserved identifier that can be used as a path segment.
1612     pub fn is_path_segment_keyword(self) -> bool {
1613         self.name.is_path_segment_keyword()
1614     }
1615
1616     /// We see this identifier in a normal identifier position, like variable name or a type.
1617     /// How was it written originally? Did it use the raw form? Let's try to guess.
1618     pub fn is_raw_guess(self) -> bool {
1619         self.name.can_be_raw() && self.is_reserved()
1620     }
1621 }
1622
1623 #[inline]
1624 fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
1625     SESSION_GLOBALS.with(|session_globals| f(&mut *session_globals.symbol_interner.lock()))
1626 }
1627
1628 /// An alternative to `Symbol`, useful when the chars within the symbol need to
1629 /// be accessed. It deliberately has limited functionality and should only be
1630 /// used for temporary values.
1631 ///
1632 /// Because the interner outlives any thread which uses this type, we can
1633 /// safely treat `string` which points to interner data, as an immortal string,
1634 /// as long as this type never crosses between threads.
1635 //
1636 // FIXME: ensure that the interner outlives any thread which uses `SymbolStr`,
1637 // by creating a new thread right after constructing the interner.
1638 #[derive(Clone, Eq, PartialOrd, Ord)]
1639 pub struct SymbolStr {
1640     string: &'static str,
1641 }
1642
1643 // This impl allows a `SymbolStr` to be directly equated with a `String` or
1644 // `&str`.
1645 impl<T: std::ops::Deref<Target = str>> std::cmp::PartialEq<T> for SymbolStr {
1646     fn eq(&self, other: &T) -> bool {
1647         self.string == other.deref()
1648     }
1649 }
1650
1651 impl !Send for SymbolStr {}
1652 impl !Sync for SymbolStr {}
1653
1654 /// This impl means that if `ss` is a `SymbolStr`:
1655 /// - `*ss` is a `str`;
1656 /// - `&*ss` is a `&str` (and `match &*ss { ... }` is a common pattern).
1657 /// - `&ss as &str` is a `&str`, which means that `&ss` can be passed to a
1658 ///   function expecting a `&str`.
1659 impl std::ops::Deref for SymbolStr {
1660     type Target = str;
1661     #[inline]
1662     fn deref(&self) -> &str {
1663         self.string
1664     }
1665 }
1666
1667 impl fmt::Debug for SymbolStr {
1668     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1669         fmt::Debug::fmt(self.string, f)
1670     }
1671 }
1672
1673 impl fmt::Display for SymbolStr {
1674     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1675         fmt::Display::fmt(self.string, f)
1676     }
1677 }
1678
1679 impl<CTX> HashStable<CTX> for SymbolStr {
1680     #[inline]
1681     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1682         self.string.hash_stable(hcx, hasher)
1683     }
1684 }
1685
1686 impl<CTX> ToStableHashKey<CTX> for SymbolStr {
1687     type KeyType = SymbolStr;
1688
1689     #[inline]
1690     fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1691         self.clone()
1692     }
1693 }