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