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