]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_span/src/symbol.rs
remove pat2021
[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         pat_param,
853         path,
854         pattern_parentheses,
855         phantom_data,
856         pin,
857         pinned,
858         platform_intrinsics,
859         plugin,
860         plugin_registrar,
861         plugins,
862         pointee_trait,
863         pointer,
864         pointer_trait,
865         pointer_trait_fmt,
866         poll,
867         position,
868         post_dash_lto: "post-lto",
869         powerpc_target_feature,
870         powf32,
871         powf64,
872         powif32,
873         powif64,
874         pre_dash_lto: "pre-lto",
875         precise_pointer_size_matching,
876         precision,
877         pref_align_of,
878         prefetch_read_data,
879         prefetch_read_instruction,
880         prefetch_write_data,
881         prefetch_write_instruction,
882         prelude,
883         prelude_import,
884         preserves_flags,
885         primitive,
886         proc_dash_macro: "proc-macro",
887         proc_macro,
888         proc_macro_attribute,
889         proc_macro_def_site,
890         proc_macro_derive,
891         proc_macro_expr,
892         proc_macro_gen,
893         proc_macro_hygiene,
894         proc_macro_internals,
895         proc_macro_mod,
896         proc_macro_non_items,
897         proc_macro_path_invoc,
898         profiler_builtins,
899         profiler_runtime,
900         ptr_guaranteed_eq,
901         ptr_guaranteed_ne,
902         ptr_null,
903         ptr_null_mut,
904         ptr_offset_from,
905         pub_macro_rules,
906         pub_restricted,
907         pure,
908         pushpop_unsafe,
909         qreg,
910         qreg_low4,
911         qreg_low8,
912         quad_precision_float,
913         question_mark,
914         quote,
915         range_inclusive_new,
916         raw_dylib,
917         raw_identifiers,
918         raw_ref_op,
919         re_rebalance_coherence,
920         read_enum,
921         read_enum_variant,
922         read_enum_variant_arg,
923         read_struct,
924         read_struct_field,
925         readonly,
926         realloc,
927         reason,
928         receiver,
929         recursion_limit,
930         reexport_test_harness_main,
931         reference,
932         reflect,
933         reg,
934         reg16,
935         reg32,
936         reg64,
937         reg_abcd,
938         reg_byte,
939         reg_thumb,
940         register_attr,
941         register_tool,
942         relaxed_adts,
943         relaxed_struct_unsize,
944         rem,
945         rem_assign,
946         repr,
947         repr128,
948         repr_align,
949         repr_align_enum,
950         repr_no_niche,
951         repr_packed,
952         repr_simd,
953         repr_transparent,
954         result,
955         result_type,
956         rhs,
957         rintf32,
958         rintf64,
959         riscv_target_feature,
960         rlib,
961         rotate_left,
962         rotate_right,
963         roundf32,
964         roundf64,
965         rt,
966         rtm_target_feature,
967         rust,
968         rust_2015,
969         rust_2015_preview,
970         rust_2018,
971         rust_2018_preview,
972         rust_2021,
973         rust_2021_preview,
974         rust_begin_unwind,
975         rust_eh_catch_typeinfo,
976         rust_eh_personality,
977         rust_eh_register_frames,
978         rust_eh_unregister_frames,
979         rust_oom,
980         rustc,
981         rustc_allocator,
982         rustc_allocator_nounwind,
983         rustc_allow_const_fn_unstable,
984         rustc_args_required_const,
985         rustc_attrs,
986         rustc_builtin_macro,
987         rustc_capture_analysis,
988         rustc_clean,
989         rustc_const_stable,
990         rustc_const_unstable,
991         rustc_conversion_suggestion,
992         rustc_def_path,
993         rustc_deprecated,
994         rustc_diagnostic_item,
995         rustc_diagnostic_macros,
996         rustc_dirty,
997         rustc_dummy,
998         rustc_dump_env_program_clauses,
999         rustc_dump_program_clauses,
1000         rustc_dump_user_substs,
1001         rustc_error,
1002         rustc_expected_cgu_reuse,
1003         rustc_if_this_changed,
1004         rustc_inherit_overflow_checks,
1005         rustc_layout,
1006         rustc_layout_scalar_valid_range_end,
1007         rustc_layout_scalar_valid_range_start,
1008         rustc_legacy_const_generics,
1009         rustc_macro_transparency,
1010         rustc_mir,
1011         rustc_nonnull_optimization_guaranteed,
1012         rustc_object_lifetime_default,
1013         rustc_on_unimplemented,
1014         rustc_outlives,
1015         rustc_paren_sugar,
1016         rustc_partition_codegened,
1017         rustc_partition_reused,
1018         rustc_peek,
1019         rustc_peek_definite_init,
1020         rustc_peek_indirectly_mutable,
1021         rustc_peek_liveness,
1022         rustc_peek_maybe_init,
1023         rustc_peek_maybe_uninit,
1024         rustc_polymorphize_error,
1025         rustc_private,
1026         rustc_proc_macro_decls,
1027         rustc_promotable,
1028         rustc_regions,
1029         rustc_reservation_impl,
1030         rustc_serialize,
1031         rustc_specialization_trait,
1032         rustc_stable,
1033         rustc_std_internal_symbol,
1034         rustc_symbol_name,
1035         rustc_synthetic,
1036         rustc_test_marker,
1037         rustc_then_this_would_need,
1038         rustc_unsafe_specialization_marker,
1039         rustc_variance,
1040         rustdoc,
1041         rustfmt,
1042         rvalue_static_promotion,
1043         sanitize,
1044         sanitizer_runtime,
1045         saturating_add,
1046         saturating_sub,
1047         self_in_typedefs,
1048         self_struct_ctor,
1049         semitransparent,
1050         send_trait,
1051         shl,
1052         shl_assign,
1053         should_panic,
1054         shr,
1055         shr_assign,
1056         simd,
1057         simd_add,
1058         simd_and,
1059         simd_bitmask,
1060         simd_cast,
1061         simd_ceil,
1062         simd_div,
1063         simd_eq,
1064         simd_extract,
1065         simd_fabs,
1066         simd_fcos,
1067         simd_fexp,
1068         simd_fexp2,
1069         simd_ffi,
1070         simd_flog,
1071         simd_flog10,
1072         simd_flog2,
1073         simd_floor,
1074         simd_fma,
1075         simd_fmax,
1076         simd_fmin,
1077         simd_fpow,
1078         simd_fpowi,
1079         simd_fsin,
1080         simd_fsqrt,
1081         simd_gather,
1082         simd_ge,
1083         simd_gt,
1084         simd_insert,
1085         simd_le,
1086         simd_lt,
1087         simd_mul,
1088         simd_ne,
1089         simd_neg,
1090         simd_or,
1091         simd_reduce_add_ordered,
1092         simd_reduce_add_unordered,
1093         simd_reduce_all,
1094         simd_reduce_and,
1095         simd_reduce_any,
1096         simd_reduce_max,
1097         simd_reduce_max_nanless,
1098         simd_reduce_min,
1099         simd_reduce_min_nanless,
1100         simd_reduce_mul_ordered,
1101         simd_reduce_mul_unordered,
1102         simd_reduce_or,
1103         simd_reduce_xor,
1104         simd_rem,
1105         simd_saturating_add,
1106         simd_saturating_sub,
1107         simd_scatter,
1108         simd_select,
1109         simd_select_bitmask,
1110         simd_shl,
1111         simd_shr,
1112         simd_sub,
1113         simd_xor,
1114         since,
1115         sinf32,
1116         sinf64,
1117         size,
1118         size_of,
1119         size_of_val,
1120         sized,
1121         skip,
1122         slice,
1123         slice_alloc,
1124         slice_patterns,
1125         slice_u8,
1126         slice_u8_alloc,
1127         slicing_syntax,
1128         soft,
1129         specialization,
1130         speed,
1131         spotlight,
1132         sqrtf32,
1133         sqrtf64,
1134         sreg,
1135         sreg_low16,
1136         sse4a_target_feature,
1137         stable,
1138         staged_api,
1139         start,
1140         state,
1141         static_in_const,
1142         static_nobundle,
1143         static_recursion,
1144         staticlib,
1145         std,
1146         std_inject,
1147         std_panic,
1148         std_panic_2015_macro,
1149         std_panic_macro,
1150         stmt,
1151         stmt_expr_attributes,
1152         stop_after_dataflow,
1153         str,
1154         str_alloc,
1155         string_type,
1156         stringify,
1157         struct_field_attributes,
1158         struct_inherit,
1159         struct_variant,
1160         structural_match,
1161         structural_peq,
1162         structural_teq,
1163         sty,
1164         sub,
1165         sub_assign,
1166         sub_with_overflow,
1167         suggestion,
1168         sym,
1169         sync,
1170         sync_trait,
1171         t32,
1172         target_arch,
1173         target_endian,
1174         target_env,
1175         target_family,
1176         target_feature,
1177         target_feature_11,
1178         target_has_atomic,
1179         target_has_atomic_equal_alignment,
1180         target_has_atomic_load_store,
1181         target_os,
1182         target_pointer_width,
1183         target_target_vendor,
1184         target_thread_local,
1185         target_vendor,
1186         task,
1187         tbm_target_feature,
1188         termination,
1189         termination_trait,
1190         termination_trait_test,
1191         test,
1192         test_2018_feature,
1193         test_accepted_feature,
1194         test_case,
1195         test_removed_feature,
1196         test_runner,
1197         then_with,
1198         thread,
1199         thread_local,
1200         tool_attributes,
1201         tool_lints,
1202         trace_macros,
1203         track_caller,
1204         trait_alias,
1205         transmute,
1206         transparent,
1207         transparent_enums,
1208         transparent_unions,
1209         trivial_bounds,
1210         truncf32,
1211         truncf64,
1212         try_blocks,
1213         try_from_trait,
1214         try_into_trait,
1215         try_trait,
1216         tt,
1217         tuple,
1218         tuple_from_req,
1219         tuple_indexing,
1220         two_phase,
1221         ty,
1222         type_alias_enum_variants,
1223         type_alias_impl_trait,
1224         type_ascription,
1225         type_id,
1226         type_length_limit,
1227         type_macros,
1228         type_name,
1229         u128,
1230         u16,
1231         u32,
1232         u64,
1233         u8,
1234         unaligned_volatile_load,
1235         unaligned_volatile_store,
1236         unboxed_closures,
1237         unchecked_add,
1238         unchecked_div,
1239         unchecked_mul,
1240         unchecked_rem,
1241         unchecked_shl,
1242         unchecked_shr,
1243         unchecked_sub,
1244         underscore_const_names,
1245         underscore_imports,
1246         underscore_lifetimes,
1247         uniform_paths,
1248         unit,
1249         universal_impl_trait,
1250         unix,
1251         unlikely,
1252         unmarked_api,
1253         unpin,
1254         unreachable,
1255         unreachable_code,
1256         unrestricted_attribute_tokens,
1257         unsafe_block_in_unsafe_fn,
1258         unsafe_cell,
1259         unsafe_no_drop_flag,
1260         unsize,
1261         unsized_fn_params,
1262         unsized_locals,
1263         unsized_tuple_coercion,
1264         unstable,
1265         untagged_unions,
1266         unused_qualifications,
1267         unwind,
1268         unwind_attributes,
1269         unwrap,
1270         unwrap_or,
1271         use_extern_macros,
1272         use_nested_groups,
1273         used,
1274         usize,
1275         v1,
1276         va_arg,
1277         va_copy,
1278         va_end,
1279         va_list,
1280         va_start,
1281         val,
1282         var,
1283         variant_count,
1284         vec,
1285         vec_type,
1286         vecdeque_type,
1287         version,
1288         vis,
1289         visible_private_types,
1290         volatile,
1291         volatile_copy_memory,
1292         volatile_copy_nonoverlapping_memory,
1293         volatile_load,
1294         volatile_set_memory,
1295         volatile_store,
1296         vreg,
1297         vreg_low16,
1298         warn,
1299         wasm_abi,
1300         wasm_import_module,
1301         wasm_target_feature,
1302         while_let,
1303         width,
1304         windows,
1305         windows_subsystem,
1306         wrapping_add,
1307         wrapping_mul,
1308         wrapping_sub,
1309         write_bytes,
1310         xmm_reg,
1311         ymm_reg,
1312         zmm_reg,
1313     }
1314 }
1315
1316 #[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
1317 pub struct Ident {
1318     pub name: Symbol,
1319     pub span: Span,
1320 }
1321
1322 impl Ident {
1323     #[inline]
1324     /// Constructs a new identifier from a symbol and a span.
1325     pub const fn new(name: Symbol, span: Span) -> Ident {
1326         Ident { name, span }
1327     }
1328
1329     /// Constructs a new identifier with a dummy span.
1330     #[inline]
1331     pub const fn with_dummy_span(name: Symbol) -> Ident {
1332         Ident::new(name, DUMMY_SP)
1333     }
1334
1335     #[inline]
1336     pub fn invalid() -> Ident {
1337         Ident::with_dummy_span(kw::Empty)
1338     }
1339
1340     /// Maps a string to an identifier with a dummy span.
1341     pub fn from_str(string: &str) -> Ident {
1342         Ident::with_dummy_span(Symbol::intern(string))
1343     }
1344
1345     /// Maps a string and a span to an identifier.
1346     pub fn from_str_and_span(string: &str, span: Span) -> Ident {
1347         Ident::new(Symbol::intern(string), span)
1348     }
1349
1350     /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
1351     pub fn with_span_pos(self, span: Span) -> Ident {
1352         Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
1353     }
1354
1355     pub fn without_first_quote(self) -> Ident {
1356         Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
1357     }
1358
1359     /// "Normalize" ident for use in comparisons using "item hygiene".
1360     /// Identifiers with same string value become same if they came from the same macro 2.0 macro
1361     /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
1362     /// different macro 2.0 macros.
1363     /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
1364     pub fn normalize_to_macros_2_0(self) -> Ident {
1365         Ident::new(self.name, self.span.normalize_to_macros_2_0())
1366     }
1367
1368     /// "Normalize" ident for use in comparisons using "local variable hygiene".
1369     /// Identifiers with same string value become same if they came from the same non-transparent
1370     /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
1371     /// non-transparent macros.
1372     /// Technically, this operation strips all transparent marks from ident's syntactic context.
1373     pub fn normalize_to_macro_rules(self) -> Ident {
1374         Ident::new(self.name, self.span.normalize_to_macro_rules())
1375     }
1376
1377     /// Convert the name to a `SymbolStr`. This is a slowish operation because
1378     /// it requires locking the symbol interner.
1379     pub fn as_str(self) -> SymbolStr {
1380         self.name.as_str()
1381     }
1382 }
1383
1384 impl PartialEq for Ident {
1385     fn eq(&self, rhs: &Self) -> bool {
1386         self.name == rhs.name && self.span.ctxt() == rhs.span.ctxt()
1387     }
1388 }
1389
1390 impl Hash for Ident {
1391     fn hash<H: Hasher>(&self, state: &mut H) {
1392         self.name.hash(state);
1393         self.span.ctxt().hash(state);
1394     }
1395 }
1396
1397 impl fmt::Debug for Ident {
1398     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1399         fmt::Display::fmt(self, f)?;
1400         fmt::Debug::fmt(&self.span.ctxt(), f)
1401     }
1402 }
1403
1404 /// This implementation is supposed to be used in error messages, so it's expected to be identical
1405 /// to printing the original identifier token written in source code (`token_to_string`),
1406 /// except that AST identifiers don't keep the rawness flag, so we have to guess it.
1407 impl fmt::Display for Ident {
1408     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1409         fmt::Display::fmt(&IdentPrinter::new(self.name, self.is_raw_guess(), None), f)
1410     }
1411 }
1412
1413 /// This is the most general way to print identifiers.
1414 /// AST pretty-printer is used as a fallback for turning AST structures into token streams for
1415 /// proc macros. Additionally, proc macros may stringify their input and expect it survive the
1416 /// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
1417 /// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
1418 /// hygiene data, most importantly name of the crate it refers to.
1419 /// As a result we print `$crate` as `crate` if it refers to the local crate
1420 /// and as `::other_crate_name` if it refers to some other crate.
1421 /// Note, that this is only done if the ident token is printed from inside of AST pretty-pringing,
1422 /// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
1423 /// so we should not perform this lossy conversion if the top level call to the pretty-printer was
1424 /// done for a token stream or a single token.
1425 pub struct IdentPrinter {
1426     symbol: Symbol,
1427     is_raw: bool,
1428     /// Span used for retrieving the crate name to which `$crate` refers to,
1429     /// if this field is `None` then the `$crate` conversion doesn't happen.
1430     convert_dollar_crate: Option<Span>,
1431 }
1432
1433 impl IdentPrinter {
1434     /// The most general `IdentPrinter` constructor. Do not use this.
1435     pub fn new(symbol: Symbol, is_raw: bool, convert_dollar_crate: Option<Span>) -> IdentPrinter {
1436         IdentPrinter { symbol, is_raw, convert_dollar_crate }
1437     }
1438
1439     /// This implementation is supposed to be used when printing identifiers
1440     /// as a part of pretty-printing for larger AST pieces.
1441     /// Do not use this either.
1442     pub fn for_ast_ident(ident: Ident, is_raw: bool) -> IdentPrinter {
1443         IdentPrinter::new(ident.name, is_raw, Some(ident.span))
1444     }
1445 }
1446
1447 impl fmt::Display for IdentPrinter {
1448     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1449         if self.is_raw {
1450             f.write_str("r#")?;
1451         } else if self.symbol == kw::DollarCrate {
1452             if let Some(span) = self.convert_dollar_crate {
1453                 let converted = span.ctxt().dollar_crate_name();
1454                 if !converted.is_path_segment_keyword() {
1455                     f.write_str("::")?;
1456                 }
1457                 return fmt::Display::fmt(&converted, f);
1458             }
1459         }
1460         fmt::Display::fmt(&self.symbol, f)
1461     }
1462 }
1463
1464 /// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
1465 /// construction.
1466 // FIXME(matthewj, petrochenkov) Use this more often, add a similar
1467 // `ModernIdent` struct and use that as well.
1468 #[derive(Copy, Clone, Eq, PartialEq, Hash)]
1469 pub struct MacroRulesNormalizedIdent(Ident);
1470
1471 impl MacroRulesNormalizedIdent {
1472     pub fn new(ident: Ident) -> Self {
1473         Self(ident.normalize_to_macro_rules())
1474     }
1475 }
1476
1477 impl fmt::Debug for MacroRulesNormalizedIdent {
1478     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1479         fmt::Debug::fmt(&self.0, f)
1480     }
1481 }
1482
1483 impl fmt::Display for MacroRulesNormalizedIdent {
1484     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1485         fmt::Display::fmt(&self.0, f)
1486     }
1487 }
1488
1489 /// An interned string.
1490 ///
1491 /// Internally, a `Symbol` is implemented as an index, and all operations
1492 /// (including hashing, equality, and ordering) operate on that index. The use
1493 /// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
1494 /// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
1495 ///
1496 /// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
1497 /// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
1498 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1499 pub struct Symbol(SymbolIndex);
1500
1501 rustc_index::newtype_index! {
1502     pub struct SymbolIndex { .. }
1503 }
1504
1505 impl Symbol {
1506     const fn new(n: u32) -> Self {
1507         Symbol(SymbolIndex::from_u32(n))
1508     }
1509
1510     /// Maps a string to its interned representation.
1511     pub fn intern(string: &str) -> Self {
1512         with_interner(|interner| interner.intern(string))
1513     }
1514
1515     /// Convert to a `SymbolStr`. This is a slowish operation because it
1516     /// requires locking the symbol interner.
1517     pub fn as_str(self) -> SymbolStr {
1518         with_interner(|interner| unsafe {
1519             SymbolStr { string: std::mem::transmute::<&str, &str>(interner.get(self)) }
1520         })
1521     }
1522
1523     pub fn as_u32(self) -> u32 {
1524         self.0.as_u32()
1525     }
1526
1527     pub fn is_empty(self) -> bool {
1528         self == kw::Empty
1529     }
1530
1531     /// This method is supposed to be used in error messages, so it's expected to be
1532     /// identical to printing the original identifier token written in source code
1533     /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
1534     /// or edition, so we have to guess the rawness using the global edition.
1535     pub fn to_ident_string(self) -> String {
1536         Ident::with_dummy_span(self).to_string()
1537     }
1538 }
1539
1540 impl fmt::Debug for Symbol {
1541     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1542         fmt::Debug::fmt(&self.as_str(), f)
1543     }
1544 }
1545
1546 impl fmt::Display for Symbol {
1547     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1548         fmt::Display::fmt(&self.as_str(), f)
1549     }
1550 }
1551
1552 impl<S: Encoder> Encodable<S> for Symbol {
1553     fn encode(&self, s: &mut S) -> Result<(), S::Error> {
1554         s.emit_str(&self.as_str())
1555     }
1556 }
1557
1558 impl<D: Decoder> Decodable<D> for Symbol {
1559     #[inline]
1560     fn decode(d: &mut D) -> Result<Symbol, D::Error> {
1561         Ok(Symbol::intern(&d.read_str()?))
1562     }
1563 }
1564
1565 impl<CTX> HashStable<CTX> for Symbol {
1566     #[inline]
1567     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1568         self.as_str().hash_stable(hcx, hasher);
1569     }
1570 }
1571
1572 impl<CTX> ToStableHashKey<CTX> for Symbol {
1573     type KeyType = SymbolStr;
1574
1575     #[inline]
1576     fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1577         self.as_str()
1578     }
1579 }
1580
1581 // The `&'static str`s in this type actually point into the arena.
1582 //
1583 // The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
1584 // found that to regress performance up to 2% in some cases. This might be
1585 // revisited after further improvements to `indexmap`.
1586 #[derive(Default)]
1587 pub struct Interner {
1588     arena: DroplessArena,
1589     names: FxHashMap<&'static str, Symbol>,
1590     strings: Vec<&'static str>,
1591 }
1592
1593 impl Interner {
1594     fn prefill(init: &[&'static str]) -> Self {
1595         Interner {
1596             strings: init.into(),
1597             names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
1598             ..Default::default()
1599         }
1600     }
1601
1602     #[inline]
1603     pub fn intern(&mut self, string: &str) -> Symbol {
1604         if let Some(&name) = self.names.get(string) {
1605             return name;
1606         }
1607
1608         let name = Symbol::new(self.strings.len() as u32);
1609
1610         // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
1611         // UTF-8.
1612         let string: &str =
1613             unsafe { str::from_utf8_unchecked(self.arena.alloc_slice(string.as_bytes())) };
1614         // It is safe to extend the arena allocation to `'static` because we only access
1615         // these while the arena is still alive.
1616         let string: &'static str = unsafe { &*(string as *const str) };
1617         self.strings.push(string);
1618         self.names.insert(string, name);
1619         name
1620     }
1621
1622     // Get the symbol as a string. `Symbol::as_str()` should be used in
1623     // preference to this function.
1624     pub fn get(&self, symbol: Symbol) -> &str {
1625         self.strings[symbol.0.as_usize()]
1626     }
1627 }
1628
1629 // This module has a very short name because it's used a lot.
1630 /// This module contains all the defined keyword `Symbol`s.
1631 ///
1632 /// Given that `kw` is imported, use them like `kw::keyword_name`.
1633 /// For example `kw::Loop` or `kw::Break`.
1634 pub mod kw {
1635     pub use super::kw_generated::*;
1636 }
1637
1638 // This module has a very short name because it's used a lot.
1639 /// This module contains all the defined non-keyword `Symbol`s.
1640 ///
1641 /// Given that `sym` is imported, use them like `sym::symbol_name`.
1642 /// For example `sym::rustfmt` or `sym::u8`.
1643 pub mod sym {
1644     use super::Symbol;
1645     use std::convert::TryInto;
1646
1647     #[doc(inline)]
1648     pub use super::sym_generated::*;
1649
1650     // Used from a macro in `librustc_feature/accepted.rs`
1651     pub use super::kw::MacroRules as macro_rules;
1652
1653     /// Get the symbol for an integer.
1654     ///
1655     /// The first few non-negative integers each have a static symbol and therefore
1656     /// are fast.
1657     pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
1658         if let Result::Ok(idx) = n.try_into() {
1659             if idx < 10 {
1660                 return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
1661             }
1662         }
1663         Symbol::intern(&n.to_string())
1664     }
1665 }
1666
1667 impl Symbol {
1668     fn is_special(self) -> bool {
1669         self <= kw::Underscore
1670     }
1671
1672     fn is_used_keyword_always(self) -> bool {
1673         self >= kw::As && self <= kw::While
1674     }
1675
1676     fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1677         (self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
1678     }
1679
1680     fn is_unused_keyword_always(self) -> bool {
1681         self >= kw::Abstract && self <= kw::Yield
1682     }
1683
1684     fn is_unused_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
1685         self == kw::Try && edition() >= Edition::Edition2018
1686     }
1687
1688     pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
1689         self.is_special()
1690             || self.is_used_keyword_always()
1691             || self.is_unused_keyword_always()
1692             || self.is_used_keyword_conditional(edition)
1693             || self.is_unused_keyword_conditional(edition)
1694     }
1695
1696     /// A keyword or reserved identifier that can be used as a path segment.
1697     pub fn is_path_segment_keyword(self) -> bool {
1698         self == kw::Super
1699             || self == kw::SelfLower
1700             || self == kw::SelfUpper
1701             || self == kw::Crate
1702             || self == kw::PathRoot
1703             || self == kw::DollarCrate
1704     }
1705
1706     /// Returns `true` if the symbol is `true` or `false`.
1707     pub fn is_bool_lit(self) -> bool {
1708         self == kw::True || self == kw::False
1709     }
1710
1711     /// Returns `true` if this symbol can be a raw identifier.
1712     pub fn can_be_raw(self) -> bool {
1713         self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword()
1714     }
1715 }
1716
1717 impl Ident {
1718     // Returns `true` for reserved identifiers used internally for elided lifetimes,
1719     // unnamed method parameters, crate root module, error recovery etc.
1720     pub fn is_special(self) -> bool {
1721         self.name.is_special()
1722     }
1723
1724     /// Returns `true` if the token is a keyword used in the language.
1725     pub fn is_used_keyword(self) -> bool {
1726         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1727         self.name.is_used_keyword_always()
1728             || self.name.is_used_keyword_conditional(|| self.span.edition())
1729     }
1730
1731     /// Returns `true` if the token is a keyword reserved for possible future use.
1732     pub fn is_unused_keyword(self) -> bool {
1733         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1734         self.name.is_unused_keyword_always()
1735             || self.name.is_unused_keyword_conditional(|| self.span.edition())
1736     }
1737
1738     /// Returns `true` if the token is either a special identifier or a keyword.
1739     pub fn is_reserved(self) -> bool {
1740         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1741         self.name.is_reserved(|| self.span.edition())
1742     }
1743
1744     /// A keyword or reserved identifier that can be used as a path segment.
1745     pub fn is_path_segment_keyword(self) -> bool {
1746         self.name.is_path_segment_keyword()
1747     }
1748
1749     /// We see this identifier in a normal identifier position, like variable name or a type.
1750     /// How was it written originally? Did it use the raw form? Let's try to guess.
1751     pub fn is_raw_guess(self) -> bool {
1752         self.name.can_be_raw() && self.is_reserved()
1753     }
1754 }
1755
1756 #[inline]
1757 fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
1758     SESSION_GLOBALS.with(|session_globals| f(&mut *session_globals.symbol_interner.lock()))
1759 }
1760
1761 /// An alternative to [`Symbol`], useful when the chars within the symbol need to
1762 /// be accessed. It deliberately has limited functionality and should only be
1763 /// used for temporary values.
1764 ///
1765 /// Because the interner outlives any thread which uses this type, we can
1766 /// safely treat `string` which points to interner data, as an immortal string,
1767 /// as long as this type never crosses between threads.
1768 //
1769 // FIXME: ensure that the interner outlives any thread which uses `SymbolStr`,
1770 // by creating a new thread right after constructing the interner.
1771 #[derive(Clone, Eq, PartialOrd, Ord)]
1772 pub struct SymbolStr {
1773     string: &'static str,
1774 }
1775
1776 // This impl allows a `SymbolStr` to be directly equated with a `String` or
1777 // `&str`.
1778 impl<T: std::ops::Deref<Target = str>> std::cmp::PartialEq<T> for SymbolStr {
1779     fn eq(&self, other: &T) -> bool {
1780         self.string == other.deref()
1781     }
1782 }
1783
1784 impl !Send for SymbolStr {}
1785 impl !Sync for SymbolStr {}
1786
1787 /// This impl means that if `ss` is a `SymbolStr`:
1788 /// - `*ss` is a `str`;
1789 /// - `&*ss` is a `&str` (and `match &*ss { ... }` is a common pattern).
1790 /// - `&ss as &str` is a `&str`, which means that `&ss` can be passed to a
1791 ///   function expecting a `&str`.
1792 impl std::ops::Deref for SymbolStr {
1793     type Target = str;
1794     #[inline]
1795     fn deref(&self) -> &str {
1796         self.string
1797     }
1798 }
1799
1800 impl fmt::Debug for SymbolStr {
1801     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1802         fmt::Debug::fmt(self.string, f)
1803     }
1804 }
1805
1806 impl fmt::Display for SymbolStr {
1807     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1808         fmt::Display::fmt(self.string, f)
1809     }
1810 }
1811
1812 impl<CTX> HashStable<CTX> for SymbolStr {
1813     #[inline]
1814     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1815         self.string.hash_stable(hcx, hasher)
1816     }
1817 }
1818
1819 impl<CTX> ToStableHashKey<CTX> for SymbolStr {
1820     type KeyType = SymbolStr;
1821
1822     #[inline]
1823     fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
1824         self.clone()
1825     }
1826 }