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