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