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