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