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