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