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