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