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