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