]> git.lizzy.rs Git - rust.git/blob - src/librustc_span/symbol.rs
d165409696ecab418e73785329d5cfbc565a9b42
[rust.git] / src / librustc_span / symbol.rs
1 //! An "interner" is a data structure that associates values with usize tags and
2 //! allows bidirectional lookup; i.e., given a value, one can easily find the
3 //! type, and vice versa.
4
5 use rustc_arena::DroplessArena;
6 use rustc_data_structures::fx::FxHashMap;
7 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
8 use rustc_macros::{symbols, HashStable_Generic};
9 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
10 use rustc_serialize::{UseSpecializedDecodable, UseSpecializedEncodable};
11
12 use std::cmp::{Ord, PartialEq, PartialOrd};
13 use std::fmt;
14 use std::hash::{Hash, Hasher};
15 use std::str;
16
17 use crate::{Span, DUMMY_SP, GLOBALS};
18
19 #[cfg(test)]
20 mod tests;
21
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     // Symbols that can be referred to with rustc_span::sym::*. The symbol is
106     // the stringified identifier unless otherwise specified (e.g.
107     // `proc_dash_macro` represents "proc-macro").
108     //
109     // As well as the symbols listed, there are symbols for the the strings
110     // "0", "1", ..., "9", which are accessible via `sym::integer`.
111     Symbols {
112         aarch64_target_feature,
113         abi,
114         abi_amdgpu_kernel,
115         abi_efiapi,
116         abi_msp430_interrupt,
117         abi_ptx,
118         abi_sysv64,
119         abi_thiscall,
120         abi_unadjusted,
121         abi_vectorcall,
122         abi_x86_interrupt,
123         abort,
124         aborts,
125         address,
126         add_with_overflow,
127         advanced_slice_patterns,
128         adx_target_feature,
129         alias,
130         align,
131         alignstack,
132         all,
133         allocator,
134         allocator_internals,
135         alloc_error_handler,
136         allow,
137         allowed,
138         allow_fail,
139         allow_internal_unsafe,
140         allow_internal_unstable,
141         allow_internal_unstable_backcompat_hack,
142         always,
143         and,
144         any,
145         arbitrary_enum_discriminant,
146         arbitrary_self_types,
147         Arc,
148         Arguments,
149         ArgumentV1,
150         arith_offset,
151         arm_target_feature,
152         asm,
153         assert,
154         associated_consts,
155         associated_type_bounds,
156         associated_type_defaults,
157         associated_types,
158         assume_init,
159         async_await,
160         async_closure,
161         attr,
162         attributes,
163         attr_literals,
164         att_syntax,
165         augmented_assignments,
166         automatically_derived,
167         avx512_target_feature,
168         await_macro,
169         begin_panic,
170         bench,
171         bin,
172         bind_by_move_pattern_guards,
173         bindings_after_at,
174         block,
175         bool,
176         borrowck_graphviz_format,
177         borrowck_graphviz_postflow,
178         borrowck_graphviz_preflow,
179         box_patterns,
180         box_syntax,
181         braced_empty_structs,
182         bswap,
183         bitreverse,
184         C,
185         caller_location,
186         cdylib,
187         cfg,
188         cfg_accessible,
189         cfg_attr,
190         cfg_attr_multi,
191         cfg_doctest,
192         cfg_sanitize,
193         cfg_target_feature,
194         cfg_target_has_atomic,
195         cfg_target_thread_local,
196         cfg_target_vendor,
197         cfg_version,
198         char,
199         clippy,
200         clone,
201         Clone,
202         clone_closures,
203         clone_from,
204         closure_to_fn_coercion,
205         cmp,
206         cmpxchg16b_target_feature,
207         cold,
208         column,
209         compile_error,
210         compiler_builtins,
211         concat,
212         concat_idents,
213         conservative_impl_trait,
214         console,
215         const_compare_raw_pointers,
216         const_constructor,
217         const_eval_limit,
218         const_extern_fn,
219         const_fn,
220         const_fn_union,
221         const_generics,
222         const_if_match,
223         const_indexing,
224         const_in_array_repeat_expressions,
225         const_let,
226         const_loop,
227         const_mut_refs,
228         const_panic,
229         const_raw_ptr_deref,
230         const_raw_ptr_to_usize_cast,
231         const_transmute,
232         const_trait_bound_opt_out,
233         const_trait_impl,
234         contents,
235         context,
236         convert,
237         Copy,
238         copy_closures,
239         core,
240         core_intrinsics,
241         crate_id,
242         crate_in_paths,
243         crate_local,
244         crate_name,
245         crate_type,
246         crate_visibility_modifier,
247         ctpop,
248         cttz,
249         cttz_nonzero,
250         ctlz,
251         ctlz_nonzero,
252         custom_attribute,
253         custom_derive,
254         custom_inner_attributes,
255         custom_test_frameworks,
256         c_variadic,
257         debug_trait,
258         declare_lint_pass,
259         decl_macro,
260         debug,
261         Debug,
262         Decodable,
263         Default,
264         default_lib_allocator,
265         default_type_parameter_fallback,
266         default_type_params,
267         delay_span_bug_from_inside_query,
268         deny,
269         deprecated,
270         deref,
271         deref_mut,
272         derive,
273         diagnostic,
274         direct,
275         discriminant_value,
276         doc,
277         doc_alias,
278         doc_cfg,
279         doc_keyword,
280         doc_masked,
281         doctest,
282         document_private_items,
283         dotdoteq_in_patterns,
284         dotdot_in_tuple_patterns,
285         double_braced_crate: "{{crate}}",
286         double_braced_impl: "{{impl}}",
287         double_braced_misc: "{{misc}}",
288         double_braced_closure: "{{closure}}",
289         double_braced_constructor: "{{constructor}}",
290         double_braced_constant: "{{constant}}",
291         double_braced_opaque: "{{opaque}}",
292         dropck_eyepatch,
293         dropck_parametricity,
294         drop_types_in_const,
295         dylib,
296         dyn_trait,
297         eh_personality,
298         enable,
299         Encodable,
300         env,
301         eq,
302         err,
303         Err,
304         Eq,
305         Equal,
306         enclosing_scope,
307         except,
308         exclusive_range_pattern,
309         exhaustive_integer_patterns,
310         exhaustive_patterns,
311         existential_type,
312         expected,
313         export_name,
314         expr,
315         extern_absolute_paths,
316         external_doc,
317         extern_crate_item_prelude,
318         extern_crate_self,
319         extern_in_paths,
320         extern_prelude,
321         extern_types,
322         f16c_target_feature,
323         f32,
324         f64,
325         feature,
326         ffi_const,
327         ffi_pure,
328         ffi_returns_twice,
329         field,
330         field_init_shorthand,
331         file,
332         fmt,
333         fmt_internals,
334         fn_must_use,
335         forbid,
336         format_args,
337         format_args_nl,
338         from,
339         From,
340         from_desugaring,
341         from_error,
342         from_generator,
343         from_method,
344         from_ok,
345         from_usize,
346         fundamental,
347         future,
348         Future,
349         FxHashSet,
350         FxHashMap,
351         gen_future,
352         gen_kill,
353         generators,
354         generic_associated_types,
355         generic_param_attrs,
356         get_context,
357         global_allocator,
358         global_asm,
359         globs,
360         half_open_range_patterns,
361         hash,
362         Hash,
363         HashSet,
364         HashMap,
365         hexagon_target_feature,
366         hidden,
367         homogeneous_aggregate,
368         html_favicon_url,
369         html_logo_url,
370         html_no_source,
371         html_playground_url,
372         html_root_url,
373         i128,
374         i128_type,
375         i16,
376         i32,
377         i64,
378         i8,
379         ident,
380         if_let,
381         if_while_or_patterns,
382         ignore,
383         inlateout,
384         inout,
385         impl_header_lifetime_elision,
386         impl_lint_pass,
387         impl_trait_in_bindings,
388         import_shadowing,
389         index,
390         index_mut,
391         in_band_lifetimes,
392         include,
393         include_bytes,
394         include_str,
395         inclusive_range_syntax,
396         infer_outlives_requirements,
397         infer_static_outlives_requirements,
398         inline,
399         intel,
400         into_iter,
401         IntoIterator,
402         into_result,
403         intrinsics,
404         irrefutable_let_patterns,
405         isize,
406         issue,
407         issue_5723_bootstrap,
408         issue_tracker_base_url,
409         item,
410         item_context: "ItemContext",
411         item_like_imports,
412         iter,
413         Iterator,
414         keyword,
415         kind,
416         label,
417         label_break_value,
418         lang,
419         lang_items,
420         lateout,
421         let_chains,
422         lhs,
423         lib,
424         lifetime,
425         line,
426         link,
427         linkage,
428         link_args,
429         link_cfg,
430         link_llvm_intrinsics,
431         link_name,
432         link_ordinal,
433         link_section,
434         LintPass,
435         lint_reasons,
436         literal,
437         llvm_asm,
438         local_inner_macros,
439         log_syntax,
440         loop_break_value,
441         macro_at_most_once_rep,
442         macro_escape,
443         macro_export,
444         macro_lifetime_matcher,
445         macro_literal_matcher,
446         macro_reexport,
447         macros_in_extern,
448         macro_use,
449         macro_vis_matcher,
450         main,
451         managed_boxes,
452         marker,
453         marker_trait_attr,
454         masked,
455         match_beginning_vert,
456         match_default_bindings,
457         may_dangle,
458         maybe_uninit_uninit,
459         maybe_uninit_zeroed,
460         mem_uninitialized,
461         mem_zeroed,
462         member_constraints,
463         memory,
464         message,
465         meta,
466         min_align_of,
467         min_const_fn,
468         min_const_unsafe_fn,
469         min_specialization,
470         mips_target_feature,
471         mmx_target_feature,
472         module,
473         module_path,
474         more_struct_aliases,
475         move_ref_pattern,
476         move_val_init,
477         movbe_target_feature,
478         mul_with_overflow,
479         must_use,
480         naked,
481         naked_functions,
482         name,
483         needs_allocator,
484         needs_drop,
485         needs_panic_runtime,
486         negate_unsigned,
487         negative_impls,
488         never,
489         never_type,
490         never_type_fallback,
491         new,
492         next,
493         __next,
494         nll,
495         no_builtins,
496         no_core,
497         no_crate_inject,
498         no_debug,
499         no_default_passes,
500         no_implicit_prelude,
501         no_inline,
502         no_link,
503         no_main,
504         no_mangle,
505         nomem,
506         non_ascii_idents,
507         None,
508         non_exhaustive,
509         non_modrs_mods,
510         noreturn,
511         no_niche,
512         no_sanitize,
513         nostack,
514         no_stack_check,
515         no_start,
516         no_std,
517         not,
518         note,
519         object_safe_for_dispatch,
520         offset,
521         Ok,
522         omit_gdb_pretty_printer_section,
523         on,
524         on_unimplemented,
525         oom,
526         ops,
527         optimize,
528         optimize_attribute,
529         optin_builtin_traits,
530         option,
531         Option,
532         option_env,
533         options,
534         opt_out_copy,
535         or,
536         or_patterns,
537         Ord,
538         Ordering,
539         out,
540         Output,
541         overlapping_marker_traits,
542         packed,
543         panic,
544         panic_handler,
545         panic_impl,
546         panic_implementation,
547         panic_runtime,
548         parent_trait,
549         partial_cmp,
550         param_attrs,
551         PartialEq,
552         PartialOrd,
553         passes,
554         pat,
555         path,
556         pattern_parentheses,
557         Pending,
558         pin,
559         Pin,
560         pinned,
561         platform_intrinsics,
562         plugin,
563         plugin_registrar,
564         plugins,
565         poll,
566         Poll,
567         powerpc_target_feature,
568         precise_pointer_size_matching,
569         pref_align_of,
570         prelude,
571         prelude_import,
572         preserves_flags,
573         primitive,
574         proc_dash_macro: "proc-macro",
575         proc_macro,
576         proc_macro_attribute,
577         proc_macro_def_site,
578         proc_macro_derive,
579         proc_macro_expr,
580         proc_macro_gen,
581         proc_macro_hygiene,
582         proc_macro_internals,
583         proc_macro_mod,
584         proc_macro_non_items,
585         proc_macro_path_invoc,
586         profiler_runtime,
587         ptr_offset_from,
588         pub_restricted,
589         pure,
590         pushpop_unsafe,
591         quad_precision_float,
592         question_mark,
593         quote,
594         Range,
595         RangeFrom,
596         RangeFull,
597         RangeInclusive,
598         RangeTo,
599         RangeToInclusive,
600         raw_dylib,
601         raw_identifiers,
602         raw_ref_op,
603         Rc,
604         readonly,
605         Ready,
606         reason,
607         recursion_limit,
608         reexport_test_harness_main,
609         reflect,
610         register_attr,
611         register_tool,
612         relaxed_adts,
613         repr,
614         repr128,
615         repr_align,
616         repr_align_enum,
617         repr_no_niche,
618         repr_packed,
619         repr_simd,
620         repr_transparent,
621         re_rebalance_coherence,
622         result,
623         Result,
624         Return,
625         rhs,
626         riscv_target_feature,
627         rlib,
628         rotate_left,
629         rotate_right,
630         rt,
631         rtm_target_feature,
632         rust,
633         rust_2015_preview,
634         rust_2018_preview,
635         rust_begin_unwind,
636         rustc,
637         RustcDecodable,
638         RustcEncodable,
639         rustc_allocator,
640         rustc_allocator_nounwind,
641         rustc_allow_const_fn_ptr,
642         rustc_args_required_const,
643         rustc_attrs,
644         rustc_builtin_macro,
645         rustc_clean,
646         rustc_const_unstable,
647         rustc_const_stable,
648         rustc_conversion_suggestion,
649         rustc_def_path,
650         rustc_deprecated,
651         rustc_diagnostic_item,
652         rustc_diagnostic_macros,
653         rustc_dirty,
654         rustc_dummy,
655         rustc_dump_env_program_clauses,
656         rustc_dump_program_clauses,
657         rustc_dump_user_substs,
658         rustc_error,
659         rustc_expected_cgu_reuse,
660         rustc_if_this_changed,
661         rustc_inherit_overflow_checks,
662         rustc_layout,
663         rustc_layout_scalar_valid_range_end,
664         rustc_layout_scalar_valid_range_start,
665         rustc_macro_transparency,
666         rustc_mir,
667         rustc_nonnull_optimization_guaranteed,
668         rustc_object_lifetime_default,
669         rustc_on_unimplemented,
670         rustc_outlives,
671         rustc_paren_sugar,
672         rustc_partition_codegened,
673         rustc_partition_reused,
674         rustc_peek,
675         rustc_peek_definite_init,
676         rustc_peek_liveness,
677         rustc_peek_maybe_init,
678         rustc_peek_maybe_uninit,
679         rustc_peek_indirectly_mutable,
680         rustc_private,
681         rustc_proc_macro_decls,
682         rustc_promotable,
683         rustc_regions,
684         rustc_unsafe_specialization_marker,
685         rustc_specialization_trait,
686         rustc_stable,
687         rustc_std_internal_symbol,
688         rustc_symbol_name,
689         rustc_synthetic,
690         rustc_reservation_impl,
691         rustc_test_marker,
692         rustc_then_this_would_need,
693         rustc_variance,
694         rustfmt,
695         rust_eh_personality,
696         rust_oom,
697         rvalue_static_promotion,
698         sanitize,
699         sanitizer_runtime,
700         saturating_add,
701         saturating_sub,
702         _Self,
703         self_in_typedefs,
704         self_struct_ctor,
705         send_trait,
706         should_panic,
707         simd,
708         simd_extract,
709         simd_ffi,
710         simd_insert,
711         since,
712         size,
713         size_of,
714         slice_patterns,
715         slicing_syntax,
716         soft,
717         Some,
718         specialization,
719         speed,
720         sse4a_target_feature,
721         stable,
722         staged_api,
723         start,
724         static_in_const,
725         staticlib,
726         static_nobundle,
727         static_recursion,
728         std,
729         std_inject,
730         str,
731         stringify,
732         stmt,
733         stmt_expr_attributes,
734         stop_after_dataflow,
735         struct_field_attributes,
736         struct_inherit,
737         structural_match,
738         struct_variant,
739         sty,
740         sub_with_overflow,
741         suggestion,
742         sym,
743         sync_trait,
744         target_feature,
745         target_feature_11,
746         target_has_atomic,
747         target_has_atomic_load_store,
748         target_thread_local,
749         task,
750         _task_context,
751         tbm_target_feature,
752         termination_trait,
753         termination_trait_test,
754         test,
755         test_2018_feature,
756         test_accepted_feature,
757         test_case,
758         test_removed_feature,
759         test_runner,
760         then_with,
761         thread,
762         thread_local,
763         tool_attributes,
764         tool_lints,
765         trace_macros,
766         track_caller,
767         trait_alias,
768         transmute,
769         transparent,
770         transparent_enums,
771         transparent_unions,
772         trivial_bounds,
773         Try,
774         try_blocks,
775         try_trait,
776         tt,
777         tuple_indexing,
778         two_phase,
779         Ty,
780         ty,
781         type_alias_impl_trait,
782         type_id,
783         type_name,
784         TyCtxt,
785         TyKind,
786         type_alias_enum_variants,
787         type_ascription,
788         type_length_limit,
789         type_macros,
790         u128,
791         u16,
792         u32,
793         u64,
794         u8,
795         unboxed_closures,
796         unchecked_add,
797         unchecked_div,
798         unchecked_mul,
799         unchecked_rem,
800         unchecked_shl,
801         unchecked_shr,
802         unchecked_sub,
803         underscore_const_names,
804         underscore_imports,
805         underscore_lifetimes,
806         uniform_paths,
807         universal_impl_trait,
808         unmarked_api,
809         unreachable_code,
810         unrestricted_attribute_tokens,
811         unsafe_block_in_unsafe_fn,
812         unsafe_no_drop_flag,
813         unsized_locals,
814         unsized_tuple_coercion,
815         unstable,
816         untagged_unions,
817         unwind,
818         unwind_attributes,
819         unwrap_or,
820         used,
821         use_extern_macros,
822         use_nested_groups,
823         usize,
824         v1,
825         val,
826         var,
827         vec,
828         Vec,
829         version,
830         vis,
831         visible_private_types,
832         volatile,
833         warn,
834         wasm_import_module,
835         wasm_target_feature,
836         while_let,
837         windows,
838         windows_subsystem,
839         wrapping_add,
840         wrapping_sub,
841         wrapping_mul,
842         Yield,
843     }
844 }
845
846 #[derive(Copy, Clone, Eq, HashStable_Generic)]
847 pub struct Ident {
848     pub name: Symbol,
849     pub span: Span,
850 }
851
852 impl Ident {
853     #[inline]
854     /// Constructs a new identifier from a symbol and a span.
855     pub const fn new(name: Symbol, span: Span) -> Ident {
856         Ident { name, span }
857     }
858
859     /// Constructs a new identifier with a dummy span.
860     #[inline]
861     pub const fn with_dummy_span(name: Symbol) -> Ident {
862         Ident::new(name, DUMMY_SP)
863     }
864
865     #[inline]
866     pub fn invalid() -> Ident {
867         Ident::with_dummy_span(kw::Invalid)
868     }
869
870     /// Maps a string to an identifier with a dummy span.
871     pub fn from_str(string: &str) -> Ident {
872         Ident::with_dummy_span(Symbol::intern(string))
873     }
874
875     /// Maps a string and a span to an identifier.
876     pub fn from_str_and_span(string: &str, span: Span) -> Ident {
877         Ident::new(Symbol::intern(string), span)
878     }
879
880     /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
881     pub fn with_span_pos(self, span: Span) -> Ident {
882         Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
883     }
884
885     pub fn without_first_quote(self) -> Ident {
886         Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
887     }
888
889     /// "Normalize" ident for use in comparisons using "item hygiene".
890     /// Identifiers with same string value become same if they came from the same macro 2.0 macro
891     /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
892     /// different macro 2.0 macros.
893     /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
894     pub fn normalize_to_macros_2_0(self) -> Ident {
895         Ident::new(self.name, self.span.normalize_to_macros_2_0())
896     }
897
898     /// "Normalize" ident for use in comparisons using "local variable hygiene".
899     /// Identifiers with same string value become same if they came from the same non-transparent
900     /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
901     /// non-transparent macros.
902     /// Technically, this operation strips all transparent marks from ident's syntactic context.
903     pub fn normalize_to_macro_rules(self) -> Ident {
904         Ident::new(self.name, self.span.normalize_to_macro_rules())
905     }
906
907     /// Convert the name to a `SymbolStr`. This is a slowish operation because
908     /// it requires locking the symbol interner.
909     pub fn as_str(self) -> SymbolStr {
910         self.name.as_str()
911     }
912 }
913
914 impl PartialEq for Ident {
915     fn eq(&self, rhs: &Self) -> bool {
916         self.name == rhs.name && self.span.ctxt() == rhs.span.ctxt()
917     }
918 }
919
920 impl Hash for Ident {
921     fn hash<H: Hasher>(&self, state: &mut H) {
922         self.name.hash(state);
923         self.span.ctxt().hash(state);
924     }
925 }
926
927 impl fmt::Debug for Ident {
928     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
929         fmt::Display::fmt(self, f)?;
930         fmt::Debug::fmt(&self.span.ctxt(), f)
931     }
932 }
933
934 /// This implementation is supposed to be used in error messages, so it's expected to be identical
935 /// to printing the original identifier token written in source code (`token_to_string`),
936 /// except that AST identifiers don't keep the rawness flag, so we have to guess it.
937 impl fmt::Display for Ident {
938     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
939         fmt::Display::fmt(&IdentPrinter::new(self.name, self.is_raw_guess(), None), f)
940     }
941 }
942
943 impl UseSpecializedEncodable for Ident {
944     fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
945         s.emit_struct("Ident", 2, |s| {
946             s.emit_struct_field("name", 0, |s| self.name.encode(s))?;
947             s.emit_struct_field("span", 1, |s| self.span.encode(s))
948         })
949     }
950 }
951
952 impl UseSpecializedDecodable for Ident {
953     fn default_decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
954         d.read_struct("Ident", 2, |d| {
955             Ok(Ident {
956                 name: d.read_struct_field("name", 0, Decodable::decode)?,
957                 span: d.read_struct_field("span", 1, Decodable::decode)?,
958             })
959         })
960     }
961 }
962
963 /// This is the most general way to print identifiers.
964 /// AST pretty-printer is used as a fallback for turning AST structures into token streams for
965 /// proc macros. Additionally, proc macros may stringify their input and expect it survive the
966 /// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
967 /// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
968 /// hygiene data, most importantly name of the crate it refers to.
969 /// As a result we print `$crate` as `crate` if it refers to the local crate
970 /// and as `::other_crate_name` if it refers to some other crate.
971 /// Note, that this is only done if the ident token is printed from inside of AST pretty-pringing,
972 /// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
973 /// so we should not perform this lossy conversion if the top level call to the pretty-printer was
974 /// done for a token stream or a single token.
975 pub struct IdentPrinter {
976     symbol: Symbol,
977     is_raw: bool,
978     /// Span used for retrieving the crate name to which `$crate` refers to,
979     /// if this field is `None` then the `$crate` conversion doesn't happen.
980     convert_dollar_crate: Option<Span>,
981 }
982
983 impl IdentPrinter {
984     /// The most general `IdentPrinter` constructor. Do not use this.
985     pub fn new(symbol: Symbol, is_raw: bool, convert_dollar_crate: Option<Span>) -> IdentPrinter {
986         IdentPrinter { symbol, is_raw, convert_dollar_crate }
987     }
988
989     /// This implementation is supposed to be used when printing identifiers
990     /// as a part of pretty-printing for larger AST pieces.
991     /// Do not use this either.
992     pub fn for_ast_ident(ident: Ident, is_raw: bool) -> IdentPrinter {
993         IdentPrinter::new(ident.name, is_raw, Some(ident.span))
994     }
995 }
996
997 impl fmt::Display for IdentPrinter {
998     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
999         if self.is_raw {
1000             f.write_str("r#")?;
1001         } else {
1002             if self.symbol == kw::DollarCrate {
1003                 if let Some(span) = self.convert_dollar_crate {
1004                     let converted = span.ctxt().dollar_crate_name();
1005                     if !converted.is_path_segment_keyword() {
1006                         f.write_str("::")?;
1007                     }
1008                     return fmt::Display::fmt(&converted, f);
1009                 }
1010             }
1011         }
1012         fmt::Display::fmt(&self.symbol, f)
1013     }
1014 }
1015
1016 /// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
1017 /// construction.
1018 // FIXME(matthewj, petrochenkov) Use this more often, add a similar
1019 // `ModernIdent` struct and use that as well.
1020 #[derive(Copy, Clone, Eq, PartialEq, Hash)]
1021 pub struct MacroRulesNormalizedIdent(Ident);
1022
1023 impl MacroRulesNormalizedIdent {
1024     pub fn new(ident: Ident) -> Self {
1025         Self(ident.normalize_to_macro_rules())
1026     }
1027 }
1028
1029 impl fmt::Debug for MacroRulesNormalizedIdent {
1030     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1031         fmt::Debug::fmt(&self.0, f)
1032     }
1033 }
1034
1035 impl fmt::Display for MacroRulesNormalizedIdent {
1036     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1037         fmt::Display::fmt(&self.0, f)
1038     }
1039 }
1040
1041 /// An interned string.
1042 ///
1043 /// Internally, a `Symbol` is implemented as an index, and all operations
1044 /// (including hashing, equality, and ordering) operate on that index. The use
1045 /// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
1046 /// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
1047 ///
1048 /// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
1049 /// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
1050 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1051 pub struct Symbol(SymbolIndex);
1052
1053 rustc_index::newtype_index! {
1054     pub struct SymbolIndex { .. }
1055 }
1056
1057 impl Symbol {
1058     const fn new(n: u32) -> Self {
1059         Symbol(SymbolIndex::from_u32(n))
1060     }
1061
1062     /// Maps a string to its interned representation.
1063     pub fn intern(string: &str) -> Self {
1064         with_interner(|interner| interner.intern(string))
1065     }
1066
1067     /// Access the symbol's chars. This is a slowish operation because it
1068     /// requires locking the symbol interner.
1069     pub fn with<F: FnOnce(&str) -> R, R>(self, f: F) -> R {
1070         with_interner(|interner| f(interner.get(self)))
1071     }
1072
1073     /// Convert to a `SymbolStr`. This is a slowish operation because it
1074     /// requires locking the symbol interner.
1075     pub fn as_str(self) -> SymbolStr {
1076         with_interner(|interner| unsafe {
1077             SymbolStr { string: std::mem::transmute::<&str, &str>(interner.get(self)) }
1078         })
1079     }
1080
1081     pub fn as_u32(self) -> u32 {
1082         self.0.as_u32()
1083     }
1084
1085     /// This method is supposed to be used in error messages, so it's expected to be
1086     /// identical to printing the original identifier token written in source code
1087     /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
1088     /// or edition, so we have to guess the rawness using the global edition.
1089     pub fn to_ident_string(self) -> String {
1090         Ident::with_dummy_span(self).to_string()
1091     }
1092 }
1093
1094 impl fmt::Debug for Symbol {
1095     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1096         self.with(|str| fmt::Debug::fmt(&str, f))
1097     }
1098 }
1099
1100 impl fmt::Display for Symbol {
1101     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1102         self.with(|str| fmt::Display::fmt(&str, f))
1103     }
1104 }
1105
1106 impl Encodable for Symbol {
1107     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
1108         self.with(|string| s.emit_str(string))
1109     }
1110 }
1111
1112 impl Decodable for Symbol {
1113     #[inline]
1114     fn decode<D: Decoder>(d: &mut D) -> Result<Symbol, D::Error> {
1115         Ok(Symbol::intern(&d.read_str()?))
1116     }
1117 }
1118
1119 impl<CTX> HashStable<CTX> for Symbol {
1120     #[inline]
1121     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1122         self.as_str().hash_stable(hcx, hasher);
1123     }
1124 }
1125
1126 impl<CTX> ToStableHashKey<CTX> for Symbol {
1127     type KeyType = SymbolStr;
1128
1129     #[inline]
1130     fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1131         self.as_str()
1132     }
1133 }
1134
1135 // The `&'static str`s in this type actually point into the arena.
1136 #[derive(Default)]
1137 pub struct Interner {
1138     arena: DroplessArena,
1139     names: FxHashMap<&'static str, Symbol>,
1140     strings: Vec<&'static str>,
1141 }
1142
1143 impl Interner {
1144     fn prefill(init: &[&'static str]) -> Self {
1145         Interner {
1146             strings: init.into(),
1147             names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
1148             ..Default::default()
1149         }
1150     }
1151
1152     #[inline]
1153     pub fn intern(&mut self, string: &str) -> Symbol {
1154         if let Some(&name) = self.names.get(string) {
1155             return name;
1156         }
1157
1158         let name = Symbol::new(self.strings.len() as u32);
1159
1160         // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
1161         // UTF-8.
1162         let string: &str =
1163             unsafe { str::from_utf8_unchecked(self.arena.alloc_slice(string.as_bytes())) };
1164         // It is safe to extend the arena allocation to `'static` because we only access
1165         // these while the arena is still alive.
1166         let string: &'static str = unsafe { &*(string as *const str) };
1167         self.strings.push(string);
1168         self.names.insert(string, name);
1169         name
1170     }
1171
1172     // Get the symbol as a string. `Symbol::as_str()` should be used in
1173     // preference to this function.
1174     pub fn get(&self, symbol: Symbol) -> &str {
1175         self.strings[symbol.0.as_usize()]
1176     }
1177 }
1178
1179 // This module has a very short name because it's used a lot.
1180 /// This module contains all the defined keyword `Symbol`s.
1181 ///
1182 /// Given that `kw` is imported, use them like `kw::keyword_name`.
1183 /// For example `kw::Loop` or `kw::Break`.
1184 pub mod kw {
1185     use super::Symbol;
1186     keywords!();
1187 }
1188
1189 // This module has a very short name because it's used a lot.
1190 /// This module contains all the defined non-keyword `Symbol`s.
1191 ///
1192 /// Given that `sym` is imported, use them like `sym::symbol_name`.
1193 /// For example `sym::rustfmt` or `sym::u8`.
1194 #[allow(rustc::default_hash_types)]
1195 pub mod sym {
1196     use super::Symbol;
1197     use std::convert::TryInto;
1198
1199     symbols!();
1200
1201     // Used from a macro in `librustc_feature/accepted.rs`
1202     pub use super::kw::MacroRules as macro_rules;
1203
1204     // Get the symbol for an integer. The first few non-negative integers each
1205     // have a static symbol and therefore are fast.
1206     pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
1207         if let Result::Ok(idx) = n.try_into() {
1208             if let Option::Some(&sym_) = digits_array.get(idx) {
1209                 return sym_;
1210             }
1211         }
1212         Symbol::intern(&n.to_string())
1213     }
1214 }
1215
1216 impl Symbol {
1217     fn is_used_keyword_2018(self) -> bool {
1218         self >= kw::Async && self <= kw::Dyn
1219     }
1220
1221     fn is_unused_keyword_2018(self) -> bool {
1222         self == kw::Try
1223     }
1224
1225     /// Used for sanity checking rustdoc keyword sections.
1226     pub fn is_doc_keyword(self) -> bool {
1227         self <= kw::Union
1228     }
1229
1230     /// A keyword or reserved identifier that can be used as a path segment.
1231     pub fn is_path_segment_keyword(self) -> bool {
1232         self == kw::Super
1233             || self == kw::SelfLower
1234             || self == kw::SelfUpper
1235             || self == kw::Crate
1236             || self == kw::PathRoot
1237             || self == kw::DollarCrate
1238     }
1239
1240     /// Returns `true` if the symbol is `true` or `false`.
1241     pub fn is_bool_lit(self) -> bool {
1242         self == kw::True || self == kw::False
1243     }
1244
1245     /// This symbol can be a raw identifier.
1246     pub fn can_be_raw(self) -> bool {
1247         self != kw::Invalid && self != kw::Underscore && !self.is_path_segment_keyword()
1248     }
1249 }
1250
1251 impl Ident {
1252     // Returns `true` for reserved identifiers used internally for elided lifetimes,
1253     // unnamed method parameters, crate root module, error recovery etc.
1254     pub fn is_special(self) -> bool {
1255         self.name <= kw::Underscore
1256     }
1257
1258     /// Returns `true` if the token is a keyword used in the language.
1259     pub fn is_used_keyword(self) -> bool {
1260         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1261         self.name >= kw::As && self.name <= kw::While
1262             || self.name.is_used_keyword_2018() && self.span.rust_2018()
1263     }
1264
1265     /// Returns `true` if the token is a keyword reserved for possible future use.
1266     pub fn is_unused_keyword(self) -> bool {
1267         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1268         self.name >= kw::Abstract && self.name <= kw::Yield
1269             || self.name.is_unused_keyword_2018() && self.span.rust_2018()
1270     }
1271
1272     /// Returns `true` if the token is either a special identifier or a keyword.
1273     pub fn is_reserved(self) -> bool {
1274         self.is_special() || self.is_used_keyword() || self.is_unused_keyword()
1275     }
1276
1277     /// A keyword or reserved identifier that can be used as a path segment.
1278     pub fn is_path_segment_keyword(self) -> bool {
1279         self.name.is_path_segment_keyword()
1280     }
1281
1282     /// We see this identifier in a normal identifier position, like variable name or a type.
1283     /// How was it written originally? Did it use the raw form? Let's try to guess.
1284     pub fn is_raw_guess(self) -> bool {
1285         self.name.can_be_raw() && self.is_reserved()
1286     }
1287 }
1288
1289 #[inline]
1290 fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
1291     GLOBALS.with(|globals| f(&mut *globals.symbol_interner.lock()))
1292 }
1293
1294 /// An alternative to `Symbol`, useful when the chars within the symbol need to
1295 /// be accessed. It deliberately has limited functionality and should only be
1296 /// used for temporary values.
1297 ///
1298 /// Because the interner outlives any thread which uses this type, we can
1299 /// safely treat `string` which points to interner data, as an immortal string,
1300 /// as long as this type never crosses between threads.
1301 //
1302 // FIXME: ensure that the interner outlives any thread which uses `SymbolStr`,
1303 // by creating a new thread right after constructing the interner.
1304 #[derive(Clone, Eq, PartialOrd, Ord)]
1305 pub struct SymbolStr {
1306     string: &'static str,
1307 }
1308
1309 // This impl allows a `SymbolStr` to be directly equated with a `String` or
1310 // `&str`.
1311 impl<T: std::ops::Deref<Target = str>> std::cmp::PartialEq<T> for SymbolStr {
1312     fn eq(&self, other: &T) -> bool {
1313         self.string == other.deref()
1314     }
1315 }
1316
1317 impl !Send for SymbolStr {}
1318 impl !Sync for SymbolStr {}
1319
1320 /// This impl means that if `ss` is a `SymbolStr`:
1321 /// - `*ss` is a `str`;
1322 /// - `&*ss` is a `&str`;
1323 /// - `&ss as &str` is a `&str`, which means that `&ss` can be passed to a
1324 ///   function expecting a `&str`.
1325 impl std::ops::Deref for SymbolStr {
1326     type Target = str;
1327     #[inline]
1328     fn deref(&self) -> &str {
1329         self.string
1330     }
1331 }
1332
1333 impl fmt::Debug for SymbolStr {
1334     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1335         fmt::Debug::fmt(self.string, f)
1336     }
1337 }
1338
1339 impl fmt::Display for SymbolStr {
1340     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1341         fmt::Display::fmt(self.string, f)
1342     }
1343 }
1344
1345 impl<CTX> HashStable<CTX> for SymbolStr {
1346     #[inline]
1347     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1348         self.string.hash_stable(hcx, hasher)
1349     }
1350 }
1351
1352 impl<CTX> ToStableHashKey<CTX> for SymbolStr {
1353     type KeyType = SymbolStr;
1354
1355     #[inline]
1356     fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1357         self.clone()
1358     }
1359 }