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