]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_span/src/symbol.rs
2d5c6451d1a52d59a421d46a6530da9dafde364c
[rust.git] / compiler / rustc_span / src / symbol.rs
1 //! An "interner" is a data structure that associates values with usize tags and
2 //! allows bidirectional lookup; i.e., given a value, one can easily find the
3 //! type, and vice versa.
4
5 use rustc_arena::DroplessArena;
6 use rustc_data_structures::fx::FxHashMap;
7 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
8 use rustc_macros::HashStable_Generic;
9 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
10
11 use std::cmp::{Ord, PartialEq, PartialOrd};
12 use std::fmt;
13 use std::hash::{Hash, Hasher};
14 use std::str;
15
16 use crate::{Span, DUMMY_SP, SESSION_GLOBALS};
17
18 #[cfg(test)]
19 mod tests;
20
21 // The proc macro code for this is in `src/librustc_macros/src/symbols.rs`.
22 symbols! {
23     // After modifying this list adjust `is_special`, `is_used_keyword`/`is_unused_keyword`,
24     // this should be rarely necessary though if the keywords are kept in alphabetic order.
25     Keywords {
26         // Special reserved identifiers used internally for elided lifetimes,
27         // unnamed method parameters, crate root module, error recovery etc.
28         Invalid:            "",
29         PathRoot:           "{{root}}",
30         DollarCrate:        "$crate",
31         Underscore:         "_",
32
33         // Keywords that are used in stable Rust.
34         As:                 "as",
35         Break:              "break",
36         Const:              "const",
37         Continue:           "continue",
38         Crate:              "crate",
39         Else:               "else",
40         Enum:               "enum",
41         Extern:             "extern",
42         False:              "false",
43         Fn:                 "fn",
44         For:                "for",
45         If:                 "if",
46         Impl:               "impl",
47         In:                 "in",
48         Let:                "let",
49         Loop:               "loop",
50         Match:              "match",
51         Mod:                "mod",
52         Move:               "move",
53         Mut:                "mut",
54         Pub:                "pub",
55         Ref:                "ref",
56         Return:             "return",
57         SelfLower:          "self",
58         SelfUpper:          "Self",
59         Static:             "static",
60         Struct:             "struct",
61         Super:              "super",
62         Trait:              "trait",
63         True:               "true",
64         Type:               "type",
65         Unsafe:             "unsafe",
66         Use:                "use",
67         Where:              "where",
68         While:              "while",
69
70         // Keywords that are used in unstable Rust or reserved for future use.
71         Abstract:           "abstract",
72         Become:             "become",
73         Box:                "box",
74         Do:                 "do",
75         Final:              "final",
76         Macro:              "macro",
77         Override:           "override",
78         Priv:               "priv",
79         Typeof:             "typeof",
80         Unsized:            "unsized",
81         Virtual:            "virtual",
82         Yield:              "yield",
83
84         // Edition-specific keywords that are used in stable Rust.
85         Async:              "async", // >= 2018 Edition only
86         Await:              "await", // >= 2018 Edition only
87         Dyn:                "dyn", // >= 2018 Edition only
88
89         // Edition-specific keywords that are used in unstable Rust or reserved for future use.
90         Try:                "try", // >= 2018 Edition only
91
92         // Special lifetime names
93         UnderscoreLifetime: "'_",
94         StaticLifetime:     "'static",
95
96         // Weak keywords, have special meaning only in specific contexts.
97         Auto:               "auto",
98         Catch:              "catch",
99         Default:            "default",
100         MacroRules:         "macro_rules",
101         Raw:                "raw",
102         Union:              "union",
103     }
104
105     // Pre-interned symbols that can be referred to with `rustc_span::sym::*`.
106     //
107     // The symbol is the stringified identifier unless otherwise specified, in
108     // which case the name should mention the non-identifier punctuation.
109     // E.g. `sym::proc_dash_macro` represents "proc-macro", and it shouldn't be
110     // called `sym::proc_macro` because then it's easy to mistakenly think it
111     // represents "proc_macro".
112     //
113     // As well as the symbols listed, there are symbols for the strings
114     // "0", "1", ..., "9", which are accessible via `sym::integer`.
115     //
116     // The proc macro will abort if symbols are not in alphabetical order (as
117     // defined by `impl Ord for str`) or if any symbols are duplicated. Vim
118     // users can sort the list by selecting it and executing the command
119     // `:'<,'>!LC_ALL=C sort`.
120     //
121     // There is currently no checking that all symbols are used; that would be
122     // nice to have.
123     Symbols {
124         Alignment,
125         Arc,
126         Argument,
127         ArgumentV1,
128         Arguments,
129         C,
130         Center,
131         Clone,
132         Copy,
133         Count,
134         Debug,
135         Decodable,
136         Decoder,
137         Default,
138         Encodable,
139         Encoder,
140         Eq,
141         Equal,
142         Err,
143         Error,
144         FormatSpec,
145         Formatter,
146         From,
147         Future,
148         FxHashMap,
149         FxHashSet,
150         GlobalAlloc,
151         Hash,
152         HashMap,
153         HashSet,
154         Hasher,
155         Implied,
156         Input,
157         IntoIterator,
158         Is,
159         ItemContext,
160         Iterator,
161         Layout,
162         Left,
163         LintPass,
164         None,
165         Ok,
166         Option,
167         Ord,
168         Ordering,
169         Output,
170         Param,
171         PartialEq,
172         PartialOrd,
173         Pending,
174         Pin,
175         Poll,
176         ProcMacro,
177         ProcMacroHack,
178         ProceduralMasqueradeDummyType,
179         Range,
180         RangeFrom,
181         RangeFull,
182         RangeInclusive,
183         RangeTo,
184         RangeToInclusive,
185         Rc,
186         Ready,
187         Result,
188         Return,
189         Right,
190         RustcDecodable,
191         RustcEncodable,
192         Send,
193         Some,
194         StructuralEq,
195         StructuralPartialEq,
196         Sync,
197         Target,
198         Try,
199         Ty,
200         TyCtxt,
201         TyKind,
202         Unknown,
203         Vec,
204         Yield,
205         _DECLS,
206         _Self,
207         __D,
208         __H,
209         __S,
210         __next,
211         __try_var,
212         _d,
213         _e,
214         _task_context,
215         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_evaluatable_checked,
352         const_extern_fn,
353         const_fn,
354         const_fn_transmute,
355         const_fn_union,
356         const_generics,
357         const_if_match,
358         const_in_array_repeat_expressions,
359         const_indexing,
360         const_let,
361         const_loop,
362         const_mut_refs,
363         const_panic,
364         const_precise_live_drops,
365         const_ptr,
366         const_raw_ptr_deref,
367         const_raw_ptr_to_usize_cast,
368         const_slice_ptr,
369         const_trait_bound_opt_out,
370         const_trait_impl,
371         const_transmute,
372         contents,
373         context,
374         convert,
375         copy,
376         copy_closures,
377         copy_nonoverlapping,
378         copysignf32,
379         copysignf64,
380         core,
381         core_intrinsics,
382         cosf32,
383         cosf64,
384         crate_id,
385         crate_in_paths,
386         crate_local,
387         crate_name,
388         crate_type,
389         crate_visibility_modifier,
390         crt_dash_static: "crt-static",
391         ctlz,
392         ctlz_nonzero,
393         ctpop,
394         cttz,
395         cttz_nonzero,
396         custom_attribute,
397         custom_derive,
398         custom_inner_attributes,
399         custom_test_frameworks,
400         d,
401         dead_code,
402         dealloc,
403         debug,
404         debug_assertions,
405         debug_struct,
406         debug_trait,
407         debug_trait_builder,
408         debug_tuple,
409         decl_macro,
410         declare_lint_pass,
411         decode,
412         default_lib_allocator,
413         default_type_parameter_fallback,
414         default_type_params,
415         delay_span_bug_from_inside_query,
416         deny,
417         deprecated,
418         deref,
419         deref_method,
420         deref_mut,
421         deref_target,
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_let_guard,
575         if_while_or_patterns,
576         ignore,
577         impl_header_lifetime_elision,
578         impl_lint_pass,
579         impl_macros,
580         impl_trait_in_bindings,
581         import_shadowing,
582         in_band_lifetimes,
583         include,
584         include_bytes,
585         include_str,
586         inclusive_range_syntax,
587         index,
588         index_mut,
589         infer_outlives_requirements,
590         infer_static_outlives_requirements,
591         inlateout,
592         inline,
593         inout,
594         intel,
595         into_iter,
596         into_result,
597         intrinsics,
598         irrefutable_let_patterns,
599         isize,
600         issue,
601         issue_5723_bootstrap,
602         issue_tracker_base_url,
603         item,
604         item_like_imports,
605         iter,
606         keyword,
607         kind,
608         label,
609         label_break_value,
610         lang,
611         lang_items,
612         lateout,
613         lazy_normalization_consts,
614         le,
615         let_chains,
616         lhs,
617         lib,
618         libc,
619         lifetime,
620         likely,
621         line,
622         link,
623         link_args,
624         link_cfg,
625         link_llvm_intrinsics,
626         link_name,
627         link_ordinal,
628         link_section,
629         linkage,
630         lint_reasons,
631         literal,
632         llvm_asm,
633         local_inner_macros,
634         log10f32,
635         log10f64,
636         log2f32,
637         log2f64,
638         log_syntax,
639         logf32,
640         logf64,
641         loop_break_value,
642         lt,
643         macro_at_most_once_rep,
644         macro_escape,
645         macro_export,
646         macro_lifetime_matcher,
647         macro_literal_matcher,
648         macro_reexport,
649         macro_use,
650         macro_vis_matcher,
651         macros_in_extern,
652         main,
653         managed_boxes,
654         manually_drop,
655         map,
656         marker,
657         marker_trait_attr,
658         masked,
659         match_beginning_vert,
660         match_default_bindings,
661         maxnumf32,
662         maxnumf64,
663         may_dangle,
664         maybe_uninit,
665         maybe_uninit_uninit,
666         maybe_uninit_zeroed,
667         mem_uninitialized,
668         mem_zeroed,
669         member_constraints,
670         memory,
671         message,
672         meta,
673         min_align_of,
674         min_align_of_val,
675         min_const_fn,
676         min_const_generics,
677         min_const_unsafe_fn,
678         min_specialization,
679         minnumf32,
680         minnumf64,
681         mips_target_feature,
682         module,
683         module_path,
684         more_struct_aliases,
685         movbe_target_feature,
686         move_ref_pattern,
687         move_val_init,
688         mul,
689         mul_assign,
690         mul_with_overflow,
691         must_use,
692         mut_ptr,
693         mut_slice_ptr,
694         naked,
695         naked_functions,
696         name,
697         ne,
698         nearbyintf32,
699         nearbyintf64,
700         needs_allocator,
701         needs_drop,
702         needs_panic_runtime,
703         neg,
704         negate_unsigned,
705         negative_impls,
706         never,
707         never_type,
708         never_type_fallback,
709         new,
710         new_unchecked,
711         next,
712         nll,
713         no,
714         no_builtins,
715         no_core,
716         no_crate_inject,
717         no_debug,
718         no_default_passes,
719         no_implicit_prelude,
720         no_inline,
721         no_link,
722         no_main,
723         no_mangle,
724         no_niche,
725         no_sanitize,
726         no_stack_check,
727         no_start,
728         no_std,
729         nomem,
730         non_ascii_idents,
731         non_exhaustive,
732         non_modrs_mods,
733         none_error,
734         nontemporal_store,
735         nontrapping_dash_fptoint: "nontrapping-fptoint",
736         noreturn,
737         nostack,
738         not,
739         note,
740         object_safe_for_dispatch,
741         of,
742         offset,
743         omit_gdb_pretty_printer_section,
744         on,
745         on_unimplemented,
746         oom,
747         opaque,
748         ops,
749         opt_out_copy,
750         optimize,
751         optimize_attribute,
752         optin_builtin_traits,
753         option,
754         option_env,
755         option_type,
756         options,
757         or,
758         or_patterns,
759         other,
760         out,
761         overlapping_marker_traits,
762         owned_box,
763         packed,
764         panic,
765         panic_abort,
766         panic_bounds_check,
767         panic_handler,
768         panic_impl,
769         panic_implementation,
770         panic_info,
771         panic_location,
772         panic_runtime,
773         panic_unwind,
774         param_attrs,
775         parent_trait,
776         partial_cmp,
777         partial_ord,
778         passes,
779         pat,
780         path,
781         pattern_parentheses,
782         phantom_data,
783         pin,
784         pinned,
785         platform_intrinsics,
786         plugin,
787         plugin_registrar,
788         plugins,
789         pointer,
790         poll,
791         position,
792         post_dash_lto: "post-lto",
793         powerpc_target_feature,
794         powf32,
795         powf64,
796         powif32,
797         powif64,
798         pre_dash_lto: "pre-lto",
799         precise_pointer_size_matching,
800         precision,
801         pref_align_of,
802         prefetch_read_data,
803         prefetch_read_instruction,
804         prefetch_write_data,
805         prefetch_write_instruction,
806         prelude,
807         prelude_import,
808         preserves_flags,
809         primitive,
810         proc_dash_macro: "proc-macro",
811         proc_macro,
812         proc_macro_attribute,
813         proc_macro_def_site,
814         proc_macro_derive,
815         proc_macro_expr,
816         proc_macro_gen,
817         proc_macro_hygiene,
818         proc_macro_internals,
819         proc_macro_mod,
820         proc_macro_non_items,
821         proc_macro_path_invoc,
822         profiler_builtins,
823         profiler_runtime,
824         ptr_guaranteed_eq,
825         ptr_guaranteed_ne,
826         ptr_offset_from,
827         pub_restricted,
828         pure,
829         pushpop_unsafe,
830         quad_precision_float,
831         question_mark,
832         quote,
833         range_inclusive_new,
834         raw_dylib,
835         raw_identifiers,
836         raw_ref_op,
837         re_rebalance_coherence,
838         read_enum,
839         read_enum_variant,
840         read_enum_variant_arg,
841         read_struct,
842         read_struct_field,
843         readonly,
844         realloc,
845         reason,
846         receiver,
847         recursion_limit,
848         reexport_test_harness_main,
849         reference,
850         reflect,
851         register_attr,
852         register_tool,
853         relaxed_adts,
854         rem,
855         rem_assign,
856         repr,
857         repr128,
858         repr_align,
859         repr_align_enum,
860         repr_no_niche,
861         repr_packed,
862         repr_simd,
863         repr_transparent,
864         result,
865         result_type,
866         rhs,
867         rintf32,
868         rintf64,
869         riscv_target_feature,
870         rlib,
871         rotate_left,
872         rotate_right,
873         roundf32,
874         roundf64,
875         rt,
876         rtm_target_feature,
877         rust,
878         rust_2015_preview,
879         rust_2018_preview,
880         rust_begin_unwind,
881         rust_eh_catch_typeinfo,
882         rust_eh_personality,
883         rust_eh_register_frames,
884         rust_eh_unregister_frames,
885         rust_oom,
886         rustc,
887         rustc_allocator,
888         rustc_allocator_nounwind,
889         rustc_allow_const_fn_ptr,
890         rustc_args_required_const,
891         rustc_attrs,
892         rustc_builtin_macro,
893         rustc_clean,
894         rustc_const_stable,
895         rustc_const_unstable,
896         rustc_conversion_suggestion,
897         rustc_def_path,
898         rustc_deprecated,
899         rustc_diagnostic_item,
900         rustc_diagnostic_macros,
901         rustc_dirty,
902         rustc_dummy,
903         rustc_dump_env_program_clauses,
904         rustc_dump_program_clauses,
905         rustc_dump_user_substs,
906         rustc_error,
907         rustc_expected_cgu_reuse,
908         rustc_if_this_changed,
909         rustc_inherit_overflow_checks,
910         rustc_layout,
911         rustc_layout_scalar_valid_range_end,
912         rustc_layout_scalar_valid_range_start,
913         rustc_macro_transparency,
914         rustc_mir,
915         rustc_nonnull_optimization_guaranteed,
916         rustc_object_lifetime_default,
917         rustc_on_unimplemented,
918         rustc_outlives,
919         rustc_paren_sugar,
920         rustc_partition_codegened,
921         rustc_partition_reused,
922         rustc_peek,
923         rustc_peek_definite_init,
924         rustc_peek_indirectly_mutable,
925         rustc_peek_liveness,
926         rustc_peek_maybe_init,
927         rustc_peek_maybe_uninit,
928         rustc_polymorphize_error,
929         rustc_private,
930         rustc_proc_macro_decls,
931         rustc_promotable,
932         rustc_regions,
933         rustc_reservation_impl,
934         rustc_serialize,
935         rustc_specialization_trait,
936         rustc_stable,
937         rustc_std_internal_symbol,
938         rustc_symbol_name,
939         rustc_synthetic,
940         rustc_test_marker,
941         rustc_then_this_would_need,
942         rustc_unsafe_specialization_marker,
943         rustc_variance,
944         rustfmt,
945         rvalue_static_promotion,
946         sanitize,
947         sanitizer_runtime,
948         saturating_add,
949         saturating_sub,
950         self_in_typedefs,
951         self_struct_ctor,
952         semitransparent,
953         send_trait,
954         shl,
955         shl_assign,
956         should_panic,
957         shr,
958         shr_assign,
959         simd,
960         simd_add,
961         simd_and,
962         simd_bitmask,
963         simd_cast,
964         simd_ceil,
965         simd_div,
966         simd_eq,
967         simd_extract,
968         simd_fabs,
969         simd_fcos,
970         simd_fexp,
971         simd_fexp2,
972         simd_ffi,
973         simd_flog,
974         simd_flog10,
975         simd_flog2,
976         simd_floor,
977         simd_fma,
978         simd_fmax,
979         simd_fmin,
980         simd_fpow,
981         simd_fpowi,
982         simd_fsin,
983         simd_fsqrt,
984         simd_gather,
985         simd_ge,
986         simd_gt,
987         simd_insert,
988         simd_le,
989         simd_lt,
990         simd_mul,
991         simd_ne,
992         simd_or,
993         simd_reduce_add_ordered,
994         simd_reduce_add_unordered,
995         simd_reduce_all,
996         simd_reduce_and,
997         simd_reduce_any,
998         simd_reduce_max,
999         simd_reduce_max_nanless,
1000         simd_reduce_min,
1001         simd_reduce_min_nanless,
1002         simd_reduce_mul_ordered,
1003         simd_reduce_mul_unordered,
1004         simd_reduce_or,
1005         simd_reduce_xor,
1006         simd_rem,
1007         simd_saturating_add,
1008         simd_saturating_sub,
1009         simd_scatter,
1010         simd_select,
1011         simd_select_bitmask,
1012         simd_shl,
1013         simd_shr,
1014         simd_sub,
1015         simd_xor,
1016         since,
1017         sinf32,
1018         sinf64,
1019         size,
1020         size_of,
1021         size_of_val,
1022         sized,
1023         slice,
1024         slice_alloc,
1025         slice_patterns,
1026         slice_u8,
1027         slice_u8_alloc,
1028         slicing_syntax,
1029         soft,
1030         specialization,
1031         speed,
1032         spotlight,
1033         sqrtf32,
1034         sqrtf64,
1035         sse4a_target_feature,
1036         stable,
1037         staged_api,
1038         start,
1039         state,
1040         static_in_const,
1041         static_nobundle,
1042         static_recursion,
1043         staticlib,
1044         std,
1045         std_inject,
1046         stmt,
1047         stmt_expr_attributes,
1048         stop_after_dataflow,
1049         str,
1050         str_alloc,
1051         string_type,
1052         stringify,
1053         struct_field_attributes,
1054         struct_inherit,
1055         struct_variant,
1056         structural_match,
1057         structural_peq,
1058         structural_teq,
1059         sty,
1060         sub,
1061         sub_assign,
1062         sub_with_overflow,
1063         suggestion,
1064         sym,
1065         sync,
1066         sync_trait,
1067         target_arch,
1068         target_endian,
1069         target_env,
1070         target_family,
1071         target_feature,
1072         target_feature_11,
1073         target_has_atomic,
1074         target_has_atomic_equal_alignment,
1075         target_has_atomic_load_store,
1076         target_os,
1077         target_pointer_width,
1078         target_target_vendor,
1079         target_thread_local,
1080         target_vendor,
1081         task,
1082         tbm_target_feature,
1083         termination,
1084         termination_trait,
1085         termination_trait_test,
1086         test,
1087         test_2018_feature,
1088         test_accepted_feature,
1089         test_case,
1090         test_removed_feature,
1091         test_runner,
1092         then_with,
1093         thread,
1094         thread_local,
1095         tool_attributes,
1096         tool_lints,
1097         trace_macros,
1098         track_caller,
1099         trait_alias,
1100         transmute,
1101         transparent,
1102         transparent_enums,
1103         transparent_unions,
1104         trivial_bounds,
1105         truncf32,
1106         truncf64,
1107         try_blocks,
1108         try_trait,
1109         tt,
1110         tuple,
1111         tuple_indexing,
1112         two_phase,
1113         ty,
1114         type_alias_enum_variants,
1115         type_alias_impl_trait,
1116         type_ascription,
1117         type_id,
1118         type_length_limit,
1119         type_macros,
1120         type_name,
1121         u128,
1122         u16,
1123         u32,
1124         u64,
1125         u8,
1126         unaligned_volatile_load,
1127         unaligned_volatile_store,
1128         unboxed_closures,
1129         unchecked_add,
1130         unchecked_div,
1131         unchecked_mul,
1132         unchecked_rem,
1133         unchecked_shl,
1134         unchecked_shr,
1135         unchecked_sub,
1136         underscore_const_names,
1137         underscore_imports,
1138         underscore_lifetimes,
1139         uniform_paths,
1140         unit,
1141         universal_impl_trait,
1142         unix,
1143         unlikely,
1144         unmarked_api,
1145         unpin,
1146         unreachable,
1147         unreachable_code,
1148         unrestricted_attribute_tokens,
1149         unsafe_block_in_unsafe_fn,
1150         unsafe_cell,
1151         unsafe_no_drop_flag,
1152         unsize,
1153         unsized_locals,
1154         unsized_tuple_coercion,
1155         unstable,
1156         untagged_unions,
1157         unused_qualifications,
1158         unwind,
1159         unwind_attributes,
1160         unwrap_or,
1161         use_extern_macros,
1162         use_nested_groups,
1163         used,
1164         usize,
1165         v1,
1166         va_arg,
1167         va_copy,
1168         va_end,
1169         va_list,
1170         va_start,
1171         val,
1172         var,
1173         variant_count,
1174         vec,
1175         vec_type,
1176         version,
1177         vis,
1178         visible_private_types,
1179         volatile,
1180         volatile_copy_memory,
1181         volatile_copy_nonoverlapping_memory,
1182         volatile_load,
1183         volatile_set_memory,
1184         volatile_store,
1185         warn,
1186         wasm_import_module,
1187         wasm_target_feature,
1188         while_let,
1189         width,
1190         windows,
1191         windows_subsystem,
1192         wrapping_add,
1193         wrapping_mul,
1194         wrapping_sub,
1195         write_bytes,
1196     }
1197 }
1198
1199 #[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
1200 pub struct Ident {
1201     pub name: Symbol,
1202     pub span: Span,
1203 }
1204
1205 impl Ident {
1206     #[inline]
1207     /// Constructs a new identifier from a symbol and a span.
1208     pub const fn new(name: Symbol, span: Span) -> Ident {
1209         Ident { name, span }
1210     }
1211
1212     /// Constructs a new identifier with a dummy span.
1213     #[inline]
1214     pub const fn with_dummy_span(name: Symbol) -> Ident {
1215         Ident::new(name, DUMMY_SP)
1216     }
1217
1218     #[inline]
1219     pub fn invalid() -> Ident {
1220         Ident::with_dummy_span(kw::Invalid)
1221     }
1222
1223     /// Maps a string to an identifier with a dummy span.
1224     pub fn from_str(string: &str) -> Ident {
1225         Ident::with_dummy_span(Symbol::intern(string))
1226     }
1227
1228     /// Maps a string and a span to an identifier.
1229     pub fn from_str_and_span(string: &str, span: Span) -> Ident {
1230         Ident::new(Symbol::intern(string), span)
1231     }
1232
1233     /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
1234     pub fn with_span_pos(self, span: Span) -> Ident {
1235         Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
1236     }
1237
1238     pub fn without_first_quote(self) -> Ident {
1239         Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
1240     }
1241
1242     /// "Normalize" ident for use in comparisons using "item hygiene".
1243     /// Identifiers with same string value become same if they came from the same macro 2.0 macro
1244     /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
1245     /// different macro 2.0 macros.
1246     /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
1247     pub fn normalize_to_macros_2_0(self) -> Ident {
1248         Ident::new(self.name, self.span.normalize_to_macros_2_0())
1249     }
1250
1251     /// "Normalize" ident for use in comparisons using "local variable hygiene".
1252     /// Identifiers with same string value become same if they came from the same non-transparent
1253     /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
1254     /// non-transparent macros.
1255     /// Technically, this operation strips all transparent marks from ident's syntactic context.
1256     pub fn normalize_to_macro_rules(self) -> Ident {
1257         Ident::new(self.name, self.span.normalize_to_macro_rules())
1258     }
1259
1260     /// Convert the name to a `SymbolStr`. This is a slowish operation because
1261     /// it requires locking the symbol interner.
1262     pub fn as_str(self) -> SymbolStr {
1263         self.name.as_str()
1264     }
1265 }
1266
1267 impl PartialEq for Ident {
1268     fn eq(&self, rhs: &Self) -> bool {
1269         self.name == rhs.name && self.span.ctxt() == rhs.span.ctxt()
1270     }
1271 }
1272
1273 impl Hash for Ident {
1274     fn hash<H: Hasher>(&self, state: &mut H) {
1275         self.name.hash(state);
1276         self.span.ctxt().hash(state);
1277     }
1278 }
1279
1280 impl fmt::Debug for Ident {
1281     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1282         fmt::Display::fmt(self, f)?;
1283         fmt::Debug::fmt(&self.span.ctxt(), f)
1284     }
1285 }
1286
1287 /// This implementation is supposed to be used in error messages, so it's expected to be identical
1288 /// to printing the original identifier token written in source code (`token_to_string`),
1289 /// except that AST identifiers don't keep the rawness flag, so we have to guess it.
1290 impl fmt::Display for Ident {
1291     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1292         fmt::Display::fmt(&IdentPrinter::new(self.name, self.is_raw_guess(), None), f)
1293     }
1294 }
1295
1296 /// This is the most general way to print identifiers.
1297 /// AST pretty-printer is used as a fallback for turning AST structures into token streams for
1298 /// proc macros. Additionally, proc macros may stringify their input and expect it survive the
1299 /// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
1300 /// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
1301 /// hygiene data, most importantly name of the crate it refers to.
1302 /// As a result we print `$crate` as `crate` if it refers to the local crate
1303 /// and as `::other_crate_name` if it refers to some other crate.
1304 /// Note, that this is only done if the ident token is printed from inside of AST pretty-pringing,
1305 /// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
1306 /// so we should not perform this lossy conversion if the top level call to the pretty-printer was
1307 /// done for a token stream or a single token.
1308 pub struct IdentPrinter {
1309     symbol: Symbol,
1310     is_raw: bool,
1311     /// Span used for retrieving the crate name to which `$crate` refers to,
1312     /// if this field is `None` then the `$crate` conversion doesn't happen.
1313     convert_dollar_crate: Option<Span>,
1314 }
1315
1316 impl IdentPrinter {
1317     /// The most general `IdentPrinter` constructor. Do not use this.
1318     pub fn new(symbol: Symbol, is_raw: bool, convert_dollar_crate: Option<Span>) -> IdentPrinter {
1319         IdentPrinter { symbol, is_raw, convert_dollar_crate }
1320     }
1321
1322     /// This implementation is supposed to be used when printing identifiers
1323     /// as a part of pretty-printing for larger AST pieces.
1324     /// Do not use this either.
1325     pub fn for_ast_ident(ident: Ident, is_raw: bool) -> IdentPrinter {
1326         IdentPrinter::new(ident.name, is_raw, Some(ident.span))
1327     }
1328 }
1329
1330 impl fmt::Display for IdentPrinter {
1331     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1332         if self.is_raw {
1333             f.write_str("r#")?;
1334         } else {
1335             if self.symbol == kw::DollarCrate {
1336                 if let Some(span) = self.convert_dollar_crate {
1337                     let converted = span.ctxt().dollar_crate_name();
1338                     if !converted.is_path_segment_keyword() {
1339                         f.write_str("::")?;
1340                     }
1341                     return fmt::Display::fmt(&converted, f);
1342                 }
1343             }
1344         }
1345         fmt::Display::fmt(&self.symbol, f)
1346     }
1347 }
1348
1349 /// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
1350 /// construction.
1351 // FIXME(matthewj, petrochenkov) Use this more often, add a similar
1352 // `ModernIdent` struct and use that as well.
1353 #[derive(Copy, Clone, Eq, PartialEq, Hash)]
1354 pub struct MacroRulesNormalizedIdent(Ident);
1355
1356 impl MacroRulesNormalizedIdent {
1357     pub fn new(ident: Ident) -> Self {
1358         Self(ident.normalize_to_macro_rules())
1359     }
1360 }
1361
1362 impl fmt::Debug for MacroRulesNormalizedIdent {
1363     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1364         fmt::Debug::fmt(&self.0, f)
1365     }
1366 }
1367
1368 impl fmt::Display for MacroRulesNormalizedIdent {
1369     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1370         fmt::Display::fmt(&self.0, f)
1371     }
1372 }
1373
1374 /// An interned string.
1375 ///
1376 /// Internally, a `Symbol` is implemented as an index, and all operations
1377 /// (including hashing, equality, and ordering) operate on that index. The use
1378 /// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
1379 /// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
1380 ///
1381 /// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
1382 /// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
1383 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1384 pub struct Symbol(SymbolIndex);
1385
1386 rustc_index::newtype_index! {
1387     pub struct SymbolIndex { .. }
1388 }
1389
1390 impl Symbol {
1391     const fn new(n: u32) -> Self {
1392         Symbol(SymbolIndex::from_u32(n))
1393     }
1394
1395     /// Maps a string to its interned representation.
1396     pub fn intern(string: &str) -> Self {
1397         with_interner(|interner| interner.intern(string))
1398     }
1399
1400     /// Access the symbol's chars. This is a slowish operation because it
1401     /// requires locking the symbol interner.
1402     pub fn with<F: FnOnce(&str) -> R, R>(self, f: F) -> R {
1403         with_interner(|interner| f(interner.get(self)))
1404     }
1405
1406     /// Convert to a `SymbolStr`. This is a slowish operation because it
1407     /// requires locking the symbol interner.
1408     pub fn as_str(self) -> SymbolStr {
1409         with_interner(|interner| unsafe {
1410             SymbolStr { string: std::mem::transmute::<&str, &str>(interner.get(self)) }
1411         })
1412     }
1413
1414     pub fn as_u32(self) -> u32 {
1415         self.0.as_u32()
1416     }
1417
1418     /// This method is supposed to be used in error messages, so it's expected to be
1419     /// identical to printing the original identifier token written in source code
1420     /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
1421     /// or edition, so we have to guess the rawness using the global edition.
1422     pub fn to_ident_string(self) -> String {
1423         Ident::with_dummy_span(self).to_string()
1424     }
1425 }
1426
1427 impl fmt::Debug for Symbol {
1428     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1429         self.with(|str| fmt::Debug::fmt(&str, f))
1430     }
1431 }
1432
1433 impl fmt::Display for Symbol {
1434     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1435         self.with(|str| fmt::Display::fmt(&str, f))
1436     }
1437 }
1438
1439 impl<S: Encoder> Encodable<S> for Symbol {
1440     fn encode(&self, s: &mut S) -> Result<(), S::Error> {
1441         self.with(|string| s.emit_str(string))
1442     }
1443 }
1444
1445 impl<D: Decoder> Decodable<D> for Symbol {
1446     #[inline]
1447     fn decode(d: &mut D) -> Result<Symbol, D::Error> {
1448         Ok(Symbol::intern(&d.read_str()?))
1449     }
1450 }
1451
1452 impl<CTX> HashStable<CTX> for Symbol {
1453     #[inline]
1454     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1455         self.as_str().hash_stable(hcx, hasher);
1456     }
1457 }
1458
1459 impl<CTX> ToStableHashKey<CTX> for Symbol {
1460     type KeyType = SymbolStr;
1461
1462     #[inline]
1463     fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1464         self.as_str()
1465     }
1466 }
1467
1468 // The `&'static str`s in this type actually point into the arena.
1469 //
1470 // The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
1471 // found that to regress performance up to 2% in some cases. This might be
1472 // revisited after further improvements to `indexmap`.
1473 #[derive(Default)]
1474 pub struct Interner {
1475     arena: DroplessArena,
1476     names: FxHashMap<&'static str, Symbol>,
1477     strings: Vec<&'static str>,
1478 }
1479
1480 impl Interner {
1481     fn prefill(init: &[&'static str]) -> Self {
1482         Interner {
1483             strings: init.into(),
1484             names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
1485             ..Default::default()
1486         }
1487     }
1488
1489     #[inline]
1490     pub fn intern(&mut self, string: &str) -> Symbol {
1491         if let Some(&name) = self.names.get(string) {
1492             return name;
1493         }
1494
1495         let name = Symbol::new(self.strings.len() as u32);
1496
1497         // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
1498         // UTF-8.
1499         let string: &str =
1500             unsafe { str::from_utf8_unchecked(self.arena.alloc_slice(string.as_bytes())) };
1501         // It is safe to extend the arena allocation to `'static` because we only access
1502         // these while the arena is still alive.
1503         let string: &'static str = unsafe { &*(string as *const str) };
1504         self.strings.push(string);
1505         self.names.insert(string, name);
1506         name
1507     }
1508
1509     // Get the symbol as a string. `Symbol::as_str()` should be used in
1510     // preference to this function.
1511     pub fn get(&self, symbol: Symbol) -> &str {
1512         self.strings[symbol.0.as_usize()]
1513     }
1514 }
1515
1516 // This module has a very short name because it's used a lot.
1517 /// This module contains all the defined keyword `Symbol`s.
1518 ///
1519 /// Given that `kw` is imported, use them like `kw::keyword_name`.
1520 /// For example `kw::Loop` or `kw::Break`.
1521 pub mod kw {
1522     use super::Symbol;
1523     keywords!();
1524 }
1525
1526 // This module has a very short name because it's used a lot.
1527 /// This module contains all the defined non-keyword `Symbol`s.
1528 ///
1529 /// Given that `sym` is imported, use them like `sym::symbol_name`.
1530 /// For example `sym::rustfmt` or `sym::u8`.
1531 #[allow(rustc::default_hash_types)]
1532 pub mod sym {
1533     use super::Symbol;
1534     use std::convert::TryInto;
1535
1536     define_symbols!();
1537
1538     // Used from a macro in `librustc_feature/accepted.rs`
1539     pub use super::kw::MacroRules as macro_rules;
1540
1541     // Get the symbol for an integer. The first few non-negative integers each
1542     // have a static symbol and therefore are fast.
1543     pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
1544         if let Result::Ok(idx) = n.try_into() {
1545             if let Option::Some(&sym_) = digits_array.get(idx) {
1546                 return sym_;
1547             }
1548         }
1549         Symbol::intern(&n.to_string())
1550     }
1551 }
1552
1553 impl Symbol {
1554     fn is_used_keyword_2018(self) -> bool {
1555         self >= kw::Async && self <= kw::Dyn
1556     }
1557
1558     fn is_unused_keyword_2018(self) -> bool {
1559         self == kw::Try
1560     }
1561
1562     /// Used for sanity checking rustdoc keyword sections.
1563     pub fn is_doc_keyword(self) -> bool {
1564         self <= kw::Union
1565     }
1566
1567     /// A keyword or reserved identifier that can be used as a path segment.
1568     pub fn is_path_segment_keyword(self) -> bool {
1569         self == kw::Super
1570             || self == kw::SelfLower
1571             || self == kw::SelfUpper
1572             || self == kw::Crate
1573             || self == kw::PathRoot
1574             || self == kw::DollarCrate
1575     }
1576
1577     /// Returns `true` if the symbol is `true` or `false`.
1578     pub fn is_bool_lit(self) -> bool {
1579         self == kw::True || self == kw::False
1580     }
1581
1582     /// This symbol can be a raw identifier.
1583     pub fn can_be_raw(self) -> bool {
1584         self != kw::Invalid && self != kw::Underscore && !self.is_path_segment_keyword()
1585     }
1586 }
1587
1588 impl Ident {
1589     // Returns `true` for reserved identifiers used internally for elided lifetimes,
1590     // unnamed method parameters, crate root module, error recovery etc.
1591     pub fn is_special(self) -> bool {
1592         self.name <= kw::Underscore
1593     }
1594
1595     /// Returns `true` if the token is a keyword used in the language.
1596     pub fn is_used_keyword(self) -> bool {
1597         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1598         self.name >= kw::As && self.name <= kw::While
1599             || self.name.is_used_keyword_2018() && self.span.rust_2018()
1600     }
1601
1602     /// Returns `true` if the token is a keyword reserved for possible future use.
1603     pub fn is_unused_keyword(self) -> bool {
1604         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1605         self.name >= kw::Abstract && self.name <= kw::Yield
1606             || self.name.is_unused_keyword_2018() && self.span.rust_2018()
1607     }
1608
1609     /// Returns `true` if the token is either a special identifier or a keyword.
1610     pub fn is_reserved(self) -> bool {
1611         self.is_special() || self.is_used_keyword() || self.is_unused_keyword()
1612     }
1613
1614     /// A keyword or reserved identifier that can be used as a path segment.
1615     pub fn is_path_segment_keyword(self) -> bool {
1616         self.name.is_path_segment_keyword()
1617     }
1618
1619     /// We see this identifier in a normal identifier position, like variable name or a type.
1620     /// How was it written originally? Did it use the raw form? Let's try to guess.
1621     pub fn is_raw_guess(self) -> bool {
1622         self.name.can_be_raw() && self.is_reserved()
1623     }
1624 }
1625
1626 #[inline]
1627 fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
1628     SESSION_GLOBALS.with(|session_globals| f(&mut *session_globals.symbol_interner.lock()))
1629 }
1630
1631 /// An alternative to `Symbol`, useful when the chars within the symbol need to
1632 /// be accessed. It deliberately has limited functionality and should only be
1633 /// used for temporary values.
1634 ///
1635 /// Because the interner outlives any thread which uses this type, we can
1636 /// safely treat `string` which points to interner data, as an immortal string,
1637 /// as long as this type never crosses between threads.
1638 //
1639 // FIXME: ensure that the interner outlives any thread which uses `SymbolStr`,
1640 // by creating a new thread right after constructing the interner.
1641 #[derive(Clone, Eq, PartialOrd, Ord)]
1642 pub struct SymbolStr {
1643     string: &'static str,
1644 }
1645
1646 // This impl allows a `SymbolStr` to be directly equated with a `String` or
1647 // `&str`.
1648 impl<T: std::ops::Deref<Target = str>> std::cmp::PartialEq<T> for SymbolStr {
1649     fn eq(&self, other: &T) -> bool {
1650         self.string == other.deref()
1651     }
1652 }
1653
1654 impl !Send for SymbolStr {}
1655 impl !Sync for SymbolStr {}
1656
1657 /// This impl means that if `ss` is a `SymbolStr`:
1658 /// - `*ss` is a `str`;
1659 /// - `&*ss` is a `&str` (and `match &*ss { ... }` is a common pattern).
1660 /// - `&ss as &str` is a `&str`, which means that `&ss` can be passed to a
1661 ///   function expecting a `&str`.
1662 impl std::ops::Deref for SymbolStr {
1663     type Target = str;
1664     #[inline]
1665     fn deref(&self) -> &str {
1666         self.string
1667     }
1668 }
1669
1670 impl fmt::Debug for SymbolStr {
1671     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1672         fmt::Debug::fmt(self.string, f)
1673     }
1674 }
1675
1676 impl fmt::Display for SymbolStr {
1677     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1678         fmt::Display::fmt(self.string, f)
1679     }
1680 }
1681
1682 impl<CTX> HashStable<CTX> for SymbolStr {
1683     #[inline]
1684     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1685         self.string.hash_stable(hcx, hasher)
1686     }
1687 }
1688
1689 impl<CTX> ToStableHashKey<CTX> for SymbolStr {
1690     type KeyType = SymbolStr;
1691
1692     #[inline]
1693     fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1694         self.clone()
1695     }
1696 }