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