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