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