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