]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_span/src/symbol.rs
Move some hard error logic to InterpError
[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         bpf_target_feature,
332         braced_empty_structs,
333         branch,
334         breakpoint,
335         bridge,
336         bswap,
337         c_str,
338         c_unwind,
339         c_variadic,
340         call,
341         call_mut,
342         call_once,
343         caller_location,
344         capture_disjoint_fields,
345         cdylib,
346         ceilf32,
347         ceilf64,
348         cfg,
349         cfg_accessible,
350         cfg_attr,
351         cfg_attr_multi,
352         cfg_doctest,
353         cfg_eval,
354         cfg_panic,
355         cfg_sanitize,
356         cfg_target_feature,
357         cfg_target_has_atomic,
358         cfg_target_thread_local,
359         cfg_target_vendor,
360         cfg_version,
361         char,
362         client,
363         clippy,
364         clone,
365         clone_closures,
366         clone_from,
367         closure,
368         closure_to_fn_coercion,
369         cmp,
370         cmpxchg16b_target_feature,
371         cmse_nonsecure_entry,
372         coerce_unsized,
373         cold,
374         column,
375         compile_error,
376         compiler_builtins,
377         concat,
378         concat_idents,
379         conservative_impl_trait,
380         console,
381         const_allocate,
382         const_async_blocks,
383         const_compare_raw_pointers,
384         const_constructor,
385         const_eval_limit,
386         const_evaluatable_checked,
387         const_extern_fn,
388         const_fn,
389         const_fn_floating_point_arithmetic,
390         const_fn_fn_ptr_basics,
391         const_fn_trait_bound,
392         const_fn_transmute,
393         const_fn_union,
394         const_fn_unsize,
395         const_generic_defaults,
396         const_generics,
397         const_generics_defaults,
398         const_if_match,
399         const_impl_trait,
400         const_in_array_repeat_expressions,
401         const_indexing,
402         const_let,
403         const_loop,
404         const_mut_refs,
405         const_panic,
406         const_precise_live_drops,
407         const_ptr,
408         const_raw_ptr_deref,
409         const_raw_ptr_to_usize_cast,
410         const_refs_to_cell,
411         const_slice_ptr,
412         const_trait_bound_opt_out,
413         const_trait_impl,
414         const_transmute,
415         constant,
416         constructor,
417         contents,
418         context,
419         control_flow_enum,
420         convert,
421         copy,
422         copy_closures,
423         copy_nonoverlapping,
424         copysignf32,
425         copysignf64,
426         core,
427         core_intrinsics,
428         core_panic,
429         core_panic_2015_macro,
430         core_panic_macro,
431         cosf32,
432         cosf64,
433         crate_id,
434         crate_in_paths,
435         crate_local,
436         crate_name,
437         crate_type,
438         crate_visibility_modifier,
439         crt_dash_static: "crt-static",
440         cstring_type,
441         ctlz,
442         ctlz_nonzero,
443         ctpop,
444         cttz,
445         cttz_nonzero,
446         custom_attribute,
447         custom_derive,
448         custom_inner_attributes,
449         custom_test_frameworks,
450         d,
451         dead_code,
452         dealloc,
453         debug,
454         debug_assert_macro,
455         debug_assertions,
456         debug_struct,
457         debug_trait,
458         debug_trait_builder,
459         debug_tuple,
460         decl_macro,
461         declare_lint_pass,
462         decode,
463         default_alloc_error_handler,
464         default_lib_allocator,
465         default_type_parameter_fallback,
466         default_type_params,
467         delay_span_bug_from_inside_query,
468         deny,
469         deprecated,
470         deref,
471         deref_method,
472         deref_mut,
473         deref_target,
474         derive,
475         destructuring_assignment,
476         diagnostic,
477         direct,
478         discriminant_kind,
479         discriminant_type,
480         discriminant_value,
481         dispatch_from_dyn,
482         div,
483         div_assign,
484         doc,
485         doc_alias,
486         doc_cfg,
487         doc_keyword,
488         doc_masked,
489         doc_notable_trait,
490         doc_spotlight,
491         doctest,
492         document_private_items,
493         dotdot_in_tuple_patterns,
494         dotdoteq_in_patterns,
495         dreg,
496         dreg_low16,
497         dreg_low8,
498         drop,
499         drop_in_place,
500         drop_types_in_const,
501         dropck_eyepatch,
502         dropck_parametricity,
503         dylib,
504         dyn_metadata,
505         dyn_trait,
506         edition_macro_pats,
507         eh_catch_typeinfo,
508         eh_personality,
509         emit_enum,
510         emit_enum_variant,
511         emit_enum_variant_arg,
512         emit_struct,
513         emit_struct_field,
514         enable,
515         enclosing_scope,
516         encode,
517         env,
518         eq,
519         ermsb_target_feature,
520         exact_div,
521         except,
522         exchange_malloc,
523         exclusive_range_pattern,
524         exhaustive_integer_patterns,
525         exhaustive_patterns,
526         existential_type,
527         exp2f32,
528         exp2f64,
529         expect,
530         expected,
531         expf32,
532         expf64,
533         export_name,
534         expr,
535         extended_key_value_attributes,
536         extern_absolute_paths,
537         extern_crate_item_prelude,
538         extern_crate_self,
539         extern_in_paths,
540         extern_prelude,
541         extern_types,
542         external_doc,
543         f,
544         f16c_target_feature,
545         f32,
546         f32_runtime,
547         f64,
548         f64_runtime,
549         fabsf32,
550         fabsf64,
551         fadd_fast,
552         fdiv_fast,
553         feature,
554         ffi,
555         ffi_const,
556         ffi_pure,
557         ffi_returns_twice,
558         field,
559         field_init_shorthand,
560         file,
561         fill,
562         finish,
563         flags,
564         float_to_int_unchecked,
565         floorf32,
566         floorf64,
567         fmaf32,
568         fmaf64,
569         fmt,
570         fmt_internals,
571         fmul_fast,
572         fn_align,
573         fn_must_use,
574         fn_mut,
575         fn_once,
576         fn_once_output,
577         forbid,
578         forget,
579         format,
580         format_args,
581         format_args_capture,
582         format_args_nl,
583         format_macro,
584         freeze,
585         freg,
586         frem_fast,
587         from,
588         from_desugaring,
589         from_generator,
590         from_method,
591         from_output,
592         from_residual,
593         from_size_align_unchecked,
594         from_trait,
595         from_usize,
596         fsub_fast,
597         fundamental,
598         future,
599         future_trait,
600         ge,
601         gen_future,
602         gen_kill,
603         generator,
604         generator_state,
605         generators,
606         generic_associated_types,
607         generic_param_attrs,
608         get_context,
609         global_allocator,
610         global_asm,
611         globs,
612         gt,
613         half_open_range_patterns,
614         hash,
615         hashmap_type,
616         hashset_type,
617         hexagon_target_feature,
618         hidden,
619         homogeneous_aggregate,
620         html_favicon_url,
621         html_logo_url,
622         html_no_source,
623         html_playground_url,
624         html_root_url,
625         hwaddress,
626         i,
627         i128,
628         i128_type,
629         i16,
630         i32,
631         i64,
632         i8,
633         ident,
634         if_let,
635         if_let_guard,
636         if_while_or_patterns,
637         ignore,
638         impl_header_lifetime_elision,
639         impl_lint_pass,
640         impl_macros,
641         impl_trait_in_bindings,
642         import_shadowing,
643         imported_main,
644         in_band_lifetimes,
645         include,
646         include_bytes,
647         include_str,
648         inclusive_range_syntax,
649         index,
650         index_mut,
651         infer_outlives_requirements,
652         infer_static_outlives_requirements,
653         inherent_associated_types,
654         inlateout,
655         inline,
656         inline_const,
657         inout,
658         instruction_set,
659         intel,
660         into_iter,
661         into_trait,
662         intra_doc_pointers,
663         intrinsics,
664         irrefutable_let_patterns,
665         isa_attribute,
666         isize,
667         issue,
668         issue_5723_bootstrap,
669         issue_tracker_base_url,
670         item,
671         item_like_imports,
672         iter,
673         keyword,
674         kind,
675         kreg,
676         label,
677         label_break_value,
678         lang,
679         lang_items,
680         large_assignments,
681         lateout,
682         lazy_normalization_consts,
683         le,
684         let_chains,
685         lhs,
686         lib,
687         libc,
688         lifetime,
689         likely,
690         line,
691         link,
692         link_args,
693         link_cfg,
694         link_llvm_intrinsics,
695         link_name,
696         link_ordinal,
697         link_section,
698         linkage,
699         lint_reasons,
700         literal,
701         llvm_asm,
702         local,
703         local_inner_macros,
704         log10f32,
705         log10f64,
706         log2f32,
707         log2f64,
708         log_syntax,
709         logf32,
710         logf64,
711         loop_break_value,
712         lt,
713         macro_at_most_once_rep,
714         macro_attributes_in_derive_output,
715         macro_escape,
716         macro_export,
717         macro_lifetime_matcher,
718         macro_literal_matcher,
719         macro_reexport,
720         macro_use,
721         macro_vis_matcher,
722         macros_in_extern,
723         main,
724         managed_boxes,
725         manually_drop,
726         map,
727         marker,
728         marker_trait_attr,
729         masked,
730         match_beginning_vert,
731         match_default_bindings,
732         maxnumf32,
733         maxnumf64,
734         may_dangle,
735         maybe_uninit,
736         maybe_uninit_uninit,
737         maybe_uninit_zeroed,
738         mem_uninitialized,
739         mem_zeroed,
740         member_constraints,
741         memory,
742         message,
743         meta,
744         metadata_type,
745         min_align_of,
746         min_align_of_val,
747         min_const_fn,
748         min_const_generics,
749         min_const_unsafe_fn,
750         min_specialization,
751         min_type_alias_impl_trait,
752         minnumf32,
753         minnumf64,
754         mips_target_feature,
755         misc,
756         modifiers,
757         module,
758         module_path,
759         more_qualified_paths,
760         more_struct_aliases,
761         movbe_target_feature,
762         move_ref_pattern,
763         move_size_limit,
764         mul,
765         mul_assign,
766         mul_with_overflow,
767         must_use,
768         mut_ptr,
769         mut_slice_ptr,
770         naked,
771         naked_functions,
772         name,
773         native_link_modifiers,
774         native_link_modifiers_as_needed,
775         native_link_modifiers_bundle,
776         native_link_modifiers_verbatim,
777         native_link_modifiers_whole_archive,
778         ne,
779         nearbyintf32,
780         nearbyintf64,
781         needs_allocator,
782         needs_drop,
783         needs_panic_runtime,
784         neg,
785         negate_unsigned,
786         negative_impls,
787         never,
788         never_type,
789         never_type_fallback,
790         new,
791         new_unchecked,
792         next,
793         nll,
794         no,
795         no_builtins,
796         no_core,
797         no_coverage,
798         no_crate_inject,
799         no_debug,
800         no_default_passes,
801         no_implicit_prelude,
802         no_inline,
803         no_link,
804         no_main,
805         no_mangle,
806         no_niche,
807         no_sanitize,
808         no_stack_check,
809         no_start,
810         no_std,
811         nomem,
812         non_ascii_idents,
813         non_exhaustive,
814         non_modrs_mods,
815         none_error,
816         nontemporal_store,
817         noop_method_borrow,
818         noop_method_clone,
819         noop_method_deref,
820         noreturn,
821         nostack,
822         not,
823         notable_trait,
824         note,
825         object_safe_for_dispatch,
826         of,
827         offset,
828         omit_gdb_pretty_printer_section,
829         on,
830         on_unimplemented,
831         oom,
832         opaque,
833         ops,
834         opt_out_copy,
835         optimize,
836         optimize_attribute,
837         optin_builtin_traits,
838         option,
839         option_env,
840         option_type,
841         options,
842         or,
843         or_patterns,
844         other,
845         out,
846         overlapping_marker_traits,
847         owned_box,
848         packed,
849         panic,
850         panic_2015,
851         panic_2021,
852         panic_abort,
853         panic_bounds_check,
854         panic_handler,
855         panic_impl,
856         panic_implementation,
857         panic_info,
858         panic_location,
859         panic_runtime,
860         panic_str,
861         panic_unwind,
862         panicking,
863         param_attrs,
864         parent_trait,
865         partial_cmp,
866         partial_ord,
867         passes,
868         pat,
869         pat_param,
870         path,
871         pattern_parentheses,
872         phantom_data,
873         pin,
874         pinned,
875         platform_intrinsics,
876         plugin,
877         plugin_registrar,
878         plugins,
879         pointee_trait,
880         pointer,
881         pointer_trait,
882         pointer_trait_fmt,
883         poll,
884         position,
885         post_dash_lto: "post-lto",
886         powerpc_target_feature,
887         powf32,
888         powf64,
889         powif32,
890         powif64,
891         pre_dash_lto: "pre-lto",
892         precise_pointer_size_matching,
893         precision,
894         pref_align_of,
895         prefetch_read_data,
896         prefetch_read_instruction,
897         prefetch_write_data,
898         prefetch_write_instruction,
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         wreg,
1338         write_bytes,
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 }