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