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