2021-05-22 09:20:22 -05:00
|
|
|
//! See [`Name`].
|
2019-10-30 08:12:55 -05:00
|
|
|
|
|
|
|
use std::fmt;
|
|
|
|
|
2020-08-12 11:26:51 -05:00
|
|
|
use syntax::{ast, SmolStr};
|
2019-10-30 08:12:55 -05:00
|
|
|
|
|
|
|
/// `Name` is a wrapper around string, which is used in hir for both references
|
|
|
|
/// and declarations. In theory, names should also carry hygiene info, but we are
|
|
|
|
/// not there yet!
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
|
|
|
pub struct Name(Repr);
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
|
|
|
enum Repr {
|
|
|
|
Text(SmolStr),
|
|
|
|
TupleField(usize),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for Name {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match &self.0 {
|
|
|
|
Repr::Text(text) => fmt::Display::fmt(&text, f),
|
|
|
|
Repr::TupleField(idx) => fmt::Display::fmt(&idx, f),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Name {
|
|
|
|
/// Note: this is private to make creating name from random string hard.
|
|
|
|
/// Hopefully, this should allow us to integrate hygiene cleaner in the
|
|
|
|
/// future, and to switch to interned representation of names.
|
|
|
|
const fn new_text(text: SmolStr) -> Name {
|
|
|
|
Name(Repr::Text(text))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new_tuple_field(idx: usize) -> Name {
|
|
|
|
Name(Repr::TupleField(idx))
|
|
|
|
}
|
|
|
|
|
2020-12-15 12:23:51 -06:00
|
|
|
pub fn new_lifetime(lt: &ast::Lifetime) -> Name {
|
2021-01-19 16:56:11 -06:00
|
|
|
Self::new_text(lt.text().into())
|
2020-05-31 03:59:40 -05:00
|
|
|
}
|
|
|
|
|
2019-10-30 08:12:55 -05:00
|
|
|
/// Shortcut to create inline plain text name
|
2020-09-23 01:45:35 -05:00
|
|
|
const fn new_inline(text: &str) -> Name {
|
|
|
|
Name::new_text(SmolStr::new_inline(text))
|
2019-10-30 08:12:55 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Resolve a name from the text of token.
|
2021-01-19 16:56:11 -06:00
|
|
|
fn resolve(raw_text: &str) -> Name {
|
2021-03-21 06:38:21 -05:00
|
|
|
if let Some(text) = raw_text.strip_prefix("r#") {
|
|
|
|
Name::new_text(SmolStr::new(text))
|
2019-10-30 08:12:55 -05:00
|
|
|
} else {
|
2021-01-19 16:56:11 -06:00
|
|
|
Name::new_text(raw_text.into())
|
2019-10-30 08:12:55 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-31 05:24:08 -05:00
|
|
|
/// A fake name for things missing in the source code.
|
|
|
|
///
|
|
|
|
/// For example, `impl Foo for {}` should be treated as a trait impl for a
|
|
|
|
/// type with a missing name. Similarly, `struct S { : u32 }` should have a
|
|
|
|
/// single field with a missing name.
|
|
|
|
///
|
|
|
|
/// Ideally, we want a `gensym` semantics for missing names -- each missing
|
|
|
|
/// name is equal only to itself. It's not clear how to implement this in
|
|
|
|
/// salsa though, so we punt on that bit for a moment.
|
2019-10-30 08:12:55 -05:00
|
|
|
pub fn missing() -> Name {
|
|
|
|
Name::new_text("[missing name]".into())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn as_tuple_index(&self) -> Option<usize> {
|
|
|
|
match self.0 {
|
|
|
|
Repr::TupleField(idx) => Some(idx),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait AsName {
|
|
|
|
fn as_name(&self) -> Name;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AsName for ast::NameRef {
|
|
|
|
fn as_name(&self) -> Name {
|
|
|
|
match self.as_tuple_field() {
|
|
|
|
Some(idx) => Name::new_tuple_field(idx),
|
2021-03-26 12:30:59 -05:00
|
|
|
None => Name::resolve(&self.text()),
|
2019-10-30 08:12:55 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AsName for ast::Name {
|
|
|
|
fn as_name(&self) -> Name {
|
2021-03-26 12:30:59 -05:00
|
|
|
Name::resolve(&self.text())
|
2019-10-30 08:12:55 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-17 08:00:44 -06:00
|
|
|
impl AsName for ast::NameOrNameRef {
|
2020-04-11 16:33:17 -05:00
|
|
|
fn as_name(&self) -> Name {
|
|
|
|
match self {
|
2021-02-17 08:00:44 -06:00
|
|
|
ast::NameOrNameRef::Name(it) => it.as_name(),
|
|
|
|
ast::NameOrNameRef::NameRef(it) => it.as_name(),
|
2020-04-11 16:33:17 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-05 08:10:33 -06:00
|
|
|
impl AsName for tt::Ident {
|
|
|
|
fn as_name(&self) -> Name {
|
|
|
|
Name::resolve(&self.text)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-30 08:12:55 -05:00
|
|
|
impl AsName for ast::FieldKind {
|
|
|
|
fn as_name(&self) -> Name {
|
|
|
|
match self {
|
|
|
|
ast::FieldKind::Name(nr) => nr.as_name(),
|
2020-01-07 07:49:42 -06:00
|
|
|
ast::FieldKind::Index(idx) => {
|
|
|
|
let idx = idx.text().parse::<usize>().unwrap_or(0);
|
|
|
|
Name::new_tuple_field(idx)
|
|
|
|
}
|
2019-10-30 08:12:55 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-13 09:25:38 -05:00
|
|
|
impl AsName for base_db::Dependency {
|
2019-10-30 08:12:55 -05:00
|
|
|
fn as_name(&self) -> Name {
|
2020-07-01 02:53:53 -05:00
|
|
|
Name::new_text(SmolStr::new(&*self.name))
|
2019-10-30 08:12:55 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-13 14:43:53 -06:00
|
|
|
pub mod known {
|
|
|
|
macro_rules! known_names {
|
|
|
|
($($ident:ident),* $(,)?) => {
|
|
|
|
$(
|
|
|
|
#[allow(bad_style)]
|
|
|
|
pub const $ident: super::Name =
|
2020-09-23 01:45:35 -05:00
|
|
|
super::Name::new_inline(stringify!($ident));
|
2019-12-13 14:43:53 -06:00
|
|
|
)*
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
known_names!(
|
|
|
|
// Primitives
|
|
|
|
isize,
|
|
|
|
i8,
|
|
|
|
i16,
|
|
|
|
i32,
|
|
|
|
i64,
|
|
|
|
i128,
|
|
|
|
usize,
|
|
|
|
u8,
|
|
|
|
u16,
|
|
|
|
u32,
|
|
|
|
u64,
|
|
|
|
u128,
|
|
|
|
f32,
|
|
|
|
f64,
|
|
|
|
bool,
|
|
|
|
char,
|
|
|
|
str,
|
|
|
|
// Special names
|
|
|
|
macro_rules,
|
2020-05-30 13:21:06 -05:00
|
|
|
doc,
|
2021-03-10 12:43:03 -06:00
|
|
|
cfg,
|
2020-12-18 11:58:42 -06:00
|
|
|
cfg_attr,
|
2021-05-20 13:40:02 -05:00
|
|
|
register_attr,
|
|
|
|
register_tool,
|
2019-12-13 14:43:53 -06:00
|
|
|
// Components of known path (value or mod name)
|
|
|
|
std,
|
2020-01-27 16:09:56 -06:00
|
|
|
core,
|
|
|
|
alloc,
|
2019-12-13 14:43:53 -06:00
|
|
|
iter,
|
|
|
|
ops,
|
|
|
|
future,
|
|
|
|
result,
|
|
|
|
boxed,
|
2020-12-30 11:23:00 -06:00
|
|
|
option,
|
2021-06-01 06:39:19 -05:00
|
|
|
prelude,
|
|
|
|
rust_2015,
|
|
|
|
rust_2018,
|
|
|
|
rust_2021,
|
2021-06-01 12:03:00 -05:00
|
|
|
v1,
|
2019-12-13 14:43:53 -06:00
|
|
|
// Components of known path (type name)
|
2020-10-06 12:07:34 -05:00
|
|
|
Iterator,
|
2019-12-13 14:43:53 -06:00
|
|
|
IntoIterator,
|
|
|
|
Item,
|
|
|
|
Try,
|
|
|
|
Ok,
|
|
|
|
Future,
|
|
|
|
Result,
|
2020-12-30 11:23:00 -06:00
|
|
|
Option,
|
2019-12-13 14:43:53 -06:00
|
|
|
Output,
|
|
|
|
Target,
|
|
|
|
Box,
|
|
|
|
RangeFrom,
|
|
|
|
RangeFull,
|
|
|
|
RangeInclusive,
|
|
|
|
RangeToInclusive,
|
|
|
|
RangeTo,
|
|
|
|
Range,
|
|
|
|
Neg,
|
|
|
|
Not,
|
2019-12-18 22:45:07 -06:00
|
|
|
Index,
|
2021-01-01 15:11:08 -06:00
|
|
|
// Components of known path (function name)
|
|
|
|
filter_map,
|
|
|
|
next,
|
2021-02-24 13:23:12 -06:00
|
|
|
iter_mut,
|
2021-03-15 12:18:50 -05:00
|
|
|
len,
|
|
|
|
is_empty,
|
2019-12-13 14:43:53 -06:00
|
|
|
// Builtin macros
|
|
|
|
file,
|
|
|
|
column,
|
|
|
|
compile_error,
|
|
|
|
line,
|
2020-12-14 09:38:53 -06:00
|
|
|
module_path,
|
2020-03-11 10:08:12 -05:00
|
|
|
assert,
|
2021-04-02 20:12:55 -05:00
|
|
|
core_panic,
|
|
|
|
std_panic,
|
2019-12-13 14:43:53 -06:00
|
|
|
stringify,
|
2020-03-02 00:05:15 -06:00
|
|
|
concat,
|
2021-05-13 17:42:10 -05:00
|
|
|
concat_idents,
|
2020-03-06 08:58:45 -06:00
|
|
|
include,
|
2020-06-27 13:02:47 -05:00
|
|
|
include_bytes,
|
2020-06-27 07:31:19 -05:00
|
|
|
include_str,
|
2019-12-13 14:43:53 -06:00
|
|
|
format_args,
|
|
|
|
format_args_nl,
|
2019-12-21 06:33:44 -06:00
|
|
|
env,
|
|
|
|
option_env,
|
2020-12-15 03:05:20 -06:00
|
|
|
llvm_asm,
|
|
|
|
asm,
|
2021-04-18 11:43:45 -05:00
|
|
|
global_asm,
|
2019-12-13 14:43:53 -06:00
|
|
|
// Builtin derives
|
|
|
|
Copy,
|
|
|
|
Clone,
|
|
|
|
Default,
|
|
|
|
Debug,
|
|
|
|
Hash,
|
|
|
|
Ord,
|
|
|
|
PartialOrd,
|
|
|
|
Eq,
|
|
|
|
PartialEq,
|
2021-06-09 11:02:31 -05:00
|
|
|
// Builtin attributes
|
|
|
|
bench,
|
|
|
|
cfg_accessible,
|
|
|
|
cfg_eval,
|
|
|
|
derive,
|
|
|
|
global_allocator,
|
|
|
|
test,
|
|
|
|
test_case,
|
2020-10-21 14:51:53 -05:00
|
|
|
// Safe intrinsics
|
2020-10-21 02:06:05 -05:00
|
|
|
abort,
|
|
|
|
size_of,
|
|
|
|
min_align_of,
|
|
|
|
needs_drop,
|
|
|
|
caller_location,
|
|
|
|
size_of_val,
|
|
|
|
min_align_of_val,
|
|
|
|
add_with_overflow,
|
|
|
|
sub_with_overflow,
|
|
|
|
mul_with_overflow,
|
|
|
|
wrapping_add,
|
|
|
|
wrapping_sub,
|
|
|
|
wrapping_mul,
|
|
|
|
saturating_add,
|
|
|
|
saturating_sub,
|
|
|
|
rotate_left,
|
|
|
|
rotate_right,
|
|
|
|
ctpop,
|
|
|
|
ctlz,
|
|
|
|
cttz,
|
|
|
|
bswap,
|
|
|
|
bitreverse,
|
|
|
|
discriminant_value,
|
|
|
|
type_id,
|
|
|
|
likely,
|
|
|
|
unlikely,
|
|
|
|
ptr_guaranteed_eq,
|
|
|
|
ptr_guaranteed_ne,
|
|
|
|
minnumf32,
|
|
|
|
minnumf64,
|
|
|
|
maxnumf32,
|
|
|
|
rustc_peek,
|
|
|
|
maxnumf64,
|
|
|
|
type_name,
|
|
|
|
variant_count,
|
2019-12-13 14:43:53 -06:00
|
|
|
);
|
|
|
|
|
|
|
|
// self/Self cannot be used as an identifier
|
2020-09-23 01:45:35 -05:00
|
|
|
pub const SELF_PARAM: super::Name = super::Name::new_inline("self");
|
|
|
|
pub const SELF_TYPE: super::Name = super::Name::new_inline("Self");
|
2019-12-13 14:43:53 -06:00
|
|
|
|
2020-12-11 06:49:32 -06:00
|
|
|
pub const STATIC_LIFETIME: super::Name = super::Name::new_inline("'static");
|
|
|
|
|
2019-12-13 14:43:53 -06:00
|
|
|
#[macro_export]
|
2019-12-13 15:01:06 -06:00
|
|
|
macro_rules! name {
|
2019-12-13 14:43:53 -06:00
|
|
|
(self) => {
|
|
|
|
$crate::name::known::SELF_PARAM
|
|
|
|
};
|
|
|
|
(Self) => {
|
|
|
|
$crate::name::known::SELF_TYPE
|
|
|
|
};
|
2020-12-11 06:49:32 -06:00
|
|
|
('static) => {
|
|
|
|
$crate::name::known::STATIC_LIFETIME
|
|
|
|
};
|
2019-12-13 14:43:53 -06:00
|
|
|
($ident:ident) => {
|
|
|
|
$crate::name::known::$ident
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-13 15:01:06 -06:00
|
|
|
pub use crate::name;
|