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