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