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