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