]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_span/src/symbol.rs
Rollup merge of #106661 - mjguzik:linux_statx, r=Mark-Simulacrum
[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_closures,
502         const_compare_raw_pointers,
503         const_constructor,
504         const_deallocate,
505         const_eval_limit,
506         const_eval_select,
507         const_evaluatable_checked,
508         const_extern_fn,
509         const_fn,
510         const_fn_floating_point_arithmetic,
511         const_fn_fn_ptr_basics,
512         const_fn_trait_bound,
513         const_fn_transmute,
514         const_fn_union,
515         const_fn_unsize,
516         const_for,
517         const_format_args,
518         const_generics,
519         const_generics_defaults,
520         const_if_match,
521         const_impl_trait,
522         const_in_array_repeat_expressions,
523         const_indexing,
524         const_let,
525         const_loop,
526         const_mut_refs,
527         const_panic,
528         const_panic_fmt,
529         const_precise_live_drops,
530         const_raw_ptr_deref,
531         const_raw_ptr_to_usize_cast,
532         const_refs_to_cell,
533         const_trait,
534         const_trait_bound_opt_out,
535         const_trait_impl,
536         const_try,
537         constant,
538         constructor,
539         context,
540         copy,
541         copy_closures,
542         copy_nonoverlapping,
543         copysignf32,
544         copysignf64,
545         core,
546         core_panic,
547         core_panic_2015_macro,
548         core_panic_2021_macro,
549         core_panic_macro,
550         cosf32,
551         cosf64,
552         count,
553         cr,
554         crate_id,
555         crate_in_paths,
556         crate_local,
557         crate_name,
558         crate_type,
559         crate_visibility_modifier,
560         crt_dash_static: "crt-static",
561         cstring_type,
562         ctlz,
563         ctlz_nonzero,
564         ctpop,
565         cttz,
566         cttz_nonzero,
567         custom_attribute,
568         custom_derive,
569         custom_inner_attributes,
570         custom_mir,
571         custom_test_frameworks,
572         d,
573         d32,
574         dbg_macro,
575         dead_code,
576         dealloc,
577         debug,
578         debug_assert_eq_macro,
579         debug_assert_macro,
580         debug_assert_ne_macro,
581         debug_assertions,
582         debug_struct,
583         debug_struct_fields_finish,
584         debug_tuple,
585         debug_tuple_fields_finish,
586         debugger_visualizer,
587         decl_macro,
588         declare_lint_pass,
589         decode,
590         default_alloc_error_handler,
591         default_lib_allocator,
592         default_method_body_is_const,
593         default_type_parameter_fallback,
594         default_type_params,
595         delay_span_bug_from_inside_query,
596         deny,
597         deprecated,
598         deprecated_safe,
599         deprecated_suggestion,
600         deref,
601         deref_method,
602         deref_mut,
603         deref_target,
604         derive,
605         derive_const,
606         derive_default_enum,
607         destruct,
608         destructuring_assignment,
609         diagnostic,
610         direct,
611         discriminant_kind,
612         discriminant_type,
613         discriminant_value,
614         dispatch_from_dyn,
615         div,
616         div_assign,
617         do_not_recommend,
618         doc,
619         doc_alias,
620         doc_auto_cfg,
621         doc_cfg,
622         doc_cfg_hide,
623         doc_keyword,
624         doc_masked,
625         doc_notable_trait,
626         doc_primitive,
627         doc_spotlight,
628         doctest,
629         document_private_items,
630         dotdot: "..",
631         dotdot_in_tuple_patterns,
632         dotdoteq_in_patterns,
633         dreg,
634         dreg_low16,
635         dreg_low8,
636         drop,
637         drop_in_place,
638         drop_types_in_const,
639         dropck_eyepatch,
640         dropck_parametricity,
641         dylib,
642         dyn_metadata,
643         dyn_star,
644         dyn_trait,
645         e,
646         edition_panic,
647         eh_catch_typeinfo,
648         eh_personality,
649         emit_enum,
650         emit_enum_variant,
651         emit_enum_variant_arg,
652         emit_struct,
653         emit_struct_field,
654         enable,
655         encode,
656         end,
657         env,
658         eprint_macro,
659         eprintln_macro,
660         eq,
661         ermsb_target_feature,
662         exact_div,
663         except,
664         exchange_malloc,
665         exclusive_range_pattern,
666         exhaustive_integer_patterns,
667         exhaustive_patterns,
668         existential_type,
669         exp2f32,
670         exp2f64,
671         expect,
672         expected,
673         expf32,
674         expf64,
675         explicit_generic_args_with_impl_trait,
676         export_name,
677         expr,
678         extended_key_value_attributes,
679         extended_varargs_abi_support,
680         extern_absolute_paths,
681         extern_crate_item_prelude,
682         extern_crate_self,
683         extern_in_paths,
684         extern_prelude,
685         extern_types,
686         external_doc,
687         f,
688         f16c_target_feature,
689         f32,
690         f64,
691         fabsf32,
692         fabsf64,
693         fadd_fast,
694         fake_variadic,
695         fdiv_fast,
696         feature,
697         fence,
698         ferris: "🦀",
699         fetch_update,
700         ffi,
701         ffi_const,
702         ffi_pure,
703         ffi_returns_twice,
704         field,
705         field_init_shorthand,
706         file,
707         fill,
708         flags,
709         float,
710         float_to_int_unchecked,
711         floorf32,
712         floorf64,
713         fmaf32,
714         fmaf64,
715         fmt,
716         fmul_fast,
717         fn_align,
718         fn_must_use,
719         fn_mut,
720         fn_once,
721         fn_once_output,
722         forbid,
723         forget,
724         format,
725         format_args,
726         format_args_capture,
727         format_args_macro,
728         format_args_nl,
729         format_macro,
730         freeze,
731         freg,
732         frem_fast,
733         from,
734         from_desugaring,
735         from_iter,
736         from_method,
737         from_output,
738         from_residual,
739         from_size_align_unchecked,
740         from_usize,
741         from_yeet,
742         fsub_fast,
743         fundamental,
744         future,
745         future_trait,
746         gdb_script_file,
747         ge,
748         gen_future,
749         gen_kill,
750         generator,
751         generator_clone,
752         generator_state,
753         generators,
754         generic_arg_infer,
755         generic_assert,
756         generic_associated_types,
757         generic_associated_types_extended,
758         generic_const_exprs,
759         generic_param_attrs,
760         get_context,
761         global_allocator,
762         global_asm,
763         globs,
764         gt,
765         half_open_range_patterns,
766         half_open_range_patterns_in_slices,
767         hash,
768         hexagon_target_feature,
769         hidden,
770         homogeneous_aggregate,
771         html_favicon_url,
772         html_logo_url,
773         html_no_source,
774         html_playground_url,
775         html_root_url,
776         hwaddress,
777         i,
778         i128,
779         i128_type,
780         i16,
781         i32,
782         i64,
783         i8,
784         ident,
785         identity_future,
786         if_let,
787         if_let_guard,
788         if_while_or_patterns,
789         ignore,
790         impl_header_lifetime_elision,
791         impl_lint_pass,
792         impl_trait_in_bindings,
793         impl_trait_in_fn_trait_return,
794         impl_trait_projections,
795         implied_by,
796         import,
797         import_name_type,
798         import_shadowing,
799         imported_main,
800         in_band_lifetimes,
801         include,
802         include_bytes,
803         include_bytes_macro,
804         include_str,
805         include_str_macro,
806         inclusive_range_syntax,
807         index,
808         index_mut,
809         infer_outlives_requirements,
810         infer_static_outlives_requirements,
811         inherent_associated_types,
812         inherit,
813         inlateout,
814         inline,
815         inline_const,
816         inline_const_pat,
817         inout,
818         instruction_set,
819         integer_: "integer",
820         integral,
821         into_future,
822         into_iter,
823         intra_doc_pointers,
824         intrinsics,
825         irrefutable_let_patterns,
826         isa_attribute,
827         isize,
828         issue,
829         issue_5723_bootstrap,
830         issue_tracker_base_url,
831         item,
832         item_like_imports,
833         iter,
834         iter_repeat,
835         iterator_collect_fn,
836         kcfi,
837         keyword,
838         kind,
839         kreg,
840         kreg0,
841         label,
842         label_break_value,
843         lang,
844         lang_items,
845         large_assignments,
846         lateout,
847         lazy_normalization_consts,
848         le,
849         len,
850         let_chains,
851         let_else,
852         lhs,
853         lib,
854         libc,
855         lifetime,
856         lifetimes,
857         likely,
858         line,
859         link,
860         link_args,
861         link_cfg,
862         link_llvm_intrinsics,
863         link_name,
864         link_ordinal,
865         link_section,
866         linkage,
867         linker,
868         lint_reasons,
869         literal,
870         load,
871         loaded_from_disk,
872         local,
873         local_inner_macros,
874         log10f32,
875         log10f64,
876         log2f32,
877         log2f64,
878         log_syntax,
879         logf32,
880         logf64,
881         loop_break_value,
882         lt,
883         macro_at_most_once_rep,
884         macro_attributes_in_derive_output,
885         macro_escape,
886         macro_export,
887         macro_lifetime_matcher,
888         macro_literal_matcher,
889         macro_metavar_expr,
890         macro_reexport,
891         macro_use,
892         macro_vis_matcher,
893         macros_in_extern,
894         main,
895         managed_boxes,
896         manually_drop,
897         map,
898         marker,
899         marker_trait_attr,
900         masked,
901         match_beginning_vert,
902         match_default_bindings,
903         matches_macro,
904         maxnumf32,
905         maxnumf64,
906         may_dangle,
907         may_unwind,
908         maybe_uninit,
909         maybe_uninit_uninit,
910         maybe_uninit_zeroed,
911         mem_discriminant,
912         mem_drop,
913         mem_forget,
914         mem_replace,
915         mem_size_of,
916         mem_size_of_val,
917         mem_uninitialized,
918         mem_variant_count,
919         mem_zeroed,
920         member_constraints,
921         memory,
922         memtag,
923         message,
924         meta,
925         metadata_type,
926         min_align_of,
927         min_align_of_val,
928         min_const_fn,
929         min_const_generics,
930         min_const_unsafe_fn,
931         min_specialization,
932         min_type_alias_impl_trait,
933         minnumf32,
934         minnumf64,
935         mips_target_feature,
936         miri,
937         misc,
938         mmx_reg,
939         modifiers,
940         module,
941         module_path,
942         more_qualified_paths,
943         more_struct_aliases,
944         movbe_target_feature,
945         move_ref_pattern,
946         move_size_limit,
947         mul,
948         mul_assign,
949         mul_with_overflow,
950         must_not_suspend,
951         must_use,
952         naked,
953         naked_functions,
954         name,
955         names,
956         native_link_modifiers,
957         native_link_modifiers_as_needed,
958         native_link_modifiers_bundle,
959         native_link_modifiers_verbatim,
960         native_link_modifiers_whole_archive,
961         natvis_file,
962         ne,
963         nearbyintf32,
964         nearbyintf64,
965         needs_allocator,
966         needs_drop,
967         needs_panic_runtime,
968         neg,
969         negate_unsigned,
970         negative_impls,
971         neon,
972         never,
973         never_type,
974         never_type_fallback,
975         new,
976         new_binary,
977         new_debug,
978         new_display,
979         new_lower_exp,
980         new_lower_hex,
981         new_octal,
982         new_pointer,
983         new_unchecked,
984         new_upper_exp,
985         new_upper_hex,
986         new_v1,
987         new_v1_formatted,
988         next,
989         nll,
990         no,
991         no_builtins,
992         no_core,
993         no_coverage,
994         no_crate_inject,
995         no_debug,
996         no_default_passes,
997         no_implicit_prelude,
998         no_inline,
999         no_link,
1000         no_main,
1001         no_mangle,
1002         no_sanitize,
1003         no_stack_check,
1004         no_start,
1005         no_std,
1006         nomem,
1007         non_ascii_idents,
1008         non_exhaustive,
1009         non_exhaustive_omitted_patterns_lint,
1010         non_modrs_mods,
1011         nontemporal_store,
1012         noop_method_borrow,
1013         noop_method_clone,
1014         noop_method_deref,
1015         noreturn,
1016         nostack,
1017         not,
1018         notable_trait,
1019         note,
1020         object_safe_for_dispatch,
1021         of,
1022         offset,
1023         omit_gdb_pretty_printer_section,
1024         on,
1025         on_unimplemented,
1026         oom,
1027         opaque,
1028         ops,
1029         opt_out_copy,
1030         optimize,
1031         optimize_attribute,
1032         optin_builtin_traits,
1033         option,
1034         option_env,
1035         options,
1036         or,
1037         or_patterns,
1038         other,
1039         out,
1040         overlapping_marker_traits,
1041         owned_box,
1042         packed,
1043         panic,
1044         panic_2015,
1045         panic_2021,
1046         panic_abort,
1047         panic_bounds_check,
1048         panic_cannot_unwind,
1049         panic_display,
1050         panic_fmt,
1051         panic_handler,
1052         panic_impl,
1053         panic_implementation,
1054         panic_info,
1055         panic_location,
1056         panic_nounwind,
1057         panic_runtime,
1058         panic_str,
1059         panic_unwind,
1060         panicking,
1061         param_attrs,
1062         parent_label,
1063         partial_cmp,
1064         partial_ord,
1065         passes,
1066         pat,
1067         pat_param,
1068         path,
1069         pattern_parentheses,
1070         phantom_data,
1071         pin,
1072         platform_intrinsics,
1073         plugin,
1074         plugin_registrar,
1075         plugins,
1076         pointee_trait,
1077         pointer,
1078         pointer_sized,
1079         poll,
1080         position,
1081         post_dash_lto: "post-lto",
1082         powerpc_target_feature,
1083         powf32,
1084         powf64,
1085         powif32,
1086         powif64,
1087         pre_dash_lto: "pre-lto",
1088         precise_pointer_size_matching,
1089         precision,
1090         pref_align_of,
1091         prefetch_read_data,
1092         prefetch_read_instruction,
1093         prefetch_write_data,
1094         prefetch_write_instruction,
1095         preg,
1096         prelude,
1097         prelude_import,
1098         preserves_flags,
1099         primitive,
1100         print_macro,
1101         println_macro,
1102         proc_dash_macro: "proc-macro",
1103         proc_macro,
1104         proc_macro_attribute,
1105         proc_macro_derive,
1106         proc_macro_expr,
1107         proc_macro_gen,
1108         proc_macro_hygiene,
1109         proc_macro_internals,
1110         proc_macro_mod,
1111         proc_macro_non_items,
1112         proc_macro_path_invoc,
1113         profiler_builtins,
1114         profiler_runtime,
1115         ptr,
1116         ptr_guaranteed_cmp,
1117         ptr_mask,
1118         ptr_null,
1119         ptr_null_mut,
1120         ptr_offset_from,
1121         ptr_offset_from_unsigned,
1122         pub_macro_rules,
1123         pub_restricted,
1124         public,
1125         pure,
1126         pushpop_unsafe,
1127         qreg,
1128         qreg_low4,
1129         qreg_low8,
1130         quad_precision_float,
1131         question_mark,
1132         quote,
1133         range_inclusive_new,
1134         raw_dylib,
1135         raw_eq,
1136         raw_identifiers,
1137         raw_ref_op,
1138         re_rebalance_coherence,
1139         read_enum,
1140         read_enum_variant,
1141         read_enum_variant_arg,
1142         read_struct,
1143         read_struct_field,
1144         readonly,
1145         realloc,
1146         reason,
1147         receiver,
1148         recursion_limit,
1149         reexport_test_harness_main,
1150         ref_unwind_safe_trait,
1151         reference,
1152         reflect,
1153         reg,
1154         reg16,
1155         reg32,
1156         reg64,
1157         reg_abcd,
1158         reg_byte,
1159         reg_iw,
1160         reg_nonzero,
1161         reg_pair,
1162         reg_ptr,
1163         reg_upper,
1164         register_attr,
1165         register_tool,
1166         relaxed_adts,
1167         relaxed_struct_unsize,
1168         rem,
1169         rem_assign,
1170         repr,
1171         repr128,
1172         repr_align,
1173         repr_align_enum,
1174         repr_packed,
1175         repr_simd,
1176         repr_transparent,
1177         require,
1178         residual,
1179         result,
1180         return_position_impl_trait_in_trait,
1181         rhs,
1182         rintf32,
1183         rintf64,
1184         riscv_target_feature,
1185         rlib,
1186         rotate_left,
1187         rotate_right,
1188         roundf32,
1189         roundf64,
1190         rt,
1191         rtm_target_feature,
1192         rust,
1193         rust_2015,
1194         rust_2015_preview,
1195         rust_2018,
1196         rust_2018_preview,
1197         rust_2021,
1198         rust_2021_preview,
1199         rust_2024,
1200         rust_2024_preview,
1201         rust_begin_unwind,
1202         rust_cold_cc,
1203         rust_eh_catch_typeinfo,
1204         rust_eh_personality,
1205         rustc,
1206         rustc_allocator,
1207         rustc_allocator_zeroed,
1208         rustc_allow_const_fn_unstable,
1209         rustc_allow_incoherent_impl,
1210         rustc_allowed_through_unstable_modules,
1211         rustc_attrs,
1212         rustc_box,
1213         rustc_builtin_macro,
1214         rustc_capture_analysis,
1215         rustc_clean,
1216         rustc_coherence_is_core,
1217         rustc_const_stable,
1218         rustc_const_unstable,
1219         rustc_conversion_suggestion,
1220         rustc_deallocator,
1221         rustc_def_path,
1222         rustc_default_body_unstable,
1223         rustc_deny_explicit_impl,
1224         rustc_diagnostic_item,
1225         rustc_diagnostic_macros,
1226         rustc_dirty,
1227         rustc_do_not_const_check,
1228         rustc_dummy,
1229         rustc_dump_env_program_clauses,
1230         rustc_dump_program_clauses,
1231         rustc_dump_user_substs,
1232         rustc_dump_vtable,
1233         rustc_effective_visibility,
1234         rustc_error,
1235         rustc_evaluate_where_clauses,
1236         rustc_expected_cgu_reuse,
1237         rustc_has_incoherent_inherent_impls,
1238         rustc_if_this_changed,
1239         rustc_inherit_overflow_checks,
1240         rustc_insignificant_dtor,
1241         rustc_layout,
1242         rustc_layout_scalar_valid_range_end,
1243         rustc_layout_scalar_valid_range_start,
1244         rustc_legacy_const_generics,
1245         rustc_lint_diagnostics,
1246         rustc_lint_opt_deny_field_access,
1247         rustc_lint_opt_ty,
1248         rustc_lint_query_instability,
1249         rustc_macro_transparency,
1250         rustc_main,
1251         rustc_mir,
1252         rustc_must_implement_one_of,
1253         rustc_nonnull_optimization_guaranteed,
1254         rustc_nounwind,
1255         rustc_object_lifetime_default,
1256         rustc_on_unimplemented,
1257         rustc_outlives,
1258         rustc_paren_sugar,
1259         rustc_partition_codegened,
1260         rustc_partition_reused,
1261         rustc_pass_by_value,
1262         rustc_peek,
1263         rustc_peek_definite_init,
1264         rustc_peek_liveness,
1265         rustc_peek_maybe_init,
1266         rustc_peek_maybe_uninit,
1267         rustc_polymorphize_error,
1268         rustc_private,
1269         rustc_proc_macro_decls,
1270         rustc_promotable,
1271         rustc_reallocator,
1272         rustc_regions,
1273         rustc_reservation_impl,
1274         rustc_safe_intrinsic,
1275         rustc_serialize,
1276         rustc_skip_array_during_method_dispatch,
1277         rustc_specialization_trait,
1278         rustc_std_internal_symbol,
1279         rustc_strict_coherence,
1280         rustc_symbol_name,
1281         rustc_test_marker,
1282         rustc_then_this_would_need,
1283         rustc_trivial_field_reads,
1284         rustc_unsafe_specialization_marker,
1285         rustc_variance,
1286         rustdoc,
1287         rustdoc_internals,
1288         rustdoc_missing_doc_code_examples,
1289         rustfmt,
1290         rvalue_static_promotion,
1291         s,
1292         safety,
1293         sanitize,
1294         sanitizer_runtime,
1295         saturating_add,
1296         saturating_sub,
1297         self_in_typedefs,
1298         self_struct_ctor,
1299         semitransparent,
1300         shadow_call_stack,
1301         shl,
1302         shl_assign,
1303         should_panic,
1304         shr,
1305         shr_assign,
1306         sig_dfl,
1307         sig_ign,
1308         simd,
1309         simd_add,
1310         simd_and,
1311         simd_arith_offset,
1312         simd_as,
1313         simd_bitmask,
1314         simd_cast,
1315         simd_cast_ptr,
1316         simd_ceil,
1317         simd_div,
1318         simd_eq,
1319         simd_expose_addr,
1320         simd_extract,
1321         simd_fabs,
1322         simd_fcos,
1323         simd_fexp,
1324         simd_fexp2,
1325         simd_ffi,
1326         simd_flog,
1327         simd_flog10,
1328         simd_flog2,
1329         simd_floor,
1330         simd_fma,
1331         simd_fmax,
1332         simd_fmin,
1333         simd_fpow,
1334         simd_fpowi,
1335         simd_from_exposed_addr,
1336         simd_fsin,
1337         simd_fsqrt,
1338         simd_gather,
1339         simd_ge,
1340         simd_gt,
1341         simd_insert,
1342         simd_le,
1343         simd_lt,
1344         simd_mul,
1345         simd_ne,
1346         simd_neg,
1347         simd_or,
1348         simd_reduce_add_ordered,
1349         simd_reduce_add_unordered,
1350         simd_reduce_all,
1351         simd_reduce_and,
1352         simd_reduce_any,
1353         simd_reduce_max,
1354         simd_reduce_max_nanless,
1355         simd_reduce_min,
1356         simd_reduce_min_nanless,
1357         simd_reduce_mul_ordered,
1358         simd_reduce_mul_unordered,
1359         simd_reduce_or,
1360         simd_reduce_xor,
1361         simd_rem,
1362         simd_round,
1363         simd_saturating_add,
1364         simd_saturating_sub,
1365         simd_scatter,
1366         simd_select,
1367         simd_select_bitmask,
1368         simd_shl,
1369         simd_shr,
1370         simd_shuffle,
1371         simd_sub,
1372         simd_trunc,
1373         simd_xor,
1374         since,
1375         sinf32,
1376         sinf64,
1377         size,
1378         size_of,
1379         size_of_val,
1380         sized,
1381         skip,
1382         slice,
1383         slice_len_fn,
1384         slice_patterns,
1385         slicing_syntax,
1386         soft,
1387         specialization,
1388         speed,
1389         spotlight,
1390         sqrtf32,
1391         sqrtf64,
1392         sreg,
1393         sreg_low16,
1394         sse,
1395         sse4a_target_feature,
1396         stable,
1397         staged_api,
1398         start,
1399         state,
1400         static_in_const,
1401         static_nobundle,
1402         static_recursion,
1403         staticlib,
1404         std,
1405         std_panic,
1406         std_panic_2015_macro,
1407         std_panic_macro,
1408         stmt,
1409         stmt_expr_attributes,
1410         stop_after_dataflow,
1411         store,
1412         str,
1413         str_split_whitespace,
1414         str_trim,
1415         str_trim_end,
1416         str_trim_start,
1417         strict_provenance,
1418         string_deref_patterns,
1419         stringify,
1420         struct_field_attributes,
1421         struct_inherit,
1422         struct_variant,
1423         structural_match,
1424         structural_peq,
1425         structural_teq,
1426         sty,
1427         sub,
1428         sub_assign,
1429         sub_with_overflow,
1430         suggestion,
1431         sym,
1432         sync,
1433         t32,
1434         target,
1435         target_abi,
1436         target_arch,
1437         target_endian,
1438         target_env,
1439         target_family,
1440         target_feature,
1441         target_feature_11,
1442         target_has_atomic,
1443         target_has_atomic_equal_alignment,
1444         target_has_atomic_load_store,
1445         target_os,
1446         target_pointer_width,
1447         target_thread_local,
1448         target_vendor,
1449         tbm_target_feature,
1450         termination,
1451         termination_trait,
1452         termination_trait_test,
1453         test,
1454         test_2018_feature,
1455         test_accepted_feature,
1456         test_case,
1457         test_removed_feature,
1458         test_runner,
1459         test_unstable_lint,
1460         thread,
1461         thread_local,
1462         thread_local_macro,
1463         thumb2,
1464         thumb_mode: "thumb-mode",
1465         tmm_reg,
1466         to_string,
1467         to_vec,
1468         todo_macro,
1469         tool_attributes,
1470         tool_lints,
1471         trace_macros,
1472         track_caller,
1473         trait_alias,
1474         trait_upcasting,
1475         transmute,
1476         transmute_opts,
1477         transmute_trait,
1478         transparent,
1479         transparent_enums,
1480         transparent_unions,
1481         trivial_bounds,
1482         truncf32,
1483         truncf64,
1484         try_blocks,
1485         try_capture,
1486         try_from,
1487         try_into,
1488         try_trait_v2,
1489         tt,
1490         tuple,
1491         tuple_indexing,
1492         tuple_trait,
1493         two_phase,
1494         ty,
1495         type_alias_enum_variants,
1496         type_alias_impl_trait,
1497         type_ascribe,
1498         type_ascription,
1499         type_changing_struct_update,
1500         type_id,
1501         type_length_limit,
1502         type_macros,
1503         type_name,
1504         u128,
1505         u16,
1506         u32,
1507         u64,
1508         u8,
1509         unaligned_volatile_load,
1510         unaligned_volatile_store,
1511         unboxed_closures,
1512         unchecked_add,
1513         unchecked_div,
1514         unchecked_mul,
1515         unchecked_rem,
1516         unchecked_shl,
1517         unchecked_shr,
1518         unchecked_sub,
1519         underscore_const_names,
1520         underscore_imports,
1521         underscore_lifetimes,
1522         uniform_paths,
1523         unimplemented_macro,
1524         unit,
1525         universal_impl_trait,
1526         unix,
1527         unix_sigpipe,
1528         unlikely,
1529         unmarked_api,
1530         unpin,
1531         unreachable,
1532         unreachable_2015,
1533         unreachable_2015_macro,
1534         unreachable_2021,
1535         unreachable_code,
1536         unreachable_display,
1537         unreachable_macro,
1538         unrestricted_attribute_tokens,
1539         unsafe_block_in_unsafe_fn,
1540         unsafe_cell,
1541         unsafe_no_drop_flag,
1542         unsafe_pin_internals,
1543         unsize,
1544         unsized_fn_params,
1545         unsized_locals,
1546         unsized_tuple_coercion,
1547         unstable,
1548         unstable_location_reason_default: "this crate is being loaded from the sysroot, an \
1549                           unstable location; did you mean to load this crate \
1550                           from crates.io via `Cargo.toml` instead?",
1551         untagged_unions,
1552         unused_imports,
1553         unwind,
1554         unwind_attributes,
1555         unwind_safe_trait,
1556         unwrap,
1557         unwrap_or,
1558         use_extern_macros,
1559         use_nested_groups,
1560         used,
1561         used_with_arg,
1562         using,
1563         usize,
1564         v1,
1565         va_arg,
1566         va_copy,
1567         va_end,
1568         va_list,
1569         va_start,
1570         val,
1571         validity,
1572         values,
1573         var,
1574         variant_count,
1575         vec,
1576         vec_macro,
1577         version,
1578         vfp2,
1579         vis,
1580         visible_private_types,
1581         volatile,
1582         volatile_copy_memory,
1583         volatile_copy_nonoverlapping_memory,
1584         volatile_load,
1585         volatile_set_memory,
1586         volatile_store,
1587         vreg,
1588         vreg_low16,
1589         vtable_align,
1590         vtable_size,
1591         warn,
1592         wasm_abi,
1593         wasm_import_module,
1594         wasm_target_feature,
1595         while_let,
1596         width,
1597         windows,
1598         windows_subsystem,
1599         with_negative_coherence,
1600         wrapping_add,
1601         wrapping_mul,
1602         wrapping_sub,
1603         wreg,
1604         write_bytes,
1605         write_macro,
1606         write_str,
1607         writeln_macro,
1608         x87_reg,
1609         xer,
1610         xmm_reg,
1611         yeet_desugar_details,
1612         yeet_expr,
1613         ymm_reg,
1614         zmm_reg,
1615     }
1616 }
1617
1618 #[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
1619 pub struct Ident {
1620     pub name: Symbol,
1621     pub span: Span,
1622 }
1623
1624 impl Ident {
1625     #[inline]
1626     /// Constructs a new identifier from a symbol and a span.
1627     pub const fn new(name: Symbol, span: Span) -> Ident {
1628         Ident { name, span }
1629     }
1630
1631     /// Constructs a new identifier with a dummy span.
1632     #[inline]
1633     pub const fn with_dummy_span(name: Symbol) -> Ident {
1634         Ident::new(name, DUMMY_SP)
1635     }
1636
1637     #[inline]
1638     pub fn empty() -> Ident {
1639         Ident::with_dummy_span(kw::Empty)
1640     }
1641
1642     /// Maps a string to an identifier with a dummy span.
1643     pub fn from_str(string: &str) -> Ident {
1644         Ident::with_dummy_span(Symbol::intern(string))
1645     }
1646
1647     /// Maps a string and a span to an identifier.
1648     pub fn from_str_and_span(string: &str, span: Span) -> Ident {
1649         Ident::new(Symbol::intern(string), span)
1650     }
1651
1652     /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
1653     pub fn with_span_pos(self, span: Span) -> Ident {
1654         Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
1655     }
1656
1657     pub fn without_first_quote(self) -> Ident {
1658         Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
1659     }
1660
1661     /// "Normalize" ident for use in comparisons using "item hygiene".
1662     /// Identifiers with same string value become same if they came from the same macro 2.0 macro
1663     /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
1664     /// different macro 2.0 macros.
1665     /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
1666     pub fn normalize_to_macros_2_0(self) -> Ident {
1667         Ident::new(self.name, self.span.normalize_to_macros_2_0())
1668     }
1669
1670     /// "Normalize" ident for use in comparisons using "local variable hygiene".
1671     /// Identifiers with same string value become same if they came from the same non-transparent
1672     /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
1673     /// non-transparent macros.
1674     /// Technically, this operation strips all transparent marks from ident's syntactic context.
1675     #[inline]
1676     pub fn normalize_to_macro_rules(self) -> Ident {
1677         Ident::new(self.name, self.span.normalize_to_macro_rules())
1678     }
1679
1680     /// Access the underlying string. This is a slowish operation because it
1681     /// requires locking the symbol interner.
1682     ///
1683     /// Note that the lifetime of the return value is a lie. See
1684     /// `Symbol::as_str()` for details.
1685     pub fn as_str(&self) -> &str {
1686         self.name.as_str()
1687     }
1688 }
1689
1690 impl PartialEq for Ident {
1691     #[inline]
1692     fn eq(&self, rhs: &Self) -> bool {
1693         self.name == rhs.name && self.span.eq_ctxt(rhs.span)
1694     }
1695 }
1696
1697 impl Hash for Ident {
1698     fn hash<H: Hasher>(&self, state: &mut H) {
1699         self.name.hash(state);
1700         self.span.ctxt().hash(state);
1701     }
1702 }
1703
1704 impl fmt::Debug for Ident {
1705     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1706         fmt::Display::fmt(self, f)?;
1707         fmt::Debug::fmt(&self.span.ctxt(), f)
1708     }
1709 }
1710
1711 /// This implementation is supposed to be used in error messages, so it's expected to be identical
1712 /// to printing the original identifier token written in source code (`token_to_string`),
1713 /// except that AST identifiers don't keep the rawness flag, so we have to guess it.
1714 impl fmt::Display for Ident {
1715     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1716         fmt::Display::fmt(&IdentPrinter::new(self.name, self.is_raw_guess(), None), f)
1717     }
1718 }
1719
1720 /// The most general type to print identifiers.
1721 ///
1722 /// AST pretty-printer is used as a fallback for turning AST structures into token streams for
1723 /// proc macros. Additionally, proc macros may stringify their input and expect it survive the
1724 /// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
1725 /// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
1726 /// hygiene data, most importantly name of the crate it refers to.
1727 /// As a result we print `$crate` as `crate` if it refers to the local crate
1728 /// and as `::other_crate_name` if it refers to some other crate.
1729 /// Note, that this is only done if the ident token is printed from inside of AST pretty-printing,
1730 /// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
1731 /// so we should not perform this lossy conversion if the top level call to the pretty-printer was
1732 /// done for a token stream or a single token.
1733 pub struct IdentPrinter {
1734     symbol: Symbol,
1735     is_raw: bool,
1736     /// Span used for retrieving the crate name to which `$crate` refers to,
1737     /// if this field is `None` then the `$crate` conversion doesn't happen.
1738     convert_dollar_crate: Option<Span>,
1739 }
1740
1741 impl IdentPrinter {
1742     /// The most general `IdentPrinter` constructor. Do not use this.
1743     pub fn new(symbol: Symbol, is_raw: bool, convert_dollar_crate: Option<Span>) -> IdentPrinter {
1744         IdentPrinter { symbol, is_raw, convert_dollar_crate }
1745     }
1746
1747     /// This implementation is supposed to be used when printing identifiers
1748     /// as a part of pretty-printing for larger AST pieces.
1749     /// Do not use this either.
1750     pub fn for_ast_ident(ident: Ident, is_raw: bool) -> IdentPrinter {
1751         IdentPrinter::new(ident.name, is_raw, Some(ident.span))
1752     }
1753 }
1754
1755 impl fmt::Display for IdentPrinter {
1756     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1757         if self.is_raw {
1758             f.write_str("r#")?;
1759         } else if self.symbol == kw::DollarCrate {
1760             if let Some(span) = self.convert_dollar_crate {
1761                 let converted = span.ctxt().dollar_crate_name();
1762                 if !converted.is_path_segment_keyword() {
1763                     f.write_str("::")?;
1764                 }
1765                 return fmt::Display::fmt(&converted, f);
1766             }
1767         }
1768         fmt::Display::fmt(&self.symbol, f)
1769     }
1770 }
1771
1772 /// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
1773 /// construction.
1774 // FIXME(matthewj, petrochenkov) Use this more often, add a similar
1775 // `ModernIdent` struct and use that as well.
1776 #[derive(Copy, Clone, Eq, PartialEq, Hash)]
1777 pub struct MacroRulesNormalizedIdent(Ident);
1778
1779 impl MacroRulesNormalizedIdent {
1780     pub fn new(ident: Ident) -> Self {
1781         Self(ident.normalize_to_macro_rules())
1782     }
1783 }
1784
1785 impl fmt::Debug for MacroRulesNormalizedIdent {
1786     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1787         fmt::Debug::fmt(&self.0, f)
1788     }
1789 }
1790
1791 impl fmt::Display for MacroRulesNormalizedIdent {
1792     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1793         fmt::Display::fmt(&self.0, f)
1794     }
1795 }
1796
1797 /// An interned string.
1798 ///
1799 /// Internally, a `Symbol` is implemented as an index, and all operations
1800 /// (including hashing, equality, and ordering) operate on that index. The use
1801 /// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
1802 /// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
1803 ///
1804 /// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
1805 /// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
1806 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1807 pub struct Symbol(SymbolIndex);
1808
1809 rustc_index::newtype_index! {
1810     struct SymbolIndex {}
1811 }
1812
1813 impl Symbol {
1814     const fn new(n: u32) -> Self {
1815         Symbol(SymbolIndex::from_u32(n))
1816     }
1817
1818     /// for use in Decoder only
1819     pub fn new_from_decoded(n: u32) -> Self {
1820         Self::new(n)
1821     }
1822
1823     /// Maps a string to its interned representation.
1824     pub fn intern(string: &str) -> Self {
1825         with_session_globals(|session_globals| session_globals.symbol_interner.intern(string))
1826     }
1827
1828     /// Access the underlying string. This is a slowish operation because it
1829     /// requires locking the symbol interner.
1830     ///
1831     /// Note that the lifetime of the return value is a lie. It's not the same
1832     /// as `&self`, but actually tied to the lifetime of the underlying
1833     /// interner. Interners are long-lived, and there are very few of them, and
1834     /// this function is typically used for short-lived things, so in practice
1835     /// it works out ok.
1836     pub fn as_str(&self) -> &str {
1837         with_session_globals(|session_globals| unsafe {
1838             std::mem::transmute::<&str, &str>(session_globals.symbol_interner.get(*self))
1839         })
1840     }
1841
1842     pub fn as_u32(self) -> u32 {
1843         self.0.as_u32()
1844     }
1845
1846     pub fn is_empty(self) -> bool {
1847         self == kw::Empty
1848     }
1849
1850     /// This method is supposed to be used in error messages, so it's expected to be
1851     /// identical to printing the original identifier token written in source code
1852     /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
1853     /// or edition, so we have to guess the rawness using the global edition.
1854     pub fn to_ident_string(self) -> String {
1855         Ident::with_dummy_span(self).to_string()
1856     }
1857 }
1858
1859 impl fmt::Debug for Symbol {
1860     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1861         fmt::Debug::fmt(self.as_str(), f)
1862     }
1863 }
1864
1865 impl fmt::Display for Symbol {
1866     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1867         fmt::Display::fmt(self.as_str(), f)
1868     }
1869 }
1870
1871 // takes advantage of `str::to_string` specialization
1872 impl ToString for Symbol {
1873     fn to_string(&self) -> String {
1874         self.as_str().to_string()
1875     }
1876 }
1877
1878 impl<S: Encoder> Encodable<S> for Symbol {
1879     default fn encode(&self, s: &mut S) {
1880         s.emit_str(self.as_str());
1881     }
1882 }
1883
1884 impl<D: Decoder> Decodable<D> for Symbol {
1885     #[inline]
1886     default fn decode(d: &mut D) -> Symbol {
1887         Symbol::intern(d.read_str())
1888     }
1889 }
1890
1891 impl<CTX> HashStable<CTX> for Symbol {
1892     #[inline]
1893     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
1894         self.as_str().hash_stable(hcx, hasher);
1895     }
1896 }
1897
1898 impl<CTX> ToStableHashKey<CTX> for Symbol {
1899     type KeyType = String;
1900     #[inline]
1901     fn to_stable_hash_key(&self, _: &CTX) -> String {
1902         self.as_str().to_string()
1903     }
1904 }
1905
1906 #[derive(Default)]
1907 pub(crate) struct Interner(Lock<InternerInner>);
1908
1909 // The `&'static str`s in this type actually point into the arena.
1910 //
1911 // The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
1912 // found that to regress performance up to 2% in some cases. This might be
1913 // revisited after further improvements to `indexmap`.
1914 //
1915 // This type is private to prevent accidentally constructing more than one
1916 // `Interner` on the same thread, which makes it easy to mix up `Symbol`s
1917 // between `Interner`s.
1918 #[derive(Default)]
1919 struct InternerInner {
1920     arena: DroplessArena,
1921     names: FxHashMap<&'static str, Symbol>,
1922     strings: Vec<&'static str>,
1923 }
1924
1925 impl Interner {
1926     fn prefill(init: &[&'static str]) -> Self {
1927         Interner(Lock::new(InternerInner {
1928             strings: init.into(),
1929             names: init.iter().copied().zip((0..).map(Symbol::new)).collect(),
1930             ..Default::default()
1931         }))
1932     }
1933
1934     #[inline]
1935     fn intern(&self, string: &str) -> Symbol {
1936         let mut inner = self.0.lock();
1937         if let Some(&name) = inner.names.get(string) {
1938             return name;
1939         }
1940
1941         let name = Symbol::new(inner.strings.len() as u32);
1942
1943         // SAFETY: we convert from `&str` to `&[u8]`, clone it into the arena,
1944         // and immediately convert the clone back to `&[u8], all because there
1945         // is no `inner.arena.alloc_str()` method. This is clearly safe.
1946         let string: &str =
1947             unsafe { str::from_utf8_unchecked(inner.arena.alloc_slice(string.as_bytes())) };
1948
1949         // SAFETY: we can extend the arena allocation to `'static` because we
1950         // only access these while the arena is still alive.
1951         let string: &'static str = unsafe { &*(string as *const str) };
1952         inner.strings.push(string);
1953
1954         // This second hash table lookup can be avoided by using `RawEntryMut`,
1955         // but this code path isn't hot enough for it to be worth it. See
1956         // #91445 for details.
1957         inner.names.insert(string, name);
1958         name
1959     }
1960
1961     // Get the symbol as a string. `Symbol::as_str()` should be used in
1962     // preference to this function.
1963     fn get(&self, symbol: Symbol) -> &str {
1964         self.0.lock().strings[symbol.0.as_usize()]
1965     }
1966 }
1967
1968 // This module has a very short name because it's used a lot.
1969 /// This module contains all the defined keyword `Symbol`s.
1970 ///
1971 /// Given that `kw` is imported, use them like `kw::keyword_name`.
1972 /// For example `kw::Loop` or `kw::Break`.
1973 pub mod kw {
1974     pub use super::kw_generated::*;
1975 }
1976
1977 // This module has a very short name because it's used a lot.
1978 /// This module contains all the defined non-keyword `Symbol`s.
1979 ///
1980 /// Given that `sym` is imported, use them like `sym::symbol_name`.
1981 /// For example `sym::rustfmt` or `sym::u8`.
1982 pub mod sym {
1983     use super::Symbol;
1984
1985     #[doc(inline)]
1986     pub use super::sym_generated::*;
1987
1988     // Used from a macro in `librustc_feature/accepted.rs`
1989     pub use super::kw::MacroRules as macro_rules;
1990
1991     /// Get the symbol for an integer.
1992     ///
1993     /// The first few non-negative integers each have a static symbol and therefore
1994     /// are fast.
1995     pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
1996         if let Result::Ok(idx) = n.try_into() {
1997             if idx < 10 {
1998                 return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32);
1999             }
2000         }
2001         Symbol::intern(&n.to_string())
2002     }
2003 }
2004
2005 impl Symbol {
2006     fn is_special(self) -> bool {
2007         self <= kw::Underscore
2008     }
2009
2010     fn is_used_keyword_always(self) -> bool {
2011         self >= kw::As && self <= kw::While
2012     }
2013
2014     fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
2015         (self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
2016     }
2017
2018     fn is_unused_keyword_always(self) -> bool {
2019         self >= kw::Abstract && self <= kw::Yield
2020     }
2021
2022     fn is_unused_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
2023         self == kw::Try && edition() >= Edition::Edition2018
2024     }
2025
2026     pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
2027         self.is_special()
2028             || self.is_used_keyword_always()
2029             || self.is_unused_keyword_always()
2030             || self.is_used_keyword_conditional(edition)
2031             || self.is_unused_keyword_conditional(edition)
2032     }
2033
2034     /// A keyword or reserved identifier that can be used as a path segment.
2035     pub fn is_path_segment_keyword(self) -> bool {
2036         self == kw::Super
2037             || self == kw::SelfLower
2038             || self == kw::SelfUpper
2039             || self == kw::Crate
2040             || self == kw::PathRoot
2041             || self == kw::DollarCrate
2042     }
2043
2044     /// Returns `true` if the symbol is `true` or `false`.
2045     pub fn is_bool_lit(self) -> bool {
2046         self == kw::True || self == kw::False
2047     }
2048
2049     /// Returns `true` if this symbol can be a raw identifier.
2050     pub fn can_be_raw(self) -> bool {
2051         self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword()
2052     }
2053
2054     /// Is this symbol was interned in compiler's `symbols!` macro
2055     pub fn is_preinterned(self) -> bool {
2056         self.as_u32() < PREINTERNED_SYMBOLS_COUNT
2057     }
2058 }
2059
2060 impl Ident {
2061     /// Returns `true` for reserved identifiers used internally for elided lifetimes,
2062     /// unnamed method parameters, crate root module, error recovery etc.
2063     pub fn is_special(self) -> bool {
2064         self.name.is_special()
2065     }
2066
2067     /// Returns `true` if the token is a keyword used in the language.
2068     pub fn is_used_keyword(self) -> bool {
2069         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
2070         self.name.is_used_keyword_always()
2071             || self.name.is_used_keyword_conditional(|| self.span.edition())
2072     }
2073
2074     /// Returns `true` if the token is a keyword reserved for possible future use.
2075     pub fn is_unused_keyword(self) -> bool {
2076         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
2077         self.name.is_unused_keyword_always()
2078             || self.name.is_unused_keyword_conditional(|| self.span.edition())
2079     }
2080
2081     /// Returns `true` if the token is either a special identifier or a keyword.
2082     pub fn is_reserved(self) -> bool {
2083         // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
2084         self.name.is_reserved(|| self.span.edition())
2085     }
2086
2087     /// A keyword or reserved identifier that can be used as a path segment.
2088     pub fn is_path_segment_keyword(self) -> bool {
2089         self.name.is_path_segment_keyword()
2090     }
2091
2092     /// We see this identifier in a normal identifier position, like variable name or a type.
2093     /// How was it written originally? Did it use the raw form? Let's try to guess.
2094     pub fn is_raw_guess(self) -> bool {
2095         self.name.can_be_raw() && self.is_reserved()
2096     }
2097 }