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