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