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