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.
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}
;
12 use std
::cmp
::{Ord, PartialEq, PartialOrd}
;
14 use std
::hash
::{Hash, Hasher}
;
17 use crate::{with_session_globals, Edition, Span, DUMMY_SP}
;
22 // The proc macro code for this is in `compiler/rustc_macros/src/symbols.rs`.
24 // After modifying this list adjust `is_special`, `is_used_keyword`/`is_unused_keyword`,
25 // this should be rarely necessary though if the keywords are kept in alphabetic order.
27 // Special reserved identifiers used internally for elided lifetimes,
28 // unnamed method parameters, crate root module, error recovery etc.
31 DollarCrate
: "$crate",
34 // Keywords that are used in stable Rust.
71 // Keywords that are used in unstable Rust or reserved for future use.
85 // Edition-specific keywords that are used in stable Rust.
86 Async
: "async", // >= 2018 Edition only
87 Await
: "await", // >= 2018 Edition only
88 Dyn
: "dyn", // >= 2018 Edition only
90 // Edition-specific keywords that are used in unstable Rust or reserved for future use.
91 Try
: "try", // >= 2018 Edition only
93 // Special lifetime names
94 UnderscoreLifetime
: "'_",
95 StaticLifetime
: "'static",
97 // Weak keywords, have special meaning only in specific contexts.
101 MacroRules
: "macro_rules",
106 // Pre-interned symbols that can be referred to with `rustc_span::sym::*`.
108 // The symbol is the stringified identifier unless otherwise specified, in
109 // which case the name should mention the non-identifier punctuation.
110 // E.g. `sym::proc_dash_macro` represents "proc-macro", and it shouldn't be
111 // called `sym::proc_macro` because then it's easy to mistakenly think it
112 // represents "proc_macro".
114 // As well as the symbols listed, there are symbols for the strings
115 // "0", "1", ..., "9", which are accessible via `sym::integer`.
117 // The proc macro will abort if symbols are not in alphabetical order (as
118 // defined by `impl Ord for str`) or if any symbols are duplicated. Vim
119 // users can sort the list by selecting it and executing the command
120 // `:'<,'>!LC_ALL=C sort`.
122 // There is currently no checking that all symbols are used; that would be
232 ProceduralMasqueradeDummyType
,
280 aarch64_target_feature
,
284 abi_c_cmse_nonsecure_call
,
286 abi_msp430_interrupt
,
300 advanced_slice_patterns
,
316 allow_internal_unsafe
,
317 allow_internal_unstable
,
325 arbitrary_enum_discriminant
,
326 arbitrary_self_types
,
338 asm_experimental_arch
,
346 assert_receiver_is_total_eq
,
349 associated_const_equality
,
351 associated_type_bounds
,
352 associated_type_defaults
,
365 augmented_assignments
,
367 automatically_derived
,
369 avx512_target_feature
,
377 bind_by_move_pattern_guards
,
389 borrowck_graphviz_format
,
390 borrowck_graphviz_postflow
,
391 borrowck_graphviz_preflow
,
396 braced_empty_structs
,
408 capture_disjoint_fields
,
424 cfg_target_has_atomic
,
425 cfg_target_has_atomic_equal_alignment
,
426 cfg_target_has_atomic_load_store
,
427 cfg_target_thread_local
,
439 closure_to_fn_coercion
,
440 closure_track_caller
,
444 cmpxchg16b_target_feature
,
445 cmse_nonsecure_entry
,
452 compare_exchange_weak
,
462 conservative_impl_trait
,
466 const_compare_raw_pointers
,
471 const_eval_select_ct
,
472 const_evaluatable_checked
,
475 const_fn_floating_point_arithmetic
,
476 const_fn_fn_ptr_basics
,
477 const_fn_trait_bound
,
483 const_generic_defaults
,
485 const_generics_defaults
,
488 const_in_array_repeat_expressions
,
495 const_precise_live_drops
,
498 const_raw_ptr_to_usize_cast
,
501 const_trait_bound_opt_out
,
518 core_panic_2015_macro
,
529 crate_visibility_modifier
,
530 crt_dash_static
: "crt-static",
539 custom_inner_attributes
,
540 custom_test_frameworks
,
546 debug_assert_eq_macro
,
548 debug_assert_ne_macro
,
556 default_alloc_error_handler
,
557 default_lib_allocator
,
558 default_method_body_is_const
,
559 default_type_parameter_fallback
,
561 delay_span_bug_from_inside_query
,
570 destructuring_assignment
,
591 document_private_items
,
593 dotdot_in_tuple_patterns
,
594 dotdoteq_in_patterns
,
602 dropck_parametricity
,
613 emit_enum_variant_arg
,
625 ermsb_target_feature
,
629 exclusive_range_pattern
,
630 exhaustive_integer_patterns
,
639 explicit_generic_args_with_impl_trait
,
642 extended_key_value_attributes
,
643 extern_absolute_paths
,
644 extern_crate_item_prelude
,
669 field_init_shorthand
,
676 float_to_int_unchecked
,
709 from_size_align_unchecked
,
723 generic_associated_types
,
731 half_open_range_patterns
,
733 hexagon_target_feature
,
735 homogeneous_aggregate
,
752 if_while_or_patterns
,
754 impl_header_lifetime_elision
,
757 impl_trait_in_bindings
,
767 inclusive_range_syntax
,
770 infer_outlives_requirements
,
771 infer_static_outlives_requirements
,
772 inherent_associated_types
,
786 irrefutable_let_patterns
,
790 issue_5723_bootstrap
,
791 issue_tracker_base_url
,
805 lazy_normalization_consts
,
820 link_llvm_intrinsics
,
841 macro_at_most_once_rep
,
842 macro_attributes_in_derive_output
,
845 macro_lifetime_matcher
,
846 macro_literal_matcher
,
858 match_beginning_vert
,
859 match_default_bindings
,
889 min_type_alias_impl_trait
,
899 more_qualified_paths
,
901 movbe_target_feature
,
915 native_link_modifiers
,
916 native_link_modifiers_as_needed
,
917 native_link_modifiers_bundle
,
918 native_link_modifiers_verbatim
,
919 native_link_modifiers_whole_archive
,
957 non_exhaustive_omitted_patterns_lint
,
969 object_safe_for_dispatch
,
972 omit_gdb_pretty_printer_section
,
981 optin_builtin_traits
,
990 overlapping_marker_traits
,
1002 panic_implementation
,
1017 pattern_parentheses
,
1021 platform_intrinsics
,
1030 post_dash_lto
: "post-lto",
1031 powerpc_target_feature
,
1036 pre_dash_lto
: "pre-lto",
1037 precise_pointer_size_matching
,
1041 prefetch_read_instruction
,
1042 prefetch_write_data
,
1043 prefetch_write_instruction
,
1051 proc_dash_macro
: "proc-macro",
1053 proc_macro_attribute
,
1054 proc_macro_def_site
,
1059 proc_macro_internals
,
1061 proc_macro_non_items
,
1062 proc_macro_path_invoc
,
1077 quad_precision_float
,
1080 range_inclusive_new
,
1085 re_rebalance_coherence
,
1088 read_enum_variant_arg
,
1096 reexport_test_harness_main
,
1097 ref_unwind_safe_trait
,
1114 relaxed_struct_unsize
,
1125 reserved_r9
: "reserved-r9",
1131 riscv_target_feature
,
1147 rust_eh_catch_typeinfo
,
1148 rust_eh_personality
,
1149 rust_eh_register_frames
,
1150 rust_eh_unregister_frames
,
1154 rustc_allocator_nounwind
,
1155 rustc_allow_const_fn_unstable
,
1157 rustc_builtin_macro
,
1158 rustc_capture_analysis
,
1161 rustc_const_unstable
,
1162 rustc_conversion_suggestion
,
1165 rustc_diagnostic_item
,
1166 rustc_diagnostic_macros
,
1168 rustc_do_not_const_check
,
1170 rustc_dump_env_program_clauses
,
1171 rustc_dump_program_clauses
,
1172 rustc_dump_user_substs
,
1175 rustc_evaluate_where_clauses
,
1176 rustc_expected_cgu_reuse
,
1177 rustc_if_this_changed
,
1178 rustc_inherit_overflow_checks
,
1179 rustc_insignificant_dtor
,
1181 rustc_layout_scalar_valid_range_end
,
1182 rustc_layout_scalar_valid_range_start
,
1183 rustc_legacy_const_generics
,
1184 rustc_lint_query_instability
,
1185 rustc_macro_transparency
,
1188 rustc_must_implement_one_of
,
1189 rustc_nonnull_optimization_guaranteed
,
1190 rustc_object_lifetime_default
,
1191 rustc_on_unimplemented
,
1194 rustc_partition_codegened
,
1195 rustc_partition_reused
,
1196 rustc_pass_by_value
,
1198 rustc_peek_definite_init
,
1199 rustc_peek_liveness
,
1200 rustc_peek_maybe_init
,
1201 rustc_peek_maybe_uninit
,
1202 rustc_polymorphize_error
,
1204 rustc_proc_macro_decls
,
1207 rustc_reservation_impl
,
1209 rustc_skip_array_during_method_dispatch
,
1210 rustc_specialization_trait
,
1212 rustc_std_internal_symbol
,
1213 rustc_strict_coherence
,
1216 rustc_then_this_would_need
,
1217 rustc_trivial_field_reads
,
1218 rustc_unsafe_specialization_marker
,
1223 rvalue_static_promotion
,
1273 simd_reduce_add_ordered
,
1274 simd_reduce_add_unordered
,
1279 simd_reduce_max_nanless
,
1281 simd_reduce_min_nanless
,
1282 simd_reduce_mul_ordered
,
1283 simd_reduce_mul_unordered
,
1288 simd_saturating_add
,
1289 simd_saturating_sub
,
1292 simd_select_bitmask
,
1323 sse4a_target_feature
,
1335 std_panic_2015_macro
,
1338 stmt_expr_attributes
,
1339 stop_after_dataflow
,
1345 struct_field_attributes
,
1367 target_has_atomic_equal_alignment
,
1368 target_has_atomic_load_store
,
1370 target_pointer_width
,
1371 target_target_vendor
,
1372 target_thread_local
,
1378 termination_trait_test
,
1381 test_accepted_feature
,
1383 test_removed_feature
,
1390 thumb_mode
: "thumb-mode",
1415 type_alias_enum_variants
,
1416 type_alias_impl_trait
,
1418 type_changing_struct_update
,
1428 unaligned_volatile_load
,
1429 unaligned_volatile_store
,
1438 underscore_const_names
,
1440 underscore_lifetimes
,
1442 unimplemented_macro
,
1444 universal_impl_trait
,
1451 unreachable_2015_macro
,
1453 unreachable_2021_macro
,
1455 unreachable_display
,
1457 unrestricted_attribute_tokens
,
1458 unsafe_block_in_unsafe_fn
,
1460 unsafe_no_drop_flag
,
1461 unsafe_pin_internals
,
1465 unsized_tuple_coercion
,
1468 unused_qualifications
,
1494 visible_private_types
,
1496 volatile_copy_memory
,
1497 volatile_copy_nonoverlapping_memory
,
1499 volatile_set_memory
,
1506 wasm_target_feature
,
1511 with_negative_coherence
,
1528 #[derive(Copy, Clone, Eq, HashStable_Generic, Encodable, Decodable)]
1536 /// Constructs a new identifier from a symbol and a span.
1537 pub const fn new(name
: Symbol
, span
: Span
) -> Ident
{
1538 Ident { name, span }
1541 /// Constructs a new identifier with a dummy span.
1543 pub const fn with_dummy_span(name
: Symbol
) -> Ident
{
1544 Ident
::new(name
, DUMMY_SP
)
1548 pub fn empty() -> Ident
{
1549 Ident
::with_dummy_span(kw
::Empty
)
1552 /// Maps a string to an identifier with a dummy span.
1553 pub fn from_str(string
: &str) -> Ident
{
1554 Ident
::with_dummy_span(Symbol
::intern(string
))
1557 /// Maps a string and a span to an identifier.
1558 pub fn from_str_and_span(string
: &str, span
: Span
) -> Ident
{
1559 Ident
::new(Symbol
::intern(string
), span
)
1562 /// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
1563 pub fn with_span_pos(self, span
: Span
) -> Ident
{
1564 Ident
::new(self.name
, span
.with_ctxt(self.span
.ctxt()))
1567 pub fn without_first_quote(self) -> Ident
{
1568 Ident
::new(Symbol
::intern(self.as_str().trim_start_matches('
\''
)), self.span
)
1571 /// "Normalize" ident for use in comparisons using "item hygiene".
1572 /// Identifiers with same string value become same if they came from the same macro 2.0 macro
1573 /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
1574 /// different macro 2.0 macros.
1575 /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
1576 pub fn normalize_to_macros_2_0(self) -> Ident
{
1577 Ident
::new(self.name
, self.span
.normalize_to_macros_2_0())
1580 /// "Normalize" ident for use in comparisons using "local variable hygiene".
1581 /// Identifiers with same string value become same if they came from the same non-transparent
1582 /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
1583 /// non-transparent macros.
1584 /// Technically, this operation strips all transparent marks from ident's syntactic context.
1585 pub fn normalize_to_macro_rules(self) -> Ident
{
1586 Ident
::new(self.name
, self.span
.normalize_to_macro_rules())
1589 /// Access the underlying string. This is a slowish operation because it
1590 /// requires locking the symbol interner.
1592 /// Note that the lifetime of the return value is a lie. See
1593 /// `Symbol::as_str()` for details.
1594 pub fn as_str(&self) -> &str {
1599 impl PartialEq
for Ident
{
1600 fn eq(&self, rhs
: &Self) -> bool
{
1601 self.name
== rhs
.name
&& self.span
.ctxt() == rhs
.span
.ctxt()
1605 impl Hash
for Ident
{
1606 fn hash
<H
: Hasher
>(&self, state
: &mut H
) {
1607 self.name
.hash(state
);
1608 self.span
.ctxt().hash(state
);
1612 impl fmt
::Debug
for Ident
{
1613 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
1614 fmt
::Display
::fmt(self, f
)?
;
1615 fmt
::Debug
::fmt(&self.span
.ctxt(), f
)
1619 /// This implementation is supposed to be used in error messages, so it's expected to be identical
1620 /// to printing the original identifier token written in source code (`token_to_string`),
1621 /// except that AST identifiers don't keep the rawness flag, so we have to guess it.
1622 impl fmt
::Display
for Ident
{
1623 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
1624 fmt
::Display
::fmt(&IdentPrinter
::new(self.name
, self.is_raw_guess(), None
), f
)
1628 /// This is the most general way to print identifiers.
1629 /// AST pretty-printer is used as a fallback for turning AST structures into token streams for
1630 /// proc macros. Additionally, proc macros may stringify their input and expect it survive the
1631 /// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30).
1632 /// So we need to somehow pretty-print `$crate` in a way preserving at least some of its
1633 /// hygiene data, most importantly name of the crate it refers to.
1634 /// As a result we print `$crate` as `crate` if it refers to the local crate
1635 /// and as `::other_crate_name` if it refers to some other crate.
1636 /// Note, that this is only done if the ident token is printed from inside of AST pretty-pringing,
1637 /// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents,
1638 /// so we should not perform this lossy conversion if the top level call to the pretty-printer was
1639 /// done for a token stream or a single token.
1640 pub struct IdentPrinter
{
1643 /// Span used for retrieving the crate name to which `$crate` refers to,
1644 /// if this field is `None` then the `$crate` conversion doesn't happen.
1645 convert_dollar_crate
: Option
<Span
>,
1649 /// The most general `IdentPrinter` constructor. Do not use this.
1650 pub fn new(symbol
: Symbol
, is_raw
: bool
, convert_dollar_crate
: Option
<Span
>) -> IdentPrinter
{
1651 IdentPrinter { symbol, is_raw, convert_dollar_crate }
1654 /// This implementation is supposed to be used when printing identifiers
1655 /// as a part of pretty-printing for larger AST pieces.
1656 /// Do not use this either.
1657 pub fn for_ast_ident(ident
: Ident
, is_raw
: bool
) -> IdentPrinter
{
1658 IdentPrinter
::new(ident
.name
, is_raw
, Some(ident
.span
))
1662 impl fmt
::Display
for IdentPrinter
{
1663 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
1666 } else if self.symbol
== kw
::DollarCrate
{
1667 if let Some(span
) = self.convert_dollar_crate
{
1668 let converted
= span
.ctxt().dollar_crate_name();
1669 if !converted
.is_path_segment_keyword() {
1672 return fmt
::Display
::fmt(&converted
, f
);
1675 fmt
::Display
::fmt(&self.symbol
, f
)
1679 /// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
1681 // FIXME(matthewj, petrochenkov) Use this more often, add a similar
1682 // `ModernIdent` struct and use that as well.
1683 #[derive(Copy, Clone, Eq, PartialEq, Hash)]
1684 pub struct MacroRulesNormalizedIdent(Ident
);
1686 impl MacroRulesNormalizedIdent
{
1687 pub fn new(ident
: Ident
) -> Self {
1688 Self(ident
.normalize_to_macro_rules())
1692 impl fmt
::Debug
for MacroRulesNormalizedIdent
{
1693 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
1694 fmt
::Debug
::fmt(&self.0, f
)
1698 impl fmt
::Display
for MacroRulesNormalizedIdent
{
1699 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
1700 fmt
::Display
::fmt(&self.0, f
)
1704 /// An interned string.
1706 /// Internally, a `Symbol` is implemented as an index, and all operations
1707 /// (including hashing, equality, and ordering) operate on that index. The use
1708 /// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
1709 /// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
1711 /// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it
1712 /// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
1713 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1714 pub struct Symbol(SymbolIndex
);
1716 rustc_index
::newtype_index
! {
1717 struct SymbolIndex { .. }
1721 const fn new(n
: u32) -> Self {
1722 Symbol(SymbolIndex
::from_u32(n
))
1725 /// Maps a string to its interned representation.
1726 pub fn intern(string
: &str) -> Self {
1727 with_session_globals(|session_globals
| session_globals
.symbol_interner
.intern(string
))
1730 /// Access the underlying string. This is a slowish operation because it
1731 /// requires locking the symbol interner.
1733 /// Note that the lifetime of the return value is a lie. It's not the same
1734 /// as `&self`, but actually tied to the lifetime of the underlying
1735 /// interner. Interners are long-lived, and there are very few of them, and
1736 /// this function is typically used for short-lived things, so in practice
1737 /// it works out ok.
1738 pub fn as_str(&self) -> &str {
1739 with_session_globals(|session_globals
| unsafe {
1740 std
::mem
::transmute
::<&str, &str>(session_globals
.symbol_interner
.get(*self))
1744 pub fn as_u32(self) -> u32 {
1748 pub fn is_empty(self) -> bool
{
1752 /// This method is supposed to be used in error messages, so it's expected to be
1753 /// identical to printing the original identifier token written in source code
1754 /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag
1755 /// or edition, so we have to guess the rawness using the global edition.
1756 pub fn to_ident_string(self) -> String
{
1757 Ident
::with_dummy_span(self).to_string()
1761 impl fmt
::Debug
for Symbol
{
1762 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
1763 fmt
::Debug
::fmt(self.as_str(), f
)
1767 impl fmt
::Display
for Symbol
{
1768 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
1769 fmt
::Display
::fmt(self.as_str(), f
)
1773 impl<S
: Encoder
> Encodable
<S
> for Symbol
{
1774 fn encode(&self, s
: &mut S
) -> Result
<(), S
::Error
> {
1775 s
.emit_str(self.as_str())
1779 impl<D
: Decoder
> Decodable
<D
> for Symbol
{
1781 fn decode(d
: &mut D
) -> Symbol
{
1782 Symbol
::intern(&d
.read_str())
1786 impl<CTX
> HashStable
<CTX
> for Symbol
{
1788 fn hash_stable(&self, hcx
: &mut CTX
, hasher
: &mut StableHasher
) {
1789 self.as_str().hash_stable(hcx
, hasher
);
1793 impl<CTX
> ToStableHashKey
<CTX
> for Symbol
{
1794 type KeyType
= String
;
1796 fn to_stable_hash_key(&self, _
: &CTX
) -> String
{
1797 self.as_str().to_string()
1802 pub(crate) struct Interner(Lock
<InternerInner
>);
1804 // The `&'static str`s in this type actually point into the arena.
1806 // The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
1807 // found that to regress performance up to 2% in some cases. This might be
1808 // revisited after further improvements to `indexmap`.
1810 // This type is private to prevent accidentally constructing more than one
1811 // `Interner` on the same thread, which makes it easy to mixup `Symbol`s
1812 // between `Interner`s.
1814 struct InternerInner
{
1815 arena
: DroplessArena
,
1816 names
: FxHashMap
<&'
static str, Symbol
>,
1817 strings
: Vec
<&'
static str>,
1821 fn prefill(init
: &[&'
static str]) -> Self {
1822 Interner(Lock
::new(InternerInner
{
1823 strings
: init
.into(),
1824 names
: init
.iter().copied().zip((0..).map(Symbol
::new
)).collect(),
1825 ..Default
::default()
1830 fn intern(&self, string
: &str) -> Symbol
{
1831 let mut inner
= self.0.lock();
1832 if let Some(&name
) = inner
.names
.get(string
) {
1836 let name
= Symbol
::new(inner
.strings
.len() as u32);
1838 // SAFETY: we convert from `&str` to `&[u8]`, clone it into the arena,
1839 // and immediately convert the clone back to `&[u8], all because there
1840 // is no `inner.arena.alloc_str()` method. This is clearly safe.
1842 unsafe { str::from_utf8_unchecked(inner.arena.alloc_slice(string.as_bytes())) }
;
1844 // SAFETY: we can extend the arena allocation to `'static` because we
1845 // only access these while the arena is still alive.
1846 let string
: &'
static str = unsafe { &*(string as *const str) }
;
1847 inner
.strings
.push(string
);
1849 // This second hash table lookup can be avoided by using `RawEntryMut`,
1850 // but this code path isn't hot enough for it to be worth it. See
1851 // #91445 for details.
1852 inner
.names
.insert(string
, name
);
1856 // Get the symbol as a string. `Symbol::as_str()` should be used in
1857 // preference to this function.
1858 fn get(&self, symbol
: Symbol
) -> &str {
1859 self.0.lock().strings
[symbol
.0.as_usize()]
1863 // This module has a very short name because it's used a lot.
1864 /// This module contains all the defined keyword `Symbol`s.
1866 /// Given that `kw` is imported, use them like `kw::keyword_name`.
1867 /// For example `kw::Loop` or `kw::Break`.
1869 pub use super::kw_generated
::*;
1872 // This module has a very short name because it's used a lot.
1873 /// This module contains all the defined non-keyword `Symbol`s.
1875 /// Given that `sym` is imported, use them like `sym::symbol_name`.
1876 /// For example `sym::rustfmt` or `sym::u8`.
1879 use std
::convert
::TryInto
;
1882 pub use super::sym_generated
::*;
1884 // Used from a macro in `librustc_feature/accepted.rs`
1885 pub use super::kw
::MacroRules
as macro_rules
;
1887 /// Get the symbol for an integer.
1889 /// The first few non-negative integers each have a static symbol and therefore
1891 pub fn integer
<N
: TryInto
<usize> + Copy
+ ToString
>(n
: N
) -> Symbol
{
1892 if let Result
::Ok(idx
) = n
.try_into() {
1894 return Symbol
::new(super::SYMBOL_DIGITS_BASE
+ idx
as u32);
1897 Symbol
::intern(&n
.to_string())
1902 fn is_special(self) -> bool
{
1903 self <= kw
::Underscore
1906 fn is_used_keyword_always(self) -> bool
{
1907 self >= kw
::As
&& self <= kw
::While
1910 fn is_used_keyword_conditional(self, edition
: impl FnOnce() -> Edition
) -> bool
{
1911 (self >= kw
::Async
&& self <= kw
::Dyn
) && edition() >= Edition
::Edition2018
1914 fn is_unused_keyword_always(self) -> bool
{
1915 self >= kw
::Abstract
&& self <= kw
::Yield
1918 fn is_unused_keyword_conditional(self, edition
: impl FnOnce() -> Edition
) -> bool
{
1919 self == kw
::Try
&& edition() >= Edition
::Edition2018
1922 pub fn is_reserved(self, edition
: impl Copy
+ FnOnce() -> Edition
) -> bool
{
1924 || self.is_used_keyword_always()
1925 || self.is_unused_keyword_always()
1926 || self.is_used_keyword_conditional(edition
)
1927 || self.is_unused_keyword_conditional(edition
)
1930 /// A keyword or reserved identifier that can be used as a path segment.
1931 pub fn is_path_segment_keyword(self) -> bool
{
1933 || self == kw
::SelfLower
1934 || self == kw
::SelfUpper
1935 || self == kw
::Crate
1936 || self == kw
::PathRoot
1937 || self == kw
::DollarCrate
1940 /// Returns `true` if the symbol is `true` or `false`.
1941 pub fn is_bool_lit(self) -> bool
{
1942 self == kw
::True
|| self == kw
::False
1945 /// Returns `true` if this symbol can be a raw identifier.
1946 pub fn can_be_raw(self) -> bool
{
1947 self != kw
::Empty
&& self != kw
::Underscore
&& !self.is_path_segment_keyword()
1952 // Returns `true` for reserved identifiers used internally for elided lifetimes,
1953 // unnamed method parameters, crate root module, error recovery etc.
1954 pub fn is_special(self) -> bool
{
1955 self.name
.is_special()
1958 /// Returns `true` if the token is a keyword used in the language.
1959 pub fn is_used_keyword(self) -> bool
{
1960 // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1961 self.name
.is_used_keyword_always()
1962 || self.name
.is_used_keyword_conditional(|| self.span
.edition())
1965 /// Returns `true` if the token is a keyword reserved for possible future use.
1966 pub fn is_unused_keyword(self) -> bool
{
1967 // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1968 self.name
.is_unused_keyword_always()
1969 || self.name
.is_unused_keyword_conditional(|| self.span
.edition())
1972 /// Returns `true` if the token is either a special identifier or a keyword.
1973 pub fn is_reserved(self) -> bool
{
1974 // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
1975 self.name
.is_reserved(|| self.span
.edition())
1978 /// A keyword or reserved identifier that can be used as a path segment.
1979 pub fn is_path_segment_keyword(self) -> bool
{
1980 self.name
.is_path_segment_keyword()
1983 /// We see this identifier in a normal identifier position, like variable name or a type.
1984 /// How was it written originally? Did it use the raw form? Let's try to guess.
1985 pub fn is_raw_guess(self) -> bool
{
1986 self.name
.can_be_raw() && self.is_reserved()