use rustc_macros::symbols;
use serialize::{Decodable, Decoder, Encodable, Encoder};
-use std::fmt;
-use std::str;
use std::cmp::{PartialEq, Ordering, PartialOrd, Ord};
+use std::fmt;
use std::hash::{Hash, Hasher};
+use std::str;
use crate::hygiene::SyntaxContext;
use crate::{Span, DUMMY_SP, GLOBALS};
// Symbols that can be referred to with syntax_pos::sym::*. The symbol is
// the stringified identifier unless otherwise specified (e.g.
// `proc_dash_macro` represents "proc-macro").
+ //
+ // As well as the symbols listed, there are symbols for the the strings
+ // "0", "1", ..., "9", which are accessible via `sym::integer`.
Symbols {
aarch64_target_feature,
abi,
allow_internal_unstable,
allow_internal_unstable_backcompat_hack,
always,
+ and,
any,
arbitrary_self_types,
+ Arguments,
+ ArgumentV1,
arm_target_feature,
asm,
associated_consts,
automatically_derived,
avx512_target_feature,
await_macro,
+ begin_panic,
+ bench,
bin,
bind_by_move_pattern_guards,
block,
cfg_target_thread_local,
cfg_target_vendor,
clone,
+ Clone,
clone_closures,
clone_from,
closure_to_fn_coercion,
+ cmp,
cmpxchg16b_target_feature,
cold,
compile_error,
const_raw_ptr_to_usize_cast,
const_transmute,
contents,
+ context,
convert,
copy_closures,
core,
custom_test_frameworks,
c_variadic,
decl_macro,
+ Default,
default_lib_allocator,
default_type_parameter_fallback,
default_type_params,
deny,
deprecated,
+ deref,
+ deref_mut,
derive,
doc,
doc_alias,
enable,
err,
Err,
+ Equal,
except,
exclusive_range_pattern,
exhaustive_integer_patterns,
existential_type,
expected,
export_name,
+ expr,
extern_absolute_paths,
external_doc,
extern_crate_item_prelude,
extern_prelude,
extern_types,
f16c_target_feature,
+ f32,
+ f64,
feature,
ffi_returns_twice,
+ field,
field_init_shorthand,
file,
+ fmt,
+ fmt_internals,
fn_must_use,
forbid,
format_args_nl,
from_error,
from_generator,
from_ok,
+ from_usize,
fundamental,
future,
Future,
+ FxHashSet,
+ FxHashMap,
gen_future,
generators,
generic_associated_types,
global_allocator,
global_asm,
globs,
+ hash,
+ Hash,
+ HashSet,
+ HashMap,
hexagon_target_feature,
hidden,
homogeneous_aggregate,
impl_header_lifetime_elision,
impl_trait_in_bindings,
import_shadowing,
+ index,
+ index_mut,
in_band_lifetimes,
include,
inclusive_range_syntax,
issue,
issue_5723_bootstrap,
issue_tracker_base_url,
+ item,
item_like_imports,
iter,
Iterator,
lang,
lang_items,
lib,
+ lifetime,
link,
linkage,
link_args,
link_name,
link_section,
lint_reasons,
+ literal,
local_inner_macros,
log_syntax,
loop_break_value,
negate_unsigned,
never,
never_type,
+ new,
next,
__next,
nll,
option,
Option,
opt_out_copy,
+ or,
+ Ord,
+ Ordering,
Output,
overlapping_marker_traits,
packed,
+ panic,
panic_handler,
panic_impl,
panic_implementation,
panic_runtime,
+ partial_cmp,
+ PartialOrd,
passes,
+ pat,
path,
pattern_parentheses,
Pending,
proc_dash_macro: "proc-macro",
proc_macro,
proc_macro_attribute,
+ proc_macro_def_site,
proc_macro_derive,
proc_macro_expr,
proc_macro_gen,
Result,
Return,
rlib,
+ rt,
rtm_target_feature,
rust,
rust_2015_preview,
rust_2018_preview,
rust_begin_unwind,
+ rustc,
rustc_allocator_nounwind,
rustc_allow_const_fn_ptr,
rustc_args_required_const,
rustc_layout_scalar_valid_range_end,
rustc_layout_scalar_valid_range_start,
rustc_mir,
+ rustc_nonnull_optimization_guaranteed,
rustc_object_lifetime_default,
rustc_on_unimplemented,
rustc_outlives,
static_recursion,
std,
str,
+ stmt,
stmt_expr_attributes,
stop_after_dataflow,
struct_field_attributes,
struct_inherit,
structural_match,
struct_variant,
+ sty,
suggestion,
target_feature,
target_has_atomic,
test,
test_2018_feature,
test_accepted_feature,
+ test_case,
test_removed_feature,
test_runner,
+ then_with,
thread_local,
tool_attributes,
tool_lints,
Try,
try_blocks,
try_trait,
+ tt,
tuple_indexing,
+ Ty,
ty,
+ TyCtxt,
+ TyKind,
type_alias_enum_variants,
type_ascription,
type_length_limit,
untagged_unions,
unwind,
unwind_attributes,
+ unwrap_or,
used,
use_extern_macros,
use_nested_groups,
usize,
v1,
val,
+ vec,
+ Vec,
vis,
visible_private_types,
volatile,
Ident::new(name, DUMMY_SP)
}
+ #[inline]
+ pub fn invalid() -> Ident {
+ Ident::with_empty_ctxt(kw::Invalid)
+ }
+
/// Maps an interned string to an identifier with an empty syntax context.
pub fn from_interned_str(string: InternedString) -> Ident {
Ident::with_empty_ctxt(string.as_symbol())
/// Transforms an underscore identifier into one with the same name, but
/// gensymed. Leaves non-underscore identifiers unchanged.
pub fn gensym_if_underscore(self) -> Ident {
- if self.name == keywords::Underscore.name() { self.gensym() } else { self }
+ if self.name == kw::Underscore { self.gensym() } else { self }
}
// WARNING: this function is deprecated and will be removed in the future.
}
impl Interner {
- fn prefill(init: &[&str]) -> Self {
- let mut this = Interner::default();
- this.names.reserve(init.len());
- this.strings.reserve(init.len());
-
- // We can't allocate empty strings in the arena, so handle this here.
- assert!(keywords::Invalid.name().as_u32() == 0 && init[0].is_empty());
- this.names.insert("", keywords::Invalid.name());
- this.strings.push("");
-
- for string in &init[1..] {
- this.intern(string);
+ fn prefill(init: &[&'static str]) -> Self {
+ let symbols = (0 .. init.len() as u32).map(Symbol::new);
+ Interner {
+ strings: init.to_vec(),
+ names: init.iter().copied().zip(symbols).collect(),
+ ..Default::default()
}
- this
}
pub fn intern(&mut self, string: &str) -> Symbol {
}
}
-pub mod keywords {
- use super::{Symbol, Ident};
-
- #[derive(Clone, Copy, PartialEq, Eq)]
- pub struct Keyword {
- ident: Ident,
- }
-
- impl Keyword {
- #[inline]
- pub fn ident(self) -> Ident {
- self.ident
- }
-
- #[inline]
- pub fn name(self) -> Symbol {
- self.ident.name
- }
- }
-
+// This module has a very short name because it's used a lot.
+pub mod kw {
+ use super::Symbol;
keywords!();
}
// This module has a very short name because it's used a lot.
pub mod sym {
+ use std::convert::TryInto;
use super::Symbol;
+
symbols!();
+
+ // Get the symbol for an integer. The first few non-negative integers each
+ // have a static symbol and therefore are fast.
+ pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {
+ if let Result::Ok(idx) = n.try_into() {
+ if let Option::Some(&sym) = digits_array.get(idx) {
+ return sym;
+ }
+ }
+ Symbol::intern(&n.to_string())
+ }
}
impl Symbol {
fn is_used_keyword_2018(self) -> bool {
- self == keywords::Dyn.name()
+ self == kw::Dyn
}
fn is_unused_keyword_2018(self) -> bool {
- self >= keywords::Async.name() && self <= keywords::Try.name()
+ self >= kw::Async && self <= kw::Try
+ }
+
+ /// Used for sanity checking rustdoc keyword sections.
+ pub fn is_doc_keyword(self) -> bool {
+ self <= kw::Union
}
}
// Returns `true` for reserved identifiers used internally for elided lifetimes,
// unnamed method parameters, crate root module, error recovery etc.
pub fn is_special(self) -> bool {
- self.name <= keywords::Underscore.name()
+ self.name <= kw::Underscore
}
/// Returns `true` if the token is a keyword used in the language.
pub fn is_used_keyword(self) -> bool {
// Note: `span.edition()` is relatively expensive, don't call it unless necessary.
- self.name >= keywords::As.name() && self.name <= keywords::While.name() ||
+ self.name >= kw::As && self.name <= kw::While ||
self.name.is_used_keyword_2018() && self.span.rust_2018()
}
/// Returns `true` if the token is a keyword reserved for possible future use.
pub fn is_unused_keyword(self) -> bool {
// Note: `span.edition()` is relatively expensive, don't call it unless necessary.
- self.name >= keywords::Abstract.name() && self.name <= keywords::Yield.name() ||
+ self.name >= kw::Abstract && self.name <= kw::Yield ||
self.name.is_unused_keyword_2018() && self.span.rust_2018()
}
/// A keyword or reserved identifier that can be used as a path segment.
pub fn is_path_segment_keyword(self) -> bool {
- self.name == keywords::Super.name() ||
- self.name == keywords::SelfLower.name() ||
- self.name == keywords::SelfUpper.name() ||
- self.name == keywords::Crate.name() ||
- self.name == keywords::PathRoot.name() ||
- self.name == keywords::DollarCrate.name()
+ self.name == kw::Super ||
+ self.name == kw::SelfLower ||
+ self.name == kw::SelfUpper ||
+ self.name == kw::Crate ||
+ self.name == kw::PathRoot ||
+ self.name == kw::DollarCrate
}
/// This identifier can be a raw identifier.
pub fn can_be_raw(self) -> bool {
- self.name != keywords::Invalid.name() && self.name != keywords::Underscore.name() &&
+ self.name != kw::Invalid && self.name != kw::Underscore &&
!self.is_path_segment_keyword()
}
fn without_first_quote_test() {
GLOBALS.set(&Globals::new(edition::DEFAULT_EDITION), || {
let i = Ident::from_str("'break");
- assert_eq!(i.without_first_quote().name, keywords::Break.name());
+ assert_eq!(i.without_first_quote().name, kw::Break);
});
}
}