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