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