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