Use Symbol in Name

This commit is contained in:
Lukas Wirth 2024-07-12 15:57:54 +02:00
parent 843806b79f
commit 3fe815b0f3
75 changed files with 750 additions and 755 deletions

View file

@ -9,6 +9,7 @@ use hir_expand::{
attrs::{collect_attrs, Attr, AttrId, RawAttrs},
HirFileId, InFile,
};
use intern::sym;
use la_arena::{ArenaMap, Idx, RawIdx};
use mbe::DelimiterKind;
use syntax::{
@ -199,8 +200,8 @@ impl Attrs {
.segments()
.iter()
.rev()
.zip(["core", "prelude", "v1", "test"].iter().rev())
.all(|it| it.0.as_str() == Some(it.1))
.zip([sym::core, sym::prelude, sym::v1, sym::test].iter().rev())
.all(|it| it.0 == it.1)
})
}
@ -568,6 +569,10 @@ impl<'attr> AttrQuery<'attr> {
self.attrs().find_map(|attr| attr.string_value())
}
pub fn string_value_with_span(self) -> Option<(&'attr str, span::Span)> {
self.attrs().find_map(|attr| attr.string_value_with_span())
}
pub fn string_value_unescape(self) -> Option<Cow<'attr, str>> {
self.attrs().find_map(|attr| attr.string_value_unescape())
}

View file

@ -5,10 +5,10 @@ use std::mem;
use base_db::CrateId;
use hir_expand::{
name::{name, AsName, Name},
name::{AsName, Name},
ExpandError, InFile,
};
use intern::Interned;
use intern::{sym, Interned};
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
use span::AstIdMap;
@ -187,8 +187,10 @@ impl ExprCollector<'_> {
{
let is_mutable =
self_param.mut_token().is_some() && self_param.amp_token().is_none();
let binding_id: la_arena::Idx<Binding> =
self.alloc_binding(name![self], BindingAnnotation::new(is_mutable, false));
let binding_id: la_arena::Idx<Binding> = self.alloc_binding(
Name::new_symbol_root(sym::self_),
BindingAnnotation::new(is_mutable, false),
);
self.body.self_param = Some(binding_id);
self.source_map.self_param = Some(self.expander.in_file(AstPtr::new(&self_param)));
}
@ -1588,18 +1590,22 @@ impl ExprCollector<'_> {
});
let mut mappings = vec![];
let fmt = match template.and_then(|it| self.expand_macros_to_string(it)) {
Some((s, is_direct_literal)) => format_args::parse(
&s,
fmt_snippet,
args,
is_direct_literal,
|name| self.alloc_expr_desugared(Expr::Path(Path::from(name))),
|name, span| {
if let Some(span) = span {
mappings.push((span, name))
}
},
),
Some((s, is_direct_literal)) => {
let call_ctx = self.expander.syntax_context();
format_args::parse(
&s,
fmt_snippet,
args,
is_direct_literal,
|name| self.alloc_expr_desugared(Expr::Path(Path::from(name))),
|name, span| {
if let Some(span) = span {
mappings.push((span, name))
}
},
call_ctx,
)
}
None => FormatArgs {
template: Default::default(),
arguments: args.finish(),
@ -1723,14 +1729,18 @@ impl ExprCollector<'_> {
// unsafe { ::core::fmt::UnsafeArg::new() }
// )
let Some(new_v1_formatted) =
LangItem::FormatArguments.ty_rel_path(self.db, self.krate, name![new_v1_formatted])
else {
let Some(new_v1_formatted) = LangItem::FormatArguments.ty_rel_path(
self.db,
self.krate,
Name::new_symbol_root(sym::new_v1_formatted),
) else {
return self.missing_expr();
};
let Some(unsafe_arg_new) =
LangItem::FormatUnsafeArg.ty_rel_path(self.db, self.krate, name![new])
else {
let Some(unsafe_arg_new) = LangItem::FormatUnsafeArg.ty_rel_path(
self.db,
self.krate,
Name::new_symbol_root(sym::new),
) else {
return self.missing_expr();
};
let new_v1_formatted = self.alloc_expr_desugared(Expr::Path(new_v1_formatted));
@ -1812,10 +1822,10 @@ impl ExprCollector<'_> {
self.db,
self.krate,
match alignment {
Some(FormatAlignment::Left) => name![Left],
Some(FormatAlignment::Right) => name![Right],
Some(FormatAlignment::Center) => name![Center],
None => name![Unknown],
Some(FormatAlignment::Left) => Name::new_symbol_root(sym::Left),
Some(FormatAlignment::Right) => Name::new_symbol_root(sym::Right),
Some(FormatAlignment::Center) => Name::new_symbol_root(sym::Center),
None => Name::new_symbol_root(sym::Unknown),
},
);
match align {
@ -1838,8 +1848,11 @@ impl ExprCollector<'_> {
let width = self.make_count(width, argmap);
let format_placeholder_new = {
let format_placeholder_new =
LangItem::FormatPlaceholder.ty_rel_path(self.db, self.krate, name![new]);
let format_placeholder_new = LangItem::FormatPlaceholder.ty_rel_path(
self.db,
self.krate,
Name::new_symbol_root(sym::new),
);
match format_placeholder_new {
Some(path) => self.alloc_expr_desugared(Expr::Path(path)),
None => self.missing_expr(),
@ -1883,11 +1896,14 @@ impl ExprCollector<'_> {
*n as u128,
Some(BuiltinUint::Usize),
)));
let count_is =
match LangItem::FormatCount.ty_rel_path(self.db, self.krate, name![Is]) {
Some(count_is) => self.alloc_expr_desugared(Expr::Path(count_is)),
None => self.missing_expr(),
};
let count_is = match LangItem::FormatCount.ty_rel_path(
self.db,
self.krate,
Name::new_symbol_root(sym::Is),
) {
Some(count_is) => self.alloc_expr_desugared(Expr::Path(count_is)),
None => self.missing_expr(),
};
self.alloc_expr_desugared(Expr::Call {
callee: count_is,
args: Box::new([args]),
@ -1905,7 +1921,7 @@ impl ExprCollector<'_> {
let count_param = match LangItem::FormatCount.ty_rel_path(
self.db,
self.krate,
name![Param],
Name::new_symbol_root(sym::Param),
) {
Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)),
None => self.missing_expr(),
@ -1921,7 +1937,11 @@ impl ExprCollector<'_> {
self.missing_expr()
}
}
None => match LangItem::FormatCount.ty_rel_path(self.db, self.krate, name![Implied]) {
None => match LangItem::FormatCount.ty_rel_path(
self.db,
self.krate,
Name::new_symbol_root(sym::Implied),
) {
Some(count_param) => self.alloc_expr_desugared(Expr::Path(count_param)),
None => self.missing_expr(),
},
@ -1942,18 +1962,18 @@ impl ExprCollector<'_> {
let new_fn = match LangItem::FormatArgument.ty_rel_path(
self.db,
self.krate,
match ty {
Format(Display) => name![new_display],
Format(Debug) => name![new_debug],
Format(LowerExp) => name![new_lower_exp],
Format(UpperExp) => name![new_upper_exp],
Format(Octal) => name![new_octal],
Format(Pointer) => name![new_pointer],
Format(Binary) => name![new_binary],
Format(LowerHex) => name![new_lower_hex],
Format(UpperHex) => name![new_upper_hex],
Usize => name![from_usize],
},
Name::new_symbol_root(match ty {
Format(Display) => sym::new_display,
Format(Debug) => sym::new_debug,
Format(LowerExp) => sym::new_lower_exp,
Format(UpperExp) => sym::new_upper_exp,
Format(Octal) => sym::new_octal,
Format(Pointer) => sym::new_pointer,
Format(Binary) => sym::new_binary,
Format(LowerHex) => sym::new_lower_hex,
Format(UpperHex) => sym::new_upper_hex,
Usize => sym::from_usize,
}),
) {
Some(new_fn) => self.alloc_expr_desugared(Expr::Path(new_fn)),
None => self.missing_expr(),

View file

@ -5,7 +5,8 @@
use std::fmt;
use hir_expand::name::{name, AsName, Name};
use hir_expand::name::{AsName, Name};
use intern::sym;
/// Different signed int types.
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum BuiltinInt {
@ -49,28 +50,28 @@ pub enum BuiltinType {
impl BuiltinType {
#[rustfmt::skip]
pub const ALL: &'static [(Name, BuiltinType)] = &[
(name![char], BuiltinType::Char),
(name![bool], BuiltinType::Bool),
(name![str], BuiltinType::Str),
(Name::new_symbol_root(sym::char), BuiltinType::Char),
(Name::new_symbol_root(sym::bool), BuiltinType::Bool),
(Name::new_symbol_root(sym::str), BuiltinType::Str),
(name![isize], BuiltinType::Int(BuiltinInt::Isize)),
(name![i8], BuiltinType::Int(BuiltinInt::I8)),
(name![i16], BuiltinType::Int(BuiltinInt::I16)),
(name![i32], BuiltinType::Int(BuiltinInt::I32)),
(name![i64], BuiltinType::Int(BuiltinInt::I64)),
(name![i128], BuiltinType::Int(BuiltinInt::I128)),
(Name::new_symbol_root(sym::isize), BuiltinType::Int(BuiltinInt::Isize)),
(Name::new_symbol_root(sym::i8), BuiltinType::Int(BuiltinInt::I8)),
(Name::new_symbol_root(sym::i16), BuiltinType::Int(BuiltinInt::I16)),
(Name::new_symbol_root(sym::i32), BuiltinType::Int(BuiltinInt::I32)),
(Name::new_symbol_root(sym::i64), BuiltinType::Int(BuiltinInt::I64)),
(Name::new_symbol_root(sym::i128), BuiltinType::Int(BuiltinInt::I128)),
(name![usize], BuiltinType::Uint(BuiltinUint::Usize)),
(name![u8], BuiltinType::Uint(BuiltinUint::U8)),
(name![u16], BuiltinType::Uint(BuiltinUint::U16)),
(name![u32], BuiltinType::Uint(BuiltinUint::U32)),
(name![u64], BuiltinType::Uint(BuiltinUint::U64)),
(name![u128], BuiltinType::Uint(BuiltinUint::U128)),
(Name::new_symbol_root(sym::usize), BuiltinType::Uint(BuiltinUint::Usize)),
(Name::new_symbol_root(sym::u8), BuiltinType::Uint(BuiltinUint::U8)),
(Name::new_symbol_root(sym::u16), BuiltinType::Uint(BuiltinUint::U16)),
(Name::new_symbol_root(sym::u32), BuiltinType::Uint(BuiltinUint::U32)),
(Name::new_symbol_root(sym::u64), BuiltinType::Uint(BuiltinUint::U64)),
(Name::new_symbol_root(sym::u128), BuiltinType::Uint(BuiltinUint::U128)),
(name![f16], BuiltinType::Float(BuiltinFloat::F16)),
(name![f32], BuiltinType::Float(BuiltinFloat::F32)),
(name![f64], BuiltinType::Float(BuiltinFloat::F64)),
(name![f128], BuiltinType::Float(BuiltinFloat::F128)),
(Name::new_symbol_root(sym::f16), BuiltinType::Float(BuiltinFloat::F16)),
(Name::new_symbol_root(sym::f32), BuiltinType::Float(BuiltinFloat::F32)),
(Name::new_symbol_root(sym::f64), BuiltinType::Float(BuiltinFloat::F64)),
(Name::new_symbol_root(sym::f128), BuiltinType::Float(BuiltinFloat::F128)),
];
pub fn by_name(name: &Name) -> Option<Self> {
@ -81,30 +82,30 @@ impl BuiltinType {
impl AsName for BuiltinType {
fn as_name(&self) -> Name {
match self {
BuiltinType::Char => name![char],
BuiltinType::Bool => name![bool],
BuiltinType::Str => name![str],
BuiltinType::Char => Name::new_symbol_root(sym::char),
BuiltinType::Bool => Name::new_symbol_root(sym::bool),
BuiltinType::Str => Name::new_symbol_root(sym::str),
BuiltinType::Int(it) => match it {
BuiltinInt::Isize => name![isize],
BuiltinInt::I8 => name![i8],
BuiltinInt::I16 => name![i16],
BuiltinInt::I32 => name![i32],
BuiltinInt::I64 => name![i64],
BuiltinInt::I128 => name![i128],
BuiltinInt::Isize => Name::new_symbol_root(sym::isize),
BuiltinInt::I8 => Name::new_symbol_root(sym::i8),
BuiltinInt::I16 => Name::new_symbol_root(sym::i16),
BuiltinInt::I32 => Name::new_symbol_root(sym::i32),
BuiltinInt::I64 => Name::new_symbol_root(sym::i64),
BuiltinInt::I128 => Name::new_symbol_root(sym::i128),
},
BuiltinType::Uint(it) => match it {
BuiltinUint::Usize => name![usize],
BuiltinUint::U8 => name![u8],
BuiltinUint::U16 => name![u16],
BuiltinUint::U32 => name![u32],
BuiltinUint::U64 => name![u64],
BuiltinUint::U128 => name![u128],
BuiltinUint::Usize => Name::new_symbol_root(sym::usize),
BuiltinUint::U8 => Name::new_symbol_root(sym::u8),
BuiltinUint::U16 => Name::new_symbol_root(sym::u16),
BuiltinUint::U32 => Name::new_symbol_root(sym::u32),
BuiltinUint::U64 => Name::new_symbol_root(sym::u64),
BuiltinUint::U128 => Name::new_symbol_root(sym::u128),
},
BuiltinType::Float(it) => match it {
BuiltinFloat::F16 => name![f16],
BuiltinFloat::F32 => name![f32],
BuiltinFloat::F64 => name![f64],
BuiltinFloat::F128 => name![f128],
BuiltinFloat::F16 => Name::new_symbol_root(sym::f16),
BuiltinFloat::F32 => Name::new_symbol_root(sym::f32),
BuiltinFloat::F64 => Name::new_symbol_root(sym::f64),
BuiltinFloat::F128 => Name::new_symbol_root(sym::f128),
},
}
}

View file

@ -6,7 +6,7 @@ use base_db::CrateId;
use hir_expand::{
name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefKind,
};
use intern::Interned;
use intern::{sym, Interned};
use smallvec::SmallVec;
use syntax::{ast, Parse};
use triomphe::Arc;
@ -485,7 +485,7 @@ impl ExternCrateDeclData {
let name = extern_crate.name.clone();
let krate = loc.container.krate();
let crate_id = if name == hir_expand::name![self] {
let crate_id = if name == sym::self_ {
Some(krate)
} else {
db.crate_def_map(krate)

View file

@ -2,7 +2,7 @@
use base_db::{salsa, CrateId, FileId, SourceDatabase, Upcast};
use either::Either;
use hir_expand::{db::ExpandDatabase, HirFileId, MacroDefId};
use intern::Interned;
use intern::{sym, Interned};
use la_arena::ArenaMap;
use span::MacroCallId;
use syntax::{ast, AstPtr};
@ -261,9 +261,9 @@ fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: CrateId) -> bool {
let item_tree = db.file_item_tree(file.into());
let attrs = item_tree.raw_attrs(AttrOwner::TopLevel);
for attr in &**attrs {
match attr.path().as_ident().and_then(|id| id.as_text()) {
Some(ident) if ident == "no_std" => return true,
Some(ident) if ident == "cfg_attr" => {}
match attr.path().as_ident() {
Some(ident) if *ident == sym::no_std => return true,
Some(ident) if *ident == sym::cfg_attr => {}
_ => continue,
}

View file

@ -10,6 +10,7 @@ use hir_expand::{
InFile, MacroCallId,
};
use limit::Limit;
use span::SyntaxContextId;
use syntax::{ast, Parse};
use triomphe::Arc;
@ -52,6 +53,11 @@ impl Expander {
self.module.krate
}
pub fn syntax_context(&self) -> SyntaxContextId {
// FIXME:
SyntaxContextId::ROOT
}
pub fn enter_expand<T: ast::AstNode>(
&mut self,
db: &dyn DefDatabase,

View file

@ -3,9 +3,10 @@
use std::{cell::Cell, cmp::Ordering, iter};
use hir_expand::{
name::{known, AsName, Name},
name::{AsName, Name},
Lookup,
};
use intern::{sym, Symbol};
use rustc_hash::FxHashSet;
use crate::{
@ -414,13 +415,13 @@ fn select_best_path(
(Unstable, Stable) => return new_path,
_ => {}
}
const STD_CRATES: [Name; 3] = [known::std, known::core, known::alloc];
const STD_CRATES: [Symbol; 3] = [sym::std, sym::core, sym::alloc];
let choose = |new: (ModPath, _), old: (ModPath, _)| {
let (new_path, _) = &new;
let (old_path, _) = &old;
let new_has_prelude = new_path.segments().iter().any(|seg| seg == &known::prelude);
let old_has_prelude = old_path.segments().iter().any(|seg| seg == &known::prelude);
let new_has_prelude = new_path.segments().iter().any(|seg| *seg == sym::prelude);
let old_has_prelude = old_path.segments().iter().any(|seg| *seg == sym::prelude);
match (new_has_prelude, old_has_prelude, cfg.prefer_prelude) {
(true, false, true) | (false, true, false) => new,
(true, false, false) | (false, true, true) => old,
@ -441,18 +442,20 @@ fn select_best_path(
};
match (old_path.0.segments().first(), new_path.0.segments().first()) {
(Some(old), Some(new)) if STD_CRATES.contains(old) && STD_CRATES.contains(new) => {
(Some(old), Some(new))
if STD_CRATES.contains(old.symbol()) && STD_CRATES.contains(new.symbol()) =>
{
let rank = match cfg.prefer_no_std {
false => |name: &Name| match name {
name if name == &known::core => 0,
name if name == &known::alloc => 1,
name if name == &known::std => 2,
name if *name == sym::core => 0,
name if *name == sym::alloc => 1,
name if *name == sym::std => 2,
_ => unreachable!(),
},
true => |name: &Name| match name {
name if name == &known::core => 2,
name if name == &known::alloc => 1,
name if name == &known::std => 0,
name if *name == sym::core => 2,
name if *name == sym::alloc => 1,
name if *name == sym::std => 0,
_ => unreachable!(),
},
};

View file

@ -3,10 +3,11 @@ use std::mem;
use hir_expand::name::Name;
use rustc_parse_format as parse;
use span::SyntaxContextId;
use stdx::TupleExt;
use syntax::{
ast::{self, IsString},
SmolStr, TextRange, TextSize,
TextRange, TextSize,
};
use crate::hir::ExprId;
@ -174,6 +175,7 @@ pub(crate) fn parse(
is_direct_literal: bool,
mut synth: impl FnMut(Name) -> ExprId,
mut record_usage: impl FnMut(Name, Option<TextRange>),
call_ctx: SyntaxContextId,
) -> FormatArgs {
let Ok(text) = s.value() else {
return FormatArgs {
@ -248,7 +250,7 @@ pub(crate) fn parse(
}
}
ArgRef::Name(name, span) => {
let name = Name::new_text_dont_use(SmolStr::new(name));
let name = Name::new(name, call_ctx);
if let Some((index, _)) = args.by_name(&name) {
record_usage(name, span);
// Name found in `args`, so we resolve it to its index.

View file

@ -2,7 +2,8 @@
use std::collections::hash_map::Entry;
use hir_expand::{mod_path::path, name, name::AsName, span_map::SpanMapRef, HirFileId};
use hir_expand::{mod_path::path, name::AsName, span_map::SpanMapRef, HirFileId};
use intern::sym;
use la_arena::Arena;
use rustc_hash::FxHashMap;
use span::{AstIdMap, SyntaxContextId};
@ -323,7 +324,7 @@ impl<'a> Ctx<'a> {
let self_type = match self_param.ty() {
Some(type_ref) => TypeRef::from_ast(&self.body_ctx, type_ref),
None => {
let self_type = TypeRef::Path(name![Self].into());
let self_type = TypeRef::Path(Name::new_symbol_root(sym::Self_).into());
match self_param.kind() {
ast::SelfParamKind::Owned => self_type,
ast::SelfParamKind::Ref => TypeRef::Reference(
@ -669,7 +670,7 @@ impl<'a> Ctx<'a> {
// Traits and trait aliases get the Self type as an implicit first type parameter.
generics.type_or_consts.alloc(
TypeParamData {
name: Some(name![Self]),
name: Some(Name::new_symbol_root(sym::Self_)),
default: None,
provenance: TypeParamProvenance::TraitSelf,
}
@ -680,7 +681,7 @@ impl<'a> Ctx<'a> {
generics.fill_bounds(
&self.body_ctx,
bounds,
Either::Left(TypeRef::Path(name![Self].into())),
Either::Left(TypeRef::Path(Name::new_symbol_root(sym::Self_).into())),
);
}
@ -745,7 +746,7 @@ fn desugar_future_path(orig: TypeRef) -> Path {
let mut generic_args: Vec<_> =
std::iter::repeat(None).take(path.segments().len() - 1).collect();
let binding = AssociatedTypeBinding {
name: name![Output],
name: Name::new_symbol_root(sym::Output),
args: None,
type_ref: Some(orig),
bounds: Box::default(),

View file

@ -3,6 +3,7 @@
//! This attribute to tell the compiler about semi built-in std library
//! features, such as Fn family of traits.
use hir_expand::name::Name;
use intern::{sym, Symbol};
use rustc_hash::FxHashMap;
use syntax::SmolStr;
use triomphe::Arc;
@ -267,6 +268,14 @@ macro_rules! language_item_table {
_ => None,
}
}
/// Opposite of [`LangItem::name`]
pub fn from_symbol(sym: Symbol) -> Option<Self> {
match sym {
$(sym if sym == $module::$name => Some(LangItem::$variant), )*
_ => None,
}
}
}
}
}
@ -274,7 +283,7 @@ macro_rules! language_item_table {
impl LangItem {
/// Opposite of [`LangItem::name`]
pub fn from_name(name: &hir_expand::name::Name) -> Option<Self> {
Self::from_str(name.as_str()?)
Self::from_str(name.as_str())
}
pub fn path(&self, db: &dyn DefDatabase, start_crate: CrateId) -> Option<Path> {
@ -360,7 +369,7 @@ language_item_table! {
DerefTarget, sym::deref_target, deref_target, Target::AssocTy, GenericRequirement::None;
Receiver, sym::receiver, receiver_trait, Target::Trait, GenericRequirement::None;
Fn, kw::fn, fn_trait, Target::Trait, GenericRequirement::Exact(1);
Fn, sym::fn_, fn_trait, Target::Trait, GenericRequirement::Exact(1);
FnMut, sym::fn_mut, fn_mut_trait, Target::Trait, GenericRequirement::Exact(1);
FnOnce, sym::fn_once, fn_once_trait, Target::Trait, GenericRequirement::Exact(1);

View file

@ -862,7 +862,7 @@ impl GeneralConstId {
.const_data(const_id)
.name
.as_ref()
.and_then(|it| it.as_str())
.map(|it| it.as_str())
.unwrap_or("_")
.to_owned(),
GeneralConstId::ConstBlockId(id) => format!("{{anonymous const {id:?}}}"),

View file

@ -13,11 +13,11 @@ use hir_expand::{
builtin_attr_macro::find_builtin_attr,
builtin_derive_macro::find_builtin_derive,
builtin_fn_macro::find_builtin_macro,
name::{name, AsName, Name},
name::{AsName, Name},
proc_macro::CustomProcMacroExpander,
ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
};
use intern::Interned;
use intern::{sym, Interned};
use itertools::{izip, Itertools};
use la_arena::Idx;
use limit::Limit;
@ -76,25 +76,28 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI
let proc_macros = if krate.is_proc_macro {
match db.proc_macros().get(&def_map.krate) {
Some(Ok(proc_macros)) => Ok(proc_macros
.iter()
.enumerate()
.map(|(idx, it)| {
let name = Name::new_text_dont_use(it.name.clone());
(
name,
if !db.expand_proc_attr_macros() {
CustomProcMacroExpander::dummy()
} else if it.disabled {
CustomProcMacroExpander::disabled()
} else {
CustomProcMacroExpander::new(hir_expand::proc_macro::ProcMacroId::new(
idx as u32,
))
},
)
})
.collect()),
Some(Ok(proc_macros)) => Ok({
let ctx = db.syntax_context(tree_id.file_id());
proc_macros
.iter()
.enumerate()
.map(|(idx, it)| {
let name = Name::new(&it.name, ctx);
(
name,
if !db.expand_proc_attr_macros() {
CustomProcMacroExpander::dummy()
} else if it.disabled {
CustomProcMacroExpander::disabled()
} else {
CustomProcMacroExpander::new(
hir_expand::proc_macro::ProcMacroId::new(idx as u32),
)
},
)
})
.collect()
}),
Some(Err(e)) => Err(e.clone().into_boxed_str()),
None => Err("No proc-macros present for crate".to_owned().into_boxed_str()),
}
@ -291,24 +294,24 @@ impl DefCollector<'_> {
let Some(attr_name) = attr.path.as_ident() else { continue };
match () {
() if *attr_name == hir_expand::name![recursion_limit] => {
() if *attr_name == sym::recursion_limit => {
if let Some(limit) = attr.string_value() {
if let Ok(limit) = limit.parse() {
crate_data.recursion_limit = Some(limit);
}
}
}
() if *attr_name == hir_expand::name![crate_type] => {
() if *attr_name == sym::crate_type => {
if let Some("proc-macro") = attr.string_value() {
self.is_proc_macro = true;
}
}
() if *attr_name == hir_expand::name![no_core] => crate_data.no_core = true,
() if *attr_name == hir_expand::name![no_std] => crate_data.no_std = true,
() if attr_name.as_text().as_deref() == Some("rustc_coherence_is_core") => {
() if *attr_name == sym::no_core => crate_data.no_core = true,
() if *attr_name == sym::no_std => crate_data.no_std = true,
() if *attr_name == sym::rustc_coherence_is_core => {
crate_data.rustc_coherence_is_core = true;
}
() if *attr_name == hir_expand::name![feature] => {
() if *attr_name == sym::feature => {
let features = attr
.parse_path_comma_token_tree(self.db.upcast())
.into_iter()
@ -319,13 +322,13 @@ impl DefCollector<'_> {
});
crate_data.unstable_features.extend(features);
}
() if *attr_name == hir_expand::name![register_attr] => {
() if *attr_name == sym::register_attr => {
if let Some(ident) = attr.single_ident_value() {
crate_data.registered_attrs.push(ident.text.clone());
cov_mark::hit!(register_attr);
}
}
() if *attr_name == hir_expand::name![register_tool] => {
() if *attr_name == sym::register_tool => {
if let Some(ident) = attr.single_ident_value() {
crate_data.registered_tools.push(ident.text.clone());
cov_mark::hit!(register_tool);
@ -535,27 +538,30 @@ impl DefCollector<'_> {
}
let krate = if self.def_map.data.no_std {
name![core]
} else if self.def_map.extern_prelude().any(|(name, _)| *name == name![std]) {
name![std]
Name::new_symbol_root(sym::core)
} else if self.def_map.extern_prelude().any(|(name, _)| *name == sym::std) {
Name::new_symbol_root(sym::std)
} else {
// If `std` does not exist for some reason, fall back to core. This mostly helps
// keep r-a's own tests minimal.
name![core]
Name::new_symbol_root(sym::core)
};
let edition = match self.def_map.data.edition {
Edition::Edition2015 => name![rust_2015],
Edition::Edition2018 => name![rust_2018],
Edition::Edition2021 => name![rust_2021],
Edition::Edition2024 => name![rust_2024],
Edition::Edition2015 => Name::new_symbol_root(sym::rust_2015),
Edition::Edition2018 => Name::new_symbol_root(sym::rust_2018),
Edition::Edition2021 => Name::new_symbol_root(sym::rust_2021),
Edition::Edition2024 => Name::new_symbol_root(sym::rust_2024),
};
let path_kind = match self.def_map.data.edition {
Edition::Edition2015 => PathKind::Plain,
_ => PathKind::Abs,
};
let path = ModPath::from_segments(path_kind, [krate, name![prelude], edition]);
let path = ModPath::from_segments(
path_kind,
[krate, Name::new_symbol_root(sym::prelude), edition],
);
let (per_ns, _) =
self.def_map.resolve_path(self.db, DefMap::ROOT, &path, BuiltinShadowMode::Other, None);
@ -838,7 +844,7 @@ impl DefCollector<'_> {
}
fn resolve_extern_crate(&self, name: &Name) -> Option<CrateRootModuleId> {
if *name == name![self] {
if *name == sym::self_ {
cov_mark::hit!(extern_crate_self_as);
Some(self.def_map.crate_root())
} else {
@ -2136,9 +2142,9 @@ impl ModCollector<'_, '_> {
let expander = if attrs.by_key("rustc_builtin_macro").exists() {
// `#[rustc_builtin_macro = "builtin_name"]` overrides the `macro_rules!` name.
let name;
let name = match attrs.by_key("rustc_builtin_macro").string_value() {
Some(it) => {
name = Name::new_text_dont_use(it.into());
let name = match attrs.by_key("rustc_builtin_macro").string_value_with_span() {
Some((it, span)) => {
name = Name::new(it, span.ctx);
&name
}
None => {

View file

@ -6,9 +6,9 @@ use crate::{lower::LowerCtx, type_ref::ConstRef};
use hir_expand::{
mod_path::resolve_crate_root,
name::{name, AsName},
name::{AsName, Name},
};
use intern::Interned;
use intern::{sym, Interned};
use syntax::ast::{self, AstNode, HasGenericArgs, HasTypeBounds};
use crate::{
@ -60,7 +60,7 @@ pub(super) fn lower_path(ctx: &LowerCtx<'_>, mut path: ast::Path) -> Option<Path
segments.push(name);
}
ast::PathSegmentKind::SelfTypeKw => {
segments.push(name![Self]);
segments.push(Name::new_symbol_root(sym::Self_));
}
ast::PathSegmentKind::Type { type_ref, trait_ref } => {
assert!(path.qualifier().is_none()); // this can only occur at the first segment
@ -268,7 +268,7 @@ fn lower_generic_args_from_fn_path(
let bindings = if let Some(ret_type) = ret_type {
let type_ref = TypeRef::from_ast_opt(ctx, ret_type.ty());
Box::new([AssociatedTypeBinding {
name: name![Output],
name: Name::new_symbol_root(sym::Output),
args: None,
type_ref: Some(type_ref),
bounds: Box::default(),
@ -277,7 +277,7 @@ fn lower_generic_args_from_fn_path(
// -> ()
let type_ref = TypeRef::Tuple(Vec::new());
Box::new([AssociatedTypeBinding {
name: name![Output],
name: Name::new_symbol_root(sym::Output),
args: None,
type_ref: Some(type_ref),
bounds: Box::default(),

View file

@ -2,11 +2,8 @@
use std::{fmt, iter, mem};
use base_db::CrateId;
use hir_expand::{
name::{name, Name},
MacroDefId,
};
use intern::Interned;
use hir_expand::{name::Name, MacroDefId};
use intern::{sym, Interned};
use rustc_hash::FxHashSet;
use smallvec::{smallvec, SmallVec};
use triomphe::Arc;
@ -197,12 +194,12 @@ impl Resolver {
}
}
&Scope::ImplDefScope(impl_) => {
if first_name == &name![Self] {
if *first_name == sym::Self_ {
return Some((TypeNs::SelfType(impl_), remaining_idx(), None));
}
}
&Scope::AdtScope(adt) => {
if first_name == &name![Self] {
if *first_name == sym::Self_ {
return Some((TypeNs::AdtSelfType(adt), remaining_idx(), None));
}
}
@ -294,7 +291,7 @@ impl Resolver {
}
};
let n_segments = path.segments().len();
let tmp = name![self];
let tmp = Name::new_symbol_root(sym::Self_);
let first_name = if path.is_self() { &tmp } else { path.segments().first()? };
let skip_to_mod = path.kind != PathKind::Plain && !path.is_self();
if skip_to_mod {
@ -325,7 +322,7 @@ impl Resolver {
}
}
&Scope::ImplDefScope(impl_) => {
if first_name == &name![Self] {
if *first_name == sym::Self_ {
return Some(ResolveValueResult::ValueNs(
ValueNs::ImplSelf(impl_),
None,
@ -352,7 +349,7 @@ impl Resolver {
}
}
&Scope::ImplDefScope(impl_) => {
if first_name == &name![Self] {
if *first_name == sym::Self_ {
return Some(ResolveValueResult::Partial(
TypeNs::SelfType(impl_),
1,
@ -361,7 +358,7 @@ impl Resolver {
}
}
Scope::AdtScope(adt) => {
if first_name == &name![Self] {
if *first_name == sym::Self_ {
let ty = TypeNs::AdtSelfType(*adt);
return Some(ResolveValueResult::Partial(ty, 1, None));
}
@ -425,7 +422,7 @@ impl Resolver {
}
pub fn resolve_lifetime(&self, lifetime: &LifetimeRef) -> Option<LifetimeNs> {
if lifetime.name == name::known::STATIC_LIFETIME {
if lifetime.name == sym::tick_static {
return Some(LifetimeNs::Static);
}
@ -781,10 +778,10 @@ impl Scope {
}
}
Scope::ImplDefScope(i) => {
acc.add(&name![Self], ScopeDef::ImplSelfType(*i));
acc.add(&Name::new_symbol_root(sym::Self_), ScopeDef::ImplSelfType(*i));
}
Scope::AdtScope(i) => {
acc.add(&name![Self], ScopeDef::AdtSelfType(*i));
acc.add(&Name::new_symbol_root(sym::Self_), ScopeDef::AdtSelfType(*i));
}
Scope::ExprScope(scope) => {
if let Some((label, name)) = scope.expr_scopes.label(scope.scope_id) {

View file

@ -4,7 +4,7 @@ use std::{borrow::Cow, fmt, ops};
use base_db::CrateId;
use cfg::CfgExpr;
use either::Either;
use intern::Interned;
use intern::{sym, Interned};
use mbe::{syntax_node_to_token_tree, DelimiterKind, DocCommentDesugarMode, Punct};
use smallvec::{smallvec, SmallVec};
use span::{Span, SyntaxContextId};
@ -12,6 +12,7 @@ use syntax::unescape;
use syntax::{ast, format_smolstr, match_ast, AstNode, AstToken, SmolStr, SyntaxNode};
use triomphe::ThinArc;
use crate::name::Name;
use crate::{
db::ExpandDatabase,
mod_path::ModPath,
@ -58,7 +59,7 @@ impl RawAttrs {
text: SmolStr::new(format_smolstr!("\"{}\"", Self::escape_chars(doc))),
span,
}))),
path: Interned::new(ModPath::from(crate::name!(doc))),
path: Interned::new(ModPath::from(Name::new_symbol(sym::doc, span.ctx))),
ctxt: span.ctx,
}
}),
@ -115,47 +116,47 @@ impl RawAttrs {
pub fn filter(self, db: &dyn ExpandDatabase, krate: CrateId) -> RawAttrs {
let has_cfg_attrs = self
.iter()
.any(|attr| attr.path.as_ident().map_or(false, |name| *name == crate::name![cfg_attr]));
.any(|attr| attr.path.as_ident().map_or(false, |name| *name == sym::cfg_attr));
if !has_cfg_attrs {
return self;
}
let crate_graph = db.crate_graph();
let new_attrs =
self.iter()
.flat_map(|attr| -> SmallVec<[_; 1]> {
let is_cfg_attr =
attr.path.as_ident().map_or(false, |name| *name == crate::name![cfg_attr]);
if !is_cfg_attr {
return smallvec![attr.clone()];
}
let new_attrs = self
.iter()
.flat_map(|attr| -> SmallVec<[_; 1]> {
let is_cfg_attr = attr.path.as_ident().map_or(false, |name| *name == sym::cfg_attr);
if !is_cfg_attr {
return smallvec![attr.clone()];
}
let subtree = match attr.token_tree_value() {
Some(it) => it,
_ => return smallvec![attr.clone()],
};
let subtree = match attr.token_tree_value() {
Some(it) => it,
_ => return smallvec![attr.clone()],
};
let (cfg, parts) = match parse_cfg_attr_input(subtree) {
Some(it) => it,
None => return smallvec![attr.clone()],
};
let index = attr.id;
let attrs = parts.enumerate().take(1 << AttrId::CFG_ATTR_BITS).filter_map(
|(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx)),
);
let (cfg, parts) = match parse_cfg_attr_input(subtree) {
Some(it) => it,
None => return smallvec![attr.clone()],
};
let index = attr.id;
let attrs = parts
.enumerate()
.take(1 << AttrId::CFG_ATTR_BITS)
.filter_map(|(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx)));
let cfg_options = &crate_graph[krate].cfg_options;
let cfg = Subtree { delimiter: subtree.delimiter, token_trees: Box::from(cfg) };
let cfg = CfgExpr::parse(&cfg);
if cfg_options.check(&cfg) == Some(false) {
smallvec![]
} else {
cov_mark::hit!(cfg_attr_active);
let cfg_options = &crate_graph[krate].cfg_options;
let cfg = Subtree { delimiter: subtree.delimiter, token_trees: Box::from(cfg) };
let cfg = CfgExpr::parse(&cfg);
if cfg_options.check(&cfg) == Some(false) {
smallvec![]
} else {
cov_mark::hit!(cfg_attr_active);
attrs.collect()
}
})
.collect::<Vec<_>>();
attrs.collect()
}
})
.collect::<Vec<_>>();
let entries = if new_attrs.is_empty() {
None
} else {
@ -316,6 +317,20 @@ impl Attr {
}
}
/// #[path = "string"]
pub fn string_value_with_span(&self) -> Option<(&str, span::Span)> {
match self.input.as_deref()? {
AttrInput::Literal(it) => match it.text.strip_prefix('r') {
Some(it) => it.trim_matches('#'),
None => it.text.as_str(),
}
.strip_prefix('"')?
.strip_suffix('"')
.zip(Some(it.span)),
_ => None,
}
}
pub fn string_value_unescape(&self) -> Option<Cow<'_, str>> {
match self.input.as_deref()? {
AttrInput::Literal(it) => match it.text.strip_prefix('r') {
@ -369,7 +384,7 @@ impl Attr {
}
pub fn cfg(&self) -> Option<CfgExpr> {
if *self.path.as_ident()? == crate::name![cfg] {
if *self.path.as_ident()? == sym::cfg {
self.token_tree_value().map(CfgExpr::parse)
} else {
None

View file

@ -1,4 +1,5 @@
//! Builtin attributes.
use intern::sym;
use span::{MacroCallId, Span};
use crate::{db::ExpandDatabase, name, tt, ExpandResult, MacroCallKind};
@ -19,7 +20,7 @@ macro_rules! register_builtin {
fn find_by_name(name: &name::Name) -> Option<Self> {
match name {
$( id if id == &name::name![$name] => Some(BuiltinAttrExpander::$variant), )*
$( id if id == &sym::$name => Some(BuiltinAttrExpander::$variant), )*
_ => None,
}
}

View file

@ -1,5 +1,6 @@
//! Builtin derives.
use intern::sym;
use itertools::izip;
use mbe::DocCommentDesugarMode;
use rustc_hash::FxHashSet;
@ -36,7 +37,7 @@ macro_rules! register_builtin {
fn find_by_name(name: &name::Name) -> Option<Self> {
match name {
$( id if id == &name::name![$trait] => Some(BuiltinDeriveExpander::$trait), )*
$( id if id == &sym::$trait => Some(BuiltinDeriveExpander::$trait), )*
_ => None,
}
}

View file

@ -3,6 +3,7 @@
use base_db::{AnchoredPath, FileId};
use cfg::CfgExpr;
use either::Either;
use intern::sym;
use itertools::Itertools;
use mbe::{parse_exprs_with_sep, parse_to_token_tree};
use span::{Edition, Span, SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID};
@ -11,8 +12,7 @@ use syntax::ast::{self, AstToken};
use crate::{
db::ExpandDatabase,
hygiene::{span_with_call_site_ctxt, span_with_def_site_ctxt},
name::{self, known},
quote,
name, quote,
quote::dollar_crate,
tt::{self, DelimSpan},
ExpandError, ExpandResult, HirFileIdExt, MacroCallId, MacroFileIdExt,
@ -48,8 +48,8 @@ macro_rules! register_builtin {
fn find_by_name(ident: &name::Name) -> Option<Either<BuiltinFnLikeExpander, EagerExpander>> {
match ident {
$( id if id == &name::name![$name] => Some(Either::Left(BuiltinFnLikeExpander::$kind)), )*
$( id if id == &name::name![$e_name] => Some(Either::Right(EagerExpander::$e_kind)), )*
$( id if id == &sym::$name => Some(Either::Left(BuiltinFnLikeExpander::$kind)), )*
$( id if id == &sym::$e_name => Some(Either::Right(EagerExpander::$e_kind)), )*
_ => return None,
}
}
@ -367,8 +367,7 @@ fn panic_expand(
let dollar_crate = dollar_crate(span);
let call_site_span = span_with_call_site_ctxt(db, span, id);
let mac =
if use_panic_2021(db, call_site_span) { known::panic_2021 } else { known::panic_2015 };
let mac = if use_panic_2021(db, call_site_span) { sym::panic_2021 } else { sym::panic_2015 };
// Expand to a macro call `$crate::panic::panic_{edition}`
let mut call = quote!(call_site_span =>#dollar_crate::panic::#mac!);
@ -397,9 +396,9 @@ fn unreachable_expand(
let call_site_span = span_with_call_site_ctxt(db, span, id);
let mac = if use_panic_2021(db, call_site_span) {
known::unreachable_2021
sym::unreachable_2021
} else {
known::unreachable_2015
sym::unreachable_2015
};
// Expand to a macro call `$crate::panic::panic_{edition}`

View file

@ -133,6 +133,15 @@ pub trait ExpandDatabase: SourceDatabase {
&self,
macro_call: MacroCallId,
) -> Option<Arc<ExpandResult<Arc<[SyntaxError]>>>>;
#[salsa::transparent]
fn syntax_context(&self, file: HirFileId) -> SyntaxContextId;
}
fn syntax_context(db: &dyn ExpandDatabase, file: HirFileId) -> SyntaxContextId {
match file.repr() {
HirFileIdRepr::FileId(_) => SyntaxContextId::ROOT,
HirFileIdRepr::MacroFile(m) => db.macro_arg(m.macro_call_id).2.ctx,
}
}
/// This expands the given macro call, but with different arguments. This is

View file

@ -2,6 +2,7 @@
use std::sync::OnceLock;
use base_db::{CrateId, VersionReq};
use intern::sym;
use mbe::DocCommentDesugarMode;
use span::{Edition, MacroCallId, Span, SyntaxContextId};
use stdx::TupleExt;
@ -111,8 +112,10 @@ impl DeclarativeMacroExpander {
match &*attrs
.iter()
.find(|it| {
it.path.as_ident().and_then(|it| it.as_str())
== Some("rustc_macro_transparency")
it.path
.as_ident()
.map(|it| *it == sym::rustc_macro_transparency)
.unwrap_or(false)
})?
.token_tree_value()?
.token_trees

View file

@ -8,10 +8,11 @@ use std::{
use crate::{
db::ExpandDatabase,
hygiene::{marks_rev, SyntaxContextExt, Transparency},
name::{known, AsName, Name},
name::{AsName, Name},
tt,
};
use base_db::CrateId;
use intern::sym;
use smallvec::SmallVec;
use span::SyntaxContextId;
use syntax::{ast, AstNode};
@ -106,10 +107,7 @@ impl ModPath {
PathKind::Abs => 0,
PathKind::DollarCrate(_) => "$crate".len(),
};
self.segments()
.iter()
.map(|segment| segment.as_str().map_or(0, str::len))
.fold(base, core::ops::Add::add)
self.segments().iter().map(|segment| segment.as_str().len()).fold(base, core::ops::Add::add)
}
pub fn is_ident(&self) -> bool {
@ -122,8 +120,7 @@ impl ModPath {
#[allow(non_snake_case)]
pub fn is_Self(&self) -> bool {
self.kind == PathKind::Plain
&& matches!(&*self.segments, [name] if *name == known::SELF_TYPE)
self.kind == PathKind::Plain && matches!(&*self.segments, [name] if *name == sym::Self_)
}
/// If this path is a single identifier, like `foo`, return its name.
@ -265,9 +262,10 @@ fn convert_path(
res
}
}
ast::PathSegmentKind::SelfTypeKw => {
ModPath::from_segments(PathKind::Plain, Some(known::SELF_TYPE))
}
ast::PathSegmentKind::SelfTypeKw => ModPath::from_segments(
PathKind::Plain,
Some(Name::new_symbol(sym::Self_, SyntaxContextId::ROOT)),
),
ast::PathSegmentKind::CrateKw => ModPath::from_segments(PathKind::Crate, iter::empty()),
ast::PathSegmentKind::SelfKw => handle_super_kw(0)?,
ast::PathSegmentKind::SuperKw => handle_super_kw(1)?,
@ -323,9 +321,9 @@ fn convert_path_tt(db: &dyn ExpandDatabase, tt: &[tt::TokenTree]) -> Option<ModP
tt::Leaf::Ident(tt::Ident { text, .. }) if text == "self" => PathKind::SELF,
tt::Leaf::Ident(tt::Ident { text, .. }) if text == "super" => {
let mut deg = 1;
while let Some(tt::Leaf::Ident(tt::Ident { text, .. })) = leaves.next() {
while let Some(tt::Leaf::Ident(tt::Ident { text, span, .. })) = leaves.next() {
if text != "super" {
segments.push(Name::new_text_dont_use(text.clone()));
segments.push(Name::new(text, span.ctx));
break;
}
deg += 1;
@ -334,13 +332,13 @@ fn convert_path_tt(db: &dyn ExpandDatabase, tt: &[tt::TokenTree]) -> Option<ModP
}
tt::Leaf::Ident(tt::Ident { text, .. }) if text == "crate" => PathKind::Crate,
tt::Leaf::Ident(ident) => {
segments.push(Name::new_text_dont_use(ident.text.clone()));
segments.push(Name::new(&ident.text, ident.span.ctx));
PathKind::Plain
}
_ => return None,
};
segments.extend(leaves.filter_map(|leaf| match leaf {
::tt::Leaf::Ident(ident) => Some(Name::new_text_dont_use(ident.text.clone())),
::tt::Leaf::Ident(ident) => Some(Name::new(&ident.text, ident.span.ctx)),
_ => None,
}));
Some(ModPath { kind, segments })
@ -385,6 +383,8 @@ macro_rules! __known_path {
(core::ops::RangeInclusive) => {};
(core::future::Future) => {};
(core::future::IntoFuture) => {};
(core::fmt::Debug) => {};
(std::fmt::format) => {};
(core::ops::Try) => {};
($path:path) => {
compile_error!("Please register your known path in the path module")
@ -396,7 +396,7 @@ macro_rules! __path {
($start:ident $(:: $seg:ident)*) => ({
$crate::__known_path!($start $(:: $seg)*);
$crate::mod_path::ModPath::from_segments($crate::mod_path::PathKind::Abs, vec![
$crate::mod_path::__name![$start], $($crate::mod_path::__name![$seg],)*
$crate::name::Name::new_symbol_root(intern::sym::$start), $($crate::name::Name::new_symbol_root(intern::sym::$seg),)*
])
});
}

View file

@ -2,6 +2,8 @@
use std::fmt;
use intern::{sym::MISSING_NAME, Symbol};
use span::SyntaxContextId;
use syntax::{ast, format_smolstr, utils::is_raw_identifier, SmolStr};
/// `Name` is a wrapper around string, which is used in hir for both references
@ -11,32 +13,49 @@ use syntax::{ast, format_smolstr, utils::is_raw_identifier, SmolStr};
/// Note that `Name` holds and prints escaped name i.e. prefixed with "r#" when it
/// is a raw identifier. Use [`unescaped()`][Name::unescaped] when you need the
/// name without "r#".
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Name(Repr);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Name {
symbol: Symbol,
ctx: (),
}
impl Ord for Name {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.symbol.as_str().cmp(other.symbol.as_str())
}
}
impl PartialOrd for Name {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl PartialEq<Symbol> for Name {
fn eq(&self, sym: &Symbol) -> bool {
self.symbol == *sym
}
}
impl PartialEq<Name> for Symbol {
fn eq(&self, name: &Name) -> bool {
*self == name.symbol
}
}
/// Wrapper of `Name` to print the name without "r#" even when it is a raw identifier.
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct UnescapedName<'a>(&'a Name);
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
enum Repr {
Text(SmolStr),
TupleField(usize),
}
impl UnescapedName<'_> {
/// Returns the textual representation of this name as a [`SmolStr`]. Prefer using this over
/// [`ToString::to_string`] if possible as this conversion is cheaper in the general case.
pub fn to_smol_str(&self) -> SmolStr {
match &self.0 .0 {
Repr::Text(it) => {
if let Some(stripped) = it.strip_prefix("r#") {
SmolStr::new(stripped)
} else {
it.clone()
}
}
Repr::TupleField(it) => SmolStr::new(it.to_string()),
let it = self.0.symbol.as_str();
if let Some(stripped) = it.strip_prefix("r#") {
SmolStr::new(stripped)
} else {
it.into()
}
}
@ -50,27 +69,26 @@ 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))
fn new_text(text: &str) -> Name {
Name { symbol: Symbol::intern(text), ctx: () }
}
// FIXME: See above, unfortunately some places really need this right now
#[doc(hidden)]
pub const fn new_text_dont_use(text: SmolStr) -> Name {
Name(Repr::Text(text))
pub fn new(text: &str, ctx: SyntaxContextId) -> Name {
_ = ctx;
Name { symbol: Symbol::intern(text), ctx: () }
}
pub fn new_tuple_field(idx: usize) -> Name {
Name(Repr::TupleField(idx))
Name { symbol: Symbol::intern(&idx.to_string()), ctx: () }
}
pub fn new_lifetime(lt: &ast::Lifetime) -> Name {
Self::new_text(lt.text().into())
Name { symbol: Symbol::intern(lt.text().as_str()), ctx: () }
}
/// Shortcut to create a name from a string literal.
const fn new_static(text: &'static str) -> Name {
Name::new_text(SmolStr::new_static(text))
fn new_ref(text: &str) -> Name {
Name { symbol: Symbol::intern(text), ctx: () }
}
/// Resolve a name from the text of token.
@ -78,14 +96,14 @@ impl Name {
match raw_text.strip_prefix("r#") {
// When `raw_text` starts with "r#" but the name does not coincide with any
// keyword, we never need the prefix so we strip it.
Some(text) if !is_raw_identifier(text) => Name::new_text(SmolStr::new(text)),
Some(text) if !is_raw_identifier(text) => Name::new_ref(text),
// Keywords (in the current edition) *can* be used as a name in earlier editions of
// Rust, e.g. "try" in Rust 2015. Even in such cases, we keep track of them in their
// escaped form.
None if is_raw_identifier(raw_text) => {
Name::new_text(format_smolstr!("r#{}", raw_text))
Name::new_text(&format_smolstr!("r#{}", raw_text))
}
_ => Name::new_text(raw_text.into()),
_ => Name::new_text(raw_text),
}
}
@ -99,7 +117,7 @@ impl Name {
/// 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.
pub const fn missing() -> Name {
Name::new_static("[missing name]")
Name { symbol: MISSING_NAME, ctx: () }
}
/// Returns true if this is a fake name for things missing in the source code. See
@ -115,41 +133,25 @@ impl Name {
/// creating desugared locals and labels. The caller is responsible for picking an index
/// that is stable across re-executions
pub fn generate_new_name(idx: usize) -> Name {
Name::new_text(format_smolstr!("<ra@gennew>{idx}"))
Name::new_text(&format_smolstr!("<ra@gennew>{idx}"))
}
/// Returns the tuple index this name represents if it is a tuple field.
pub fn as_tuple_index(&self) -> Option<usize> {
match self.0 {
Repr::TupleField(idx) => Some(idx),
_ => None,
}
self.symbol.as_str().parse().ok()
}
/// Returns the text this name represents if it isn't a tuple field.
pub fn as_text(&self) -> Option<SmolStr> {
match &self.0 {
Repr::Text(it) => Some(it.clone()),
_ => None,
}
}
/// Returns the text this name represents if it isn't a tuple field.
pub fn as_str(&self) -> Option<&str> {
match &self.0 {
Repr::Text(it) => Some(it),
_ => None,
}
pub fn as_str(&self) -> &str {
self.symbol.as_str()
}
// FIXME: Remove this
/// Returns the textual representation of this name as a [`SmolStr`].
/// Prefer using this over [`ToString::to_string`] if possible as this conversion is cheaper in
/// the general case.
pub fn to_smol_str(&self) -> SmolStr {
match &self.0 {
Repr::Text(it) => it.clone(),
Repr::TupleField(it) => SmolStr::new(it.to_string()),
}
self.symbol.as_str().into()
}
pub fn unescaped(&self) -> UnescapedName<'_> {
@ -157,16 +159,27 @@ impl Name {
}
pub fn is_escaped(&self) -> bool {
match &self.0 {
Repr::Text(it) => it.starts_with("r#"),
Repr::TupleField(_) => false,
}
self.symbol.as_str().starts_with("r#")
}
pub fn display<'a>(&'a self, db: &dyn crate::db::ExpandDatabase) -> impl fmt::Display + 'a {
_ = db;
Display { name: self }
}
pub fn symbol(&self) -> &Symbol {
&self.symbol
}
pub const fn new_symbol(doc: Symbol, ctx: SyntaxContextId) -> Self {
_ = ctx;
Self { symbol: doc, ctx: () }
}
// FIXME: This needs to go once we have hygiene
pub const fn new_symbol_root(doc: Symbol) -> Self {
Self { symbol: doc, ctx: () }
}
}
struct Display<'a> {
@ -175,10 +188,7 @@ struct Display<'a> {
impl fmt::Display for Display<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.name.0 {
Repr::Text(text) => fmt::Display::fmt(&text, f),
Repr::TupleField(idx) => fmt::Display::fmt(&idx, f),
}
fmt::Display::fmt(self.name.symbol.as_str(), f)
}
}
@ -188,13 +198,9 @@ struct UnescapedDisplay<'a> {
impl fmt::Display for UnescapedDisplay<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.name.0 .0 {
Repr::Text(text) => {
let text = text.strip_prefix("r#").unwrap_or(text);
fmt::Display::fmt(&text, f)
}
Repr::TupleField(idx) => fmt::Display::fmt(&idx, f),
}
let symbol = &self.name.0.symbol.as_str();
let text = symbol.strip_prefix("r#").unwrap_or(symbol);
fmt::Display::fmt(&text, f)
}
}
@ -246,251 +252,6 @@ impl AsName for ast::FieldKind {
impl AsName for base_db::Dependency {
fn as_name(&self) -> Name {
Name::new_text(SmolStr::new(&*self.name))
Name::new_text(&self.name)
}
}
pub mod known {
macro_rules! known_names {
($($ident:ident),* $(,)?) => {
$(
#[allow(bad_style)]
pub const $ident: super::Name =
super::Name::new_static(stringify!($ident));
)*
};
}
known_names!(
// Primitives
isize,
i8,
i16,
i32,
i64,
i128,
usize,
u8,
u16,
u32,
u64,
u128,
f16,
f32,
f64,
f128,
bool,
char,
str,
// Special names
macro_rules,
doc,
cfg,
cfg_attr,
register_attr,
register_tool,
// Components of known path (value or mod name)
std,
core,
alloc,
iter,
ops,
fmt,
future,
result,
string,
boxed,
option,
prelude,
rust_2015,
rust_2018,
rust_2021,
rust_2024,
v1,
new_display,
new_debug,
new_lower_exp,
new_upper_exp,
new_octal,
new_pointer,
new_binary,
new_lower_hex,
new_upper_hex,
from_usize,
panic_2015,
panic_2021,
unreachable_2015,
unreachable_2021,
// Components of known path (type name)
Iterator,
IntoIterator,
Item,
IntoIter,
Try,
Ok,
Future,
IntoFuture,
Result,
Option,
Output,
Target,
Box,
RangeFrom,
RangeFull,
RangeInclusive,
RangeToInclusive,
RangeTo,
Range,
String,
Neg,
Not,
None,
Index,
Left,
Right,
Center,
Unknown,
Is,
Param,
Implied,
// Components of known path (function name)
filter_map,
next,
iter_mut,
len,
is_empty,
as_str,
new,
new_v1_formatted,
none,
// Builtin macros
asm,
assert,
column,
compile_error,
concat_idents,
concat_bytes,
concat,
const_format_args,
core_panic,
env,
file,
format,
format_args_nl,
format_args,
global_asm,
include_bytes,
include_str,
include,
line,
llvm_asm,
log_syntax,
module_path,
option_env,
quote,
std_panic,
stringify,
trace_macros,
unreachable,
// Builtin derives
Copy,
Clone,
Default,
Debug,
Hash,
Ord,
PartialOrd,
Eq,
PartialEq,
// Builtin attributes
bench,
cfg_accessible,
cfg_eval,
crate_type,
derive,
derive_const,
global_allocator,
no_core,
no_std,
test,
test_case,
recursion_limit,
feature,
// known methods of lang items
call_once,
call_mut,
call,
eq,
ne,
ge,
gt,
le,
lt,
// known fields of lang items
pieces,
// lang items
add_assign,
add,
bitand_assign,
bitand,
bitor_assign,
bitor,
bitxor_assign,
bitxor,
branch,
deref_mut,
deref,
div_assign,
div,
drop,
fn_mut,
fn_once,
future_trait,
index,
index_mut,
into_future,
mul_assign,
mul,
neg,
not,
owned_box,
partial_ord,
poll,
r#fn,
rem_assign,
rem,
shl_assign,
shl,
shr_assign,
shr,
sub_assign,
sub,
unsafe_cell,
va_list
);
// self/Self cannot be used as an identifier
pub const SELF_PARAM: super::Name = super::Name::new_static("self");
pub const SELF_TYPE: super::Name = super::Name::new_static("Self");
pub const STATIC_LIFETIME: super::Name = super::Name::new_static("'static");
pub const DOLLAR_CRATE: super::Name = super::Name::new_static("$crate");
#[macro_export]
macro_rules! name {
(self) => {
$crate::name::known::SELF_PARAM
};
(Self) => {
$crate::name::known::SELF_TYPE
};
('static) => {
$crate::name::known::STATIC_LIFETIME
};
($ident:ident) => {
$crate::name::known::$ident
};
}
}
pub use crate::name;

View file

@ -1,6 +1,7 @@
//! A simplified version of quote-crate like quasi quote macro
#![allow(clippy::crate_in_macro_def)]
use intern::Symbol;
use span::Span;
use syntax::format_smolstr;
@ -219,6 +220,7 @@ impl_to_to_tokentrees! {
span: &str => self { crate::tt::Literal{text: format_smolstr!("\"{}\"", self.escape_default()), span}};
span: String => self { crate::tt::Literal{text: format_smolstr!("\"{}\"", self.escape_default()), span}};
span: Name => self { crate::tt::Ident{text: self.to_smol_str(), span}};
span: Symbol => self { crate::tt::Ident{text: self.as_str().into(), span}};
}
#[cfg(test)]

View file

@ -5,7 +5,8 @@
use chalk_ir::cast::Cast;
use hir_def::lang_item::LangItem;
use hir_expand::name::name;
use hir_expand::name::Name;
use intern::sym;
use limit::Limit;
use triomphe::Arc;
@ -151,7 +152,8 @@ pub(crate) fn deref_by_trait(
let deref_trait =
db.lang_item(table.trait_env.krate, LangItem::Deref).and_then(|l| l.as_trait())?;
let target = db.trait_data(deref_trait).associated_type_by_name(&name![Target])?;
let target =
db.trait_data(deref_trait).associated_type_by_name(&Name::new_symbol_root(sym::Target))?;
let projection = {
let b = TyBuilder::subst_for_def(db, deref_trait, None);

View file

@ -3,6 +3,8 @@
use core::ops;
use std::{iter, ops::ControlFlow, sync::Arc};
use hir_expand::name::Name;
use intern::sym;
use tracing::debug;
use chalk_ir::{cast::Caster, fold::shift::Shift, CanonicalVarKinds};
@ -16,7 +18,6 @@ use hir_def::{
AssocItemId, BlockId, CallableDefId, GenericDefId, HasModule, ItemContainerId, Lookup,
TypeAliasId, VariantId,
};
use hir_expand::name::name;
use crate::{
db::{HirDatabase, InternedCoroutine},
@ -293,8 +294,10 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
.lang_item(self.krate, LangItem::Future)
.and_then(|item| item.as_trait())
.and_then(|trait_| {
let alias =
self.db.trait_data(trait_).associated_type_by_name(&name![Output])?;
let alias = self
.db
.trait_data(trait_)
.associated_type_by_name(&Name::new_symbol_root(sym::Output))?;
Some((trait_, alias))
})
{

View file

@ -247,7 +247,7 @@ impl<'a> DeclValidator<'a> {
// Check the module name.
let Some(module_name) = module_id.name(self.db.upcast()) else { return };
let Some(module_name_replacement) =
module_name.as_str().and_then(to_lower_snake_case).map(|new_name| Replacement {
to_lower_snake_case(module_name.as_str()).map(|new_name| Replacement {
current_name: module_name,
suggested_text: new_name,
expected_case: CaseType::LowerSnakeCase,

View file

@ -8,7 +8,7 @@ use either::Either;
use hir_def::lang_item::LangItem;
use hir_def::{resolver::HasResolver, AdtId, AssocItemId, DefWithBodyId, HasModule};
use hir_def::{ItemContainerId, Lookup};
use hir_expand::name;
use intern::sym;
use itertools::Itertools;
use rustc_hash::FxHashSet;
use rustc_pattern_analysis::constructor::Constructor;
@ -423,7 +423,7 @@ impl FilterMapNextChecker {
ItemContainerId::TraitId(iterator_trait_id) => {
let iterator_trait_items = &db.trait_data(iterator_trait_id).items;
iterator_trait_items.iter().find_map(|(name, it)| match it {
&AssocItemId::FunctionId(id) if *name == name![filter_map] => Some(id),
&AssocItemId::FunctionId(id) if *name == sym::filter_map => Some(id),
_ => None,
})
}

View file

@ -25,7 +25,7 @@ use hir_def::{
ModuleId, TraitId,
};
use hir_expand::name::Name;
use intern::{Internable, Interned};
use intern::{sym, Internable, Interned};
use itertools::Itertools;
use la_arena::ArenaMap;
use rustc_apfloat::{
@ -1171,7 +1171,8 @@ impl HirDisplay for Ty {
.lang_item(body.module(db.upcast()).krate(), LangItem::Future)
.and_then(LangItemTarget::as_trait);
let output = future_trait.and_then(|t| {
db.trait_data(t).associated_type_by_name(&hir_expand::name!(Output))
db.trait_data(t)
.associated_type_by_name(&Name::new_symbol_root(sym::Output))
});
write!(f, "impl ")?;
if let Some(t) = future_trait {

View file

@ -46,8 +46,9 @@ use hir_def::{
AdtId, AssocItemId, DefWithBodyId, FieldId, FunctionId, ItemContainerId, Lookup, TraitId,
TupleFieldId, TupleId, TypeAliasId, VariantId,
};
use hir_expand::name::{name, Name};
use hir_expand::name::Name;
use indexmap::IndexSet;
use intern::sym;
use la_arena::{ArenaMap, Entry};
use once_cell::unsync::OnceCell;
use rustc_hash::{FxHashMap, FxHashSet};
@ -1424,7 +1425,7 @@ impl<'a> InferenceContext<'a> {
}
fn resolve_output_on(&self, trait_: TraitId) -> Option<TypeAliasId> {
self.db.trait_data(trait_).associated_type_by_name(&name![Output])
self.db.trait_data(trait_).associated_type_by_name(&Name::new_symbol_root(sym::Output))
}
fn resolve_lang_trait(&self, lang: LangItem) -> Option<TraitId> {

View file

@ -15,7 +15,8 @@ use hir_def::{
resolver::{resolver_for_expr, ResolveValueResult, ValueNs},
DefWithBodyId, FieldId, HasModule, TupleFieldId, TupleId, VariantId,
};
use hir_expand::name;
use hir_expand::name::Name;
use intern::sym;
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
use stdx::never;
@ -268,9 +269,7 @@ impl CapturedItem {
}
let variant_data = f.parent.variant_data(db.upcast());
let field = match &*variant_data {
VariantData::Record(fields) => {
fields[f.local_id].name.as_str().unwrap_or("[missing field]").to_owned()
}
VariantData::Record(fields) => fields[f.local_id].name.as_str().to_owned(),
VariantData::Tuple(fields) => fields
.iter()
.position(|it| it.0 == f.local_id)
@ -621,8 +620,10 @@ impl InferenceContext<'_> {
if let Some(deref_trait) =
self.resolve_lang_item(LangItem::DerefMut).and_then(|it| it.as_trait())
{
if let Some(deref_fn) =
self.db.trait_data(deref_trait).method_by_name(&name![deref_mut])
if let Some(deref_fn) = self
.db
.trait_data(deref_trait)
.method_by_name(&Name::new_symbol_root(sym::deref_mut))
{
break 'b deref_fn == f;
}

View file

@ -15,7 +15,8 @@ use hir_def::{
path::{GenericArgs, Path},
BlockId, FieldId, GenericDefId, GenericParamId, ItemContainerId, Lookup, TupleFieldId, TupleId,
};
use hir_expand::name::{name, Name};
use hir_expand::name::Name;
use intern::sym;
use stdx::always;
use syntax::ast::RangeOp;
@ -646,8 +647,10 @@ impl InferenceContext<'_> {
match op {
UnaryOp::Deref => {
if let Some(deref_trait) = self.resolve_lang_trait(LangItem::Deref) {
if let Some(deref_fn) =
self.db.trait_data(deref_trait).method_by_name(&name![deref])
if let Some(deref_fn) = self
.db
.trait_data(deref_trait)
.method_by_name(&Name::new_symbol_root(sym::deref))
{
// FIXME: this is wrong in multiple ways, subst is empty, and we emit it even for builtin deref (note that
// the mutability is not wrong, and will be fixed in `self.infer_mut`).
@ -785,8 +788,10 @@ impl InferenceContext<'_> {
// mutability will be fixed up in `InferenceContext::infer_mut`;
adj.push(Adjustment::borrow(Mutability::Not, self_ty.clone()));
self.write_expr_adj(*base, adj);
if let Some(func) =
self.db.trait_data(index_trait).method_by_name(&name!(index))
if let Some(func) = self
.db
.trait_data(index_trait)
.method_by_name(&Name::new_symbol_root(sym::index))
{
let substs = TyBuilder::subst_for_def(self.db, index_trait, None)
.push(self_ty.clone())

View file

@ -6,7 +6,8 @@ use hir_def::{
hir::{Array, BinaryOp, BindingAnnotation, Expr, ExprId, PatId, Statement, UnaryOp},
lang_item::LangItem,
};
use hir_expand::name;
use hir_expand::name::Name;
use intern::sym;
use crate::{lower::lower_to_chalk_mutability, Adjust, Adjustment, AutoBorrow, OverloadedDeref};
@ -108,8 +109,10 @@ impl InferenceContext<'_> {
.lang_item(self.table.trait_env.krate, LangItem::IndexMut)
.and_then(|l| l.as_trait())
{
if let Some(index_fn) =
self.db.trait_data(index_trait).method_by_name(&name![index_mut])
if let Some(index_fn) = self
.db
.trait_data(index_trait)
.method_by_name(&Name::new_symbol_root(sym::index_mut))
{
*f = index_fn;
let base_adjustments = self
@ -139,8 +142,10 @@ impl InferenceContext<'_> {
.lang_item(self.table.trait_env.krate, LangItem::DerefMut)
.and_then(|l| l.as_trait())
{
if let Some(deref_fn) =
self.db.trait_data(deref_trait).method_by_name(&name![deref_mut])
if let Some(deref_fn) = self
.db
.trait_data(deref_trait)
.method_by_name(&Name::new_symbol_root(sym::deref_mut))
{
*f = deref_fn;
}

View file

@ -7,6 +7,7 @@ use hir_def::{
AdtId, AssocItemId, GenericDefId, ItemContainerId, Lookup,
};
use hir_expand::name::Name;
use intern::sym;
use stdx::never;
use crate::{
@ -227,7 +228,7 @@ impl InferenceContext<'_> {
Path::LangItem(..) => (
PathSegment {
name: {
_d = hir_expand::name::known::Unknown;
_d = Name::new_symbol_root(sym::Unknown);
&_d
},
args_and_bindings: None,

View file

@ -9,7 +9,8 @@ use chalk_ir::{
use chalk_solve::infer::ParameterEnaVariableExt;
use either::Either;
use ena::unify::UnifyKey;
use hir_expand::name;
use hir_expand::name::Name;
use intern::sym;
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
use triomphe::Arc;
@ -781,7 +782,8 @@ impl<'a> InferenceTable<'a> {
let krate = self.trait_env.krate;
let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?;
let trait_data = self.db.trait_data(fn_once_trait);
let output_assoc_type = trait_data.associated_type_by_name(&name![Output])?;
let output_assoc_type =
trait_data.associated_type_by_name(&Name::new_symbol_root(sym::Output))?;
let mut arg_tys = Vec::with_capacity(num_args);
let arg_ty = TyBuilder::tuple(num_args)

View file

@ -2,6 +2,7 @@
use hir_def::{data::adt::StructFlags, lang_item::LangItem, AdtId};
use hir_expand::name::Name;
use intern::sym;
use crate::db::HirDatabase;
@ -16,48 +17,47 @@ pub fn is_unsafe_cell(db: &dyn HirDatabase, adt: AdtId) -> bool {
}
pub fn lang_items_for_bin_op(op: syntax::ast::BinaryOp) -> Option<(Name, LangItem)> {
use hir_expand::name;
use syntax::ast::{ArithOp, BinaryOp, CmpOp, Ordering};
Some(match op {
BinaryOp::LogicOp(_) => return None,
BinaryOp::ArithOp(aop) => match aop {
ArithOp::Add => (name![add], LangItem::Add),
ArithOp::Mul => (name![mul], LangItem::Mul),
ArithOp::Sub => (name![sub], LangItem::Sub),
ArithOp::Div => (name![div], LangItem::Div),
ArithOp::Rem => (name![rem], LangItem::Rem),
ArithOp::Shl => (name![shl], LangItem::Shl),
ArithOp::Shr => (name![shr], LangItem::Shr),
ArithOp::BitXor => (name![bitxor], LangItem::BitXor),
ArithOp::BitOr => (name![bitor], LangItem::BitOr),
ArithOp::BitAnd => (name![bitand], LangItem::BitAnd),
ArithOp::Add => (Name::new_symbol_root(sym::add), LangItem::Add),
ArithOp::Mul => (Name::new_symbol_root(sym::mul), LangItem::Mul),
ArithOp::Sub => (Name::new_symbol_root(sym::sub), LangItem::Sub),
ArithOp::Div => (Name::new_symbol_root(sym::div), LangItem::Div),
ArithOp::Rem => (Name::new_symbol_root(sym::rem), LangItem::Rem),
ArithOp::Shl => (Name::new_symbol_root(sym::shl), LangItem::Shl),
ArithOp::Shr => (Name::new_symbol_root(sym::shr), LangItem::Shr),
ArithOp::BitXor => (Name::new_symbol_root(sym::bitxor), LangItem::BitXor),
ArithOp::BitOr => (Name::new_symbol_root(sym::bitor), LangItem::BitOr),
ArithOp::BitAnd => (Name::new_symbol_root(sym::bitand), LangItem::BitAnd),
},
BinaryOp::Assignment { op: Some(aop) } => match aop {
ArithOp::Add => (name![add_assign], LangItem::AddAssign),
ArithOp::Mul => (name![mul_assign], LangItem::MulAssign),
ArithOp::Sub => (name![sub_assign], LangItem::SubAssign),
ArithOp::Div => (name![div_assign], LangItem::DivAssign),
ArithOp::Rem => (name![rem_assign], LangItem::RemAssign),
ArithOp::Shl => (name![shl_assign], LangItem::ShlAssign),
ArithOp::Shr => (name![shr_assign], LangItem::ShrAssign),
ArithOp::BitXor => (name![bitxor_assign], LangItem::BitXorAssign),
ArithOp::BitOr => (name![bitor_assign], LangItem::BitOrAssign),
ArithOp::BitAnd => (name![bitand_assign], LangItem::BitAndAssign),
ArithOp::Add => (Name::new_symbol_root(sym::add_assign), LangItem::AddAssign),
ArithOp::Mul => (Name::new_symbol_root(sym::mul_assign), LangItem::MulAssign),
ArithOp::Sub => (Name::new_symbol_root(sym::sub_assign), LangItem::SubAssign),
ArithOp::Div => (Name::new_symbol_root(sym::div_assign), LangItem::DivAssign),
ArithOp::Rem => (Name::new_symbol_root(sym::rem_assign), LangItem::RemAssign),
ArithOp::Shl => (Name::new_symbol_root(sym::shl_assign), LangItem::ShlAssign),
ArithOp::Shr => (Name::new_symbol_root(sym::shr_assign), LangItem::ShrAssign),
ArithOp::BitXor => (Name::new_symbol_root(sym::bitxor_assign), LangItem::BitXorAssign),
ArithOp::BitOr => (Name::new_symbol_root(sym::bitor_assign), LangItem::BitOrAssign),
ArithOp::BitAnd => (Name::new_symbol_root(sym::bitand_assign), LangItem::BitAndAssign),
},
BinaryOp::CmpOp(cop) => match cop {
CmpOp::Eq { negated: false } => (name![eq], LangItem::PartialEq),
CmpOp::Eq { negated: true } => (name![ne], LangItem::PartialEq),
CmpOp::Eq { negated: false } => (Name::new_symbol_root(sym::eq), LangItem::PartialEq),
CmpOp::Eq { negated: true } => (Name::new_symbol_root(sym::ne), LangItem::PartialEq),
CmpOp::Ord { ordering: Ordering::Less, strict: false } => {
(name![le], LangItem::PartialOrd)
(Name::new_symbol_root(sym::le), LangItem::PartialOrd)
}
CmpOp::Ord { ordering: Ordering::Less, strict: true } => {
(name![lt], LangItem::PartialOrd)
(Name::new_symbol_root(sym::lt), LangItem::PartialOrd)
}
CmpOp::Ord { ordering: Ordering::Greater, strict: false } => {
(name![ge], LangItem::PartialOrd)
(Name::new_symbol_root(sym::ge), LangItem::PartialOrd)
}
CmpOp::Ord { ordering: Ordering::Greater, strict: true } => {
(name![gt], LangItem::PartialOrd)
(Name::new_symbol_root(sym::gt), LangItem::PartialOrd)
}
},
BinaryOp::Assignment { op: None } => return None,

View file

@ -61,7 +61,8 @@ use chalk_ir::{
};
use either::Either;
use hir_def::{hir::ExprId, type_ref::Rawness, CallableDefId, GeneralConstId, TypeOrConstParamId};
use hir_expand::name;
use hir_expand::name::Name;
use intern::sym;
use la_arena::{Arena, Idx};
use mir::{MirEvalError, VTableMap};
use rustc_hash::{FxHashMap, FxHashSet};
@ -894,7 +895,9 @@ pub fn callable_sig_from_fn_trait(
) -> Option<(FnTrait, CallableSig)> {
let krate = trait_env.krate;
let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?;
let output_assoc_type = db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?;
let output_assoc_type = db
.trait_data(fn_once_trait)
.associated_type_by_name(&Name::new_symbol_root(sym::Output))?;
let mut table = InferenceTable::new(db, trait_env.clone());
let b = TyBuilder::trait_ref(db, fn_once_trait);

View file

@ -14,8 +14,8 @@ use hir_def::{
AdtId, ConstId, DefWithBodyId, EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup,
StaticId, VariantId,
};
use hir_expand::{mod_path::ModPath, HirFileIdExt, InFile};
use intern::Interned;
use hir_expand::{mod_path::path, name::Name, HirFileIdExt, InFile};
use intern::{sym, Interned};
use la_arena::ArenaMap;
use rustc_abi::TargetDataLayout;
use rustc_apfloat::{
@ -35,7 +35,7 @@ use crate::{
layout::{Layout, LayoutError, RustcEnumVariantIdx},
mapping::from_chalk,
method_resolution::{is_dyn_method, lookup_impl_const},
name, static_lifetime,
static_lifetime,
traits::FnTrait,
utils::{detect_variant_from_bytes, ClosureSubst},
CallableDefId, ClosureId, ComplexMemoryMap, Const, ConstScalar, FnDefId, Interner, MemoryMap,
@ -631,15 +631,19 @@ impl Evaluator<'_> {
cached_fn_trait_func: db
.lang_item(crate_id, LangItem::Fn)
.and_then(|x| x.as_trait())
.and_then(|x| db.trait_data(x).method_by_name(&name![call])),
.and_then(|x| db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call))),
cached_fn_mut_trait_func: db
.lang_item(crate_id, LangItem::FnMut)
.and_then(|x| x.as_trait())
.and_then(|x| db.trait_data(x).method_by_name(&name![call_mut])),
.and_then(|x| {
db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call_mut))
}),
cached_fn_once_trait_func: db
.lang_item(crate_id, LangItem::FnOnce)
.and_then(|x| x.as_trait())
.and_then(|x| db.trait_data(x).method_by_name(&name![call_once])),
.and_then(|x| {
db.trait_data(x).method_by_name(&Name::new_symbol_root(sym::call_once))
}),
})
}
@ -2633,10 +2637,7 @@ impl Evaluator<'_> {
let static_data = self.db.static_data(st);
let result = if !static_data.is_extern {
let konst = self.db.const_eval_static(st).map_err(|e| {
MirEvalError::ConstEvalError(
static_data.name.as_str().unwrap_or("_").to_owned(),
Box::new(e),
)
MirEvalError::ConstEvalError(static_data.name.as_str().to_owned(), Box::new(e))
})?;
self.allocate_const_in_heap(locals, &konst)?
} else {
@ -2693,7 +2694,7 @@ impl Evaluator<'_> {
) -> Result<()> {
let Some(drop_fn) = (|| {
let drop_trait = self.db.lang_item(self.crate_id, LangItem::Drop)?.as_trait()?;
self.db.trait_data(drop_trait).method_by_name(&name![drop])
self.db.trait_data(drop_trait).method_by_name(&Name::new_symbol_root(sym::drop))
})() else {
// in some tests we don't have drop trait in minicore, and
// we can ignore drop in them.
@ -2797,14 +2798,13 @@ pub fn render_const_using_debug_impl(
let resolver = owner.resolver(db.upcast());
let Some(TypeNs::TraitId(debug_trait)) = resolver.resolve_path_in_type_ns_fully(
db.upcast(),
&hir_def::path::Path::from_known_path_with_no_generic(ModPath::from_segments(
hir_expand::mod_path::PathKind::Abs,
[name![core], name![fmt], name![Debug]],
)),
&hir_def::path::Path::from_known_path_with_no_generic(path![core::fmt::Debug]),
) else {
not_supported!("core::fmt::Debug not found");
};
let Some(debug_fmt_fn) = db.trait_data(debug_trait).method_by_name(&name![fmt]) else {
let Some(debug_fmt_fn) =
db.trait_data(debug_trait).method_by_name(&Name::new_symbol_root(sym::fmt))
else {
not_supported!("core::fmt::Debug::fmt not found");
};
// a1 = &[""]
@ -2829,10 +2829,7 @@ pub fn render_const_using_debug_impl(
evaluator.write_memory(a3.offset(5 * evaluator.ptr_size()), &[1])?;
let Some(ValueNs::FunctionId(format_fn)) = resolver.resolve_path_in_value_ns_fully(
db.upcast(),
&hir_def::path::Path::from_known_path_with_no_generic(ModPath::from_segments(
hir_expand::mod_path::PathKind::Abs,
[name![std], name![fmt], name![format]],
)),
&hir_def::path::Path::from_known_path_with_no_generic(path![std::fmt::format]),
) else {
not_supported!("std::fmt::format not found");
};

View file

@ -8,12 +8,14 @@ use hir_def::{
builtin_type::{BuiltinInt, BuiltinUint},
resolver::HasResolver,
};
use hir_expand::name::Name;
use intern::sym;
use crate::{
error_lifetime,
mir::eval::{
name, pad16, Address, AdtId, Arc, BuiltinType, Evaluator, FunctionId, HasModule,
HirDisplay, Interned, InternedClosure, Interner, Interval, IntervalAndTy, IntervalOrOwned,
pad16, Address, AdtId, Arc, BuiltinType, Evaluator, FunctionId, HasModule, HirDisplay,
Interned, InternedClosure, Interner, Interval, IntervalAndTy, IntervalOrOwned,
ItemContainerId, LangItem, Layout, Locals, Lookup, MirEvalError, MirSpan, Mutability,
Result, Substitution, Ty, TyBuilder, TyExt,
},
@ -64,7 +66,7 @@ impl Evaluator<'_> {
};
if is_intrinsic {
self.exec_intrinsic(
function_data.name.as_text().unwrap_or_default().as_str(),
function_data.name.as_str(),
args,
generic_args,
destination,
@ -86,7 +88,7 @@ impl Evaluator<'_> {
};
if is_platform_intrinsic {
self.exec_platform_intrinsic(
function_data.name.as_text().unwrap_or_default().as_str(),
function_data.name.as_str(),
args,
generic_args,
destination,
@ -104,7 +106,7 @@ impl Evaluator<'_> {
};
if is_extern_c {
self.exec_extern_c(
function_data.name.as_text().unwrap_or_default().as_str(),
function_data.name.as_str(),
args,
generic_args,
destination,
@ -117,7 +119,7 @@ impl Evaluator<'_> {
.attrs
.iter()
.filter_map(|it| it.path().as_ident())
.filter_map(|it| it.as_str())
.map(|it| it.as_str())
.find(|it| {
[
"rustc_allocator",
@ -1274,10 +1276,11 @@ impl Evaluator<'_> {
args.push(IntervalAndTy::new(addr, field, self, locals)?);
}
if let Some(target) = self.db.lang_item(self.crate_id, LangItem::FnOnce) {
if let Some(def) = target
.as_trait()
.and_then(|it| self.db.trait_data(it).method_by_name(&name![call_once]))
{
if let Some(def) = target.as_trait().and_then(|it| {
self.db
.trait_data(it)
.method_by_name(&Name::new_symbol_root(sym::call_once))
}) {
self.exec_fn_trait(
def,
&args,

View file

@ -1113,9 +1113,9 @@ impl<'ctx> MirLowerCtx<'ctx> {
.iter()
.map(|it| {
let o = match it.1.name.as_str() {
Some("start") => lp.take(),
Some("end") => rp.take(),
Some("exhausted") => {
"start" => lp.take(),
"end" => rp.take(),
"exhausted" => {
Some(Operand::from_bytes(Box::new([0]), TyBuilder::bool()))
}
_ => None,

View file

@ -4,7 +4,7 @@ use crate::mir::MutBorrowKind;
use super::*;
use hir_def::FunctionId;
use hir_expand::name;
use intern::sym;
macro_rules! not_supported {
($it: expr) => {
@ -192,7 +192,7 @@ impl MirLowerCtx<'_> {
if let Some(deref_fn) = self
.db
.trait_data(deref_trait)
.method_by_name(&name![deref_mut])
.method_by_name(&Name::new_symbol_root(sym::deref_mut))
{
break 'b deref_fn == f;
}
@ -324,12 +324,17 @@ impl MirLowerCtx<'_> {
mutability: bool,
) -> Result<Option<(Place, BasicBlockId)>> {
let (chalk_mut, trait_lang_item, trait_method_name, borrow_kind) = if !mutability {
(Mutability::Not, LangItem::Deref, name![deref], BorrowKind::Shared)
(
Mutability::Not,
LangItem::Deref,
Name::new_symbol_root(sym::deref),
BorrowKind::Shared,
)
} else {
(
Mutability::Mut,
LangItem::DerefMut,
name![deref_mut],
Name::new_symbol_root(sym::deref_mut),
BorrowKind::Mut { kind: MutBorrowKind::Default },
)
};

View file

@ -12,7 +12,8 @@ use hir_def::{
lang_item::{LangItem, LangItemTarget},
BlockId, TraitId,
};
use hir_expand::name::{name, Name};
use hir_expand::name::Name;
use intern::sym;
use stdx::panic_context;
use triomphe::Arc;
@ -256,9 +257,9 @@ impl FnTrait {
pub fn method_name(self) -> Name {
match self {
FnTrait::FnOnce => name!(call_once),
FnTrait::FnMut => name!(call_mut),
FnTrait::Fn => name!(call),
FnTrait::FnOnce => Name::new_symbol_root(sym::call_once),
FnTrait::FnMut => Name::new_symbol_root(sym::call_mut),
FnTrait::Fn => Name::new_symbol_root(sym::call),
}
}

View file

@ -12,6 +12,7 @@ use hir_def::{
};
use hir_expand::{mod_path::PathKind, name::Name};
use hir_ty::{db::HirDatabase, method_resolution};
use span::SyntaxContextId;
use crate::{
Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, DocLinkDef, Enum, ExternCrateDecl,
@ -328,7 +329,7 @@ fn doc_modpath_from_str(link: &str) -> Option<ModPath> {
let parts = first_segment.into_iter().chain(parts).map(|segment| match segment.parse() {
Ok(idx) => Name::new_tuple_field(idx),
Err(_) => {
Name::new_text_dont_use(segment.split_once('<').map_or(segment, |it| it.0).into())
Name::new(segment.split_once('<').map_or(segment, |it| it.0), SyntaxContextId::ROOT)
}
});
Some(ModPath::from_segments(kind, parts))

View file

@ -58,7 +58,7 @@ use hir_def::{
TypeOrConstParamId, TypeParamId, UnionId,
};
use hir_expand::{
attrs::collect_attrs, name::name, proc_macro::ProcMacroKind, AstId, MacroCallKind, ValueResult,
attrs::collect_attrs, proc_macro::ProcMacroKind, AstId, MacroCallKind, ValueResult,
};
use hir_ty::{
all_super_traits, autoderef, check_orphan_rules,
@ -131,7 +131,7 @@ pub use {
change::ChangeWithProcMacros,
hygiene::{marks_rev, SyntaxContextExt},
inert_attr_macro::AttributeTemplate,
name::{known, Name},
name::Name,
proc_macro::ProcMacros,
tt, ExpandResult, HirFileId, HirFileIdExt, InFile, InMacroFile, InRealFile, MacroFileId,
MacroFileIdExt,
@ -145,6 +145,7 @@ pub use {
},
// FIXME: Properly encapsulate mir
hir_ty::{mir, Interner as ChalkTyInterner},
intern::{sym, Symbol},
};
// These are negative re-exports: pub using these names is forbidden, they
@ -1826,7 +1827,7 @@ impl DefWithBody {
continue;
}
let mut need_mut = &mol[local];
if body[binding_id].name.as_str() == Some("self")
if body[binding_id].name == sym::self_
&& need_mut == &mir::MutabilityReason::Unused
{
need_mut = &mir::MutabilityReason::Not;
@ -1836,7 +1837,7 @@ impl DefWithBody {
match (need_mut, is_mut) {
(mir::MutabilityReason::Unused, _) => {
let should_ignore = matches!(body[binding_id].name.as_str(), Some(it) if it.starts_with('_'));
let should_ignore = body[binding_id].name.as_str().starts_with('_');
if !should_ignore {
acc.push(UnusedVariable { local }.into())
}
@ -1866,7 +1867,7 @@ impl DefWithBody {
}
(mir::MutabilityReason::Not, true) => {
if !infer.mutated_bindings_in_closure.contains(&binding_id) {
let should_ignore = matches!(body[binding_id].name.as_str(), Some(it) if it.starts_with('_'));
let should_ignore = body[binding_id].name.as_str().starts_with('_');
if !should_ignore {
acc.push(UnusedMut { local }.into())
}
@ -2588,7 +2589,7 @@ pub struct StaticLifetime;
impl StaticLifetime {
pub fn name(self) -> Name {
known::STATIC_LIFETIME
Name::new_symbol_root(sym::tick_static)
}
}
@ -3248,7 +3249,7 @@ impl Local {
}
pub fn is_self(self, db: &dyn HirDatabase) -> bool {
self.name(db) == name![self]
self.name(db) == sym::self_
}
pub fn is_mut(self, db: &dyn HirDatabase) -> bool {

View file

@ -25,11 +25,8 @@ use hir_def::{
};
use hir_expand::{
mod_path::path,
name::{AsName, Name},
HirFileId, InFile, InMacroFile, MacroFileId, MacroFileIdExt,
{
name,
name::{AsName, Name},
},
};
use hir_ty::{
diagnostics::{
@ -40,6 +37,7 @@ use hir_ty::{
method_resolution, Adjustment, InferenceResult, Interner, Substitution, Ty, TyExt, TyKind,
TyLoweringContext,
};
use intern::sym;
use itertools::Itertools;
use smallvec::SmallVec;
use syntax::{
@ -368,7 +366,7 @@ impl SourceAnalyzer {
let items = into_future_trait.items(db);
let into_future_type = items.into_iter().find_map(|item| match item {
AssocItem::TypeAlias(alias)
if alias.name(db) == hir_expand::name![IntoFuture] =>
if alias.name(db) == Name::new_symbol_root(sym::IntoFuture) =>
{
Some(alias)
}
@ -398,14 +396,17 @@ impl SourceAnalyzer {
// Since deref kind is inferenced and stored in `InferenceResult.method_resolution`,
// use that result to find out which one it is.
let (deref_trait, deref) =
self.lang_trait_fn(db, LangItem::Deref, &name![deref])?;
self.lang_trait_fn(db, LangItem::Deref, &Name::new_symbol_root(sym::deref))?;
self.infer
.as_ref()
.and_then(|infer| {
let expr = self.expr_id(db, &prefix_expr.clone().into())?;
let (func, _) = infer.method_resolution(expr)?;
let (deref_mut_trait, deref_mut) =
self.lang_trait_fn(db, LangItem::DerefMut, &name![deref_mut])?;
let (deref_mut_trait, deref_mut) = self.lang_trait_fn(
db,
LangItem::DerefMut,
&Name::new_symbol_root(sym::deref_mut),
)?;
if func == deref_mut {
Some((deref_mut_trait, deref_mut))
} else {
@ -414,8 +415,12 @@ impl SourceAnalyzer {
})
.unwrap_or((deref_trait, deref))
}
ast::UnaryOp::Not => self.lang_trait_fn(db, LangItem::Not, &name![not])?,
ast::UnaryOp::Neg => self.lang_trait_fn(db, LangItem::Neg, &name![neg])?,
ast::UnaryOp::Not => {
self.lang_trait_fn(db, LangItem::Not, &Name::new_symbol_root(sym::not))?
}
ast::UnaryOp::Neg => {
self.lang_trait_fn(db, LangItem::Neg, &Name::new_symbol_root(sym::neg))?
}
};
let ty = self.ty_of_expr(db, &prefix_expr.expr()?)?;
@ -435,15 +440,19 @@ impl SourceAnalyzer {
let base_ty = self.ty_of_expr(db, &index_expr.base()?)?;
let index_ty = self.ty_of_expr(db, &index_expr.index()?)?;
let (index_trait, index_fn) = self.lang_trait_fn(db, LangItem::Index, &name![index])?;
let (index_trait, index_fn) =
self.lang_trait_fn(db, LangItem::Index, &Name::new_symbol_root(sym::index))?;
let (op_trait, op_fn) = self
.infer
.as_ref()
.and_then(|infer| {
let expr = self.expr_id(db, &index_expr.clone().into())?;
let (func, _) = infer.method_resolution(expr)?;
let (index_mut_trait, index_mut_fn) =
self.lang_trait_fn(db, LangItem::IndexMut, &name![index_mut])?;
let (index_mut_trait, index_mut_fn) = self.lang_trait_fn(
db,
LangItem::IndexMut,
&Name::new_symbol_root(sym::index_mut),
)?;
if func == index_mut_fn {
Some((index_mut_trait, index_mut_fn))
} else {

View file

@ -239,7 +239,7 @@ impl<'a> SymbolCollector<'a> {
fn collect_from_trait(&mut self, trait_id: TraitId) {
let trait_data = self.db.trait_data(trait_id);
self.with_container_name(trait_data.name.as_text(), |s| {
self.with_container_name(Some(trait_data.name.as_str().into()), |s| {
for &(_, assoc_item_id) in &trait_data.items {
s.push_assoc_item(assoc_item_id);
}

View file

@ -470,7 +470,7 @@ fn add_enum_def(
.module()
.scope(ctx.db(), Some(*target_module))
.iter()
.any(|(name, _)| name.as_str() == Some("Bool"))
.any(|(name, _)| name.as_str() == "Bool")
{
return None;
}

View file

@ -1,4 +1,4 @@
use hir::{known, AsAssocItem, Semantics};
use hir::{sym, AsAssocItem, Semantics};
use ide_db::{
famous_defs::FamousDefs,
syntax_helpers::node_ext::{
@ -223,7 +223,7 @@ fn option_variants(
let fam = FamousDefs(sema, sema.scope(expr)?.krate());
let option_variants = fam.core_option_Option()?.variants(sema.db);
match &*option_variants {
&[variant0, variant1] => Some(if variant0.name(sema.db) == known::None {
&[variant0, variant1] => Some(if variant0.name(sema.db) == sym::None {
(variant0, variant1)
} else {
(variant1, variant0)

View file

@ -1,4 +1,4 @@
use hir::known;
use hir::{sym, Name};
use ide_db::famous_defs::FamousDefs;
use stdx::format_to;
use syntax::{
@ -149,7 +149,11 @@ fn is_ref_and_impls_iter_method(
ast::Expr::RefExpr(r) => r,
_ => return None,
};
let wanted_method = if ref_expr.mut_token().is_some() { known::iter_mut } else { known::iter };
let wanted_method = Name::new_symbol_root(if ref_expr.mut_token().is_some() {
sym::iter_mut
} else {
sym::iter
});
let expr_behind_ref = ref_expr.expr()?;
let ty = sema.type_of_expr(&expr_behind_ref)?.adjusted();
let scope = sema.scope(iterable.syntax())?;

View file

@ -169,8 +169,8 @@ fn get_names_in_scope(
let mut names = FxHashSet::default();
scope.process_all_names(&mut |name, scope| {
if let (Some(name), hir::ScopeDef::Local(_)) = (name.as_text(), scope) {
names.insert(name);
if let hir::ScopeDef::Local(_) = scope {
names.insert(name.as_str().into());
}
});
Some(names)

View file

@ -1,4 +1,4 @@
use hir::{known, HasSource, Name};
use hir::{sym, HasSource, Name};
use syntax::{
ast::{self, HasName},
AstNode,
@ -54,13 +54,13 @@ pub(crate) fn generate_is_empty_from_len(acc: &mut Assists, ctx: &AssistContext<
}
let impl_ = fn_node.syntax().ancestors().find_map(ast::Impl::cast)?;
let len_fn = get_impl_method(ctx, &impl_, &known::len)?;
let len_fn = get_impl_method(ctx, &impl_, &Name::new_symbol_root(sym::len))?;
if !len_fn.ret_type(ctx.sema.db).is_usize() {
cov_mark::hit!(len_fn_different_return_type);
return None;
}
if get_impl_method(ctx, &impl_, &known::is_empty).is_some() {
if get_impl_method(ctx, &impl_, &Name::new_symbol_root(sym::is_empty)).is_some() {
cov_mark::hit!(is_empty_already_implemented);
return None;
}

View file

@ -2,7 +2,7 @@ use std::collections::BTreeSet;
use ast::make;
use either::Either;
use hir::{db::HirDatabase, PathResolution, Semantics, TypeInfo};
use hir::{db::HirDatabase, sym, PathResolution, Semantics, TypeInfo};
use ide_db::{
base_db::{FileId, FileRange},
defs::Definition,
@ -430,10 +430,7 @@ fn inline(
let ty = sema.type_of_expr(expr).filter(TypeInfo::has_adjustment).and(param_ty);
let is_self = param
.name(sema.db)
.and_then(|name| name.as_text())
.is_some_and(|name| name == "self");
let is_self = param.name(sema.db).is_some_and(|name| name == sym::self_);
if is_self {
let mut this_pat = make::ident_pat(false, false, make::name("this"));

View file

@ -47,7 +47,7 @@ pub(crate) fn replace_with_lazy_method(acc: &mut Assists, ctx: &AssistContext<'_
None,
None,
|func| {
let valid = func.name(ctx.sema.db).as_str() == Some(&*method_name_lazy)
let valid = func.name(ctx.sema.db).as_str() == &*method_name_lazy
&& func.num_params(ctx.sema.db) == n_params
&& {
let params = func.params_without_self(ctx.sema.db);
@ -133,7 +133,7 @@ pub(crate) fn replace_with_eager_method(acc: &mut Assists, ctx: &AssistContext<'
None,
None,
|func| {
let valid = func.name(ctx.sema.db).as_str() == Some(method_name_eager)
let valid = func.name(ctx.sema.db).as_str() == method_name_eager
&& func.num_params(ctx.sema.db) == n_params;
valid.then_some(func)
},

View file

@ -88,8 +88,8 @@ pub fn has_test_related_attribute(attrs: &hir::AttrsWithOwner) -> bool {
let path = attr.path();
(|| {
Some(
path.segments().first()?.as_text()?.starts_with("test")
|| path.segments().last()?.as_text()?.ends_with("test"),
path.segments().first()?.as_str().starts_with("test")
|| path.segments().last()?.as_str().ends_with("test"),
)
})()
.unwrap_or_default()

View file

@ -24,7 +24,7 @@ pub(crate) mod vis;
use std::iter;
use hir::{known, HasAttrs, ImportPathConfig, ScopeDef, Variant};
use hir::{sym, HasAttrs, ImportPathConfig, Name, ScopeDef, Variant};
use ide_db::{imports::import_assets::LocatedImport, RootDatabase, SymbolKind};
use syntax::{ast, SmolStr};
@ -618,7 +618,7 @@ fn enum_variants_with_paths(
let mut process_variant = |variant: Variant| {
let self_path = hir::ModPath::from_segments(
hir::PathKind::Plain,
iter::once(known::SELF_TYPE).chain(iter::once(variant.name(ctx.db))),
iter::once(Name::new_symbol_root(sym::Self_)).chain(iter::once(variant.name(ctx.db))),
);
cb(acc, ctx, variant, self_path);

View file

@ -18,7 +18,7 @@ pub(super) fn complete_macro_use(
for mod_def in krate.root_module().declarations(ctx.db) {
if let ModuleDef::Macro(mac) = mod_def {
let mac_name = mac.name(ctx.db);
let Some(mac_name) = mac_name.as_str() else { continue };
let mac_name = mac_name.as_str();
let existing_import = existing_imports
.iter()

View file

@ -1,5 +1,6 @@
//! Completes references after dot (fields and method calls).
use hir::{sym, Name};
use ide_db::FxHashSet;
use syntax::SmolStr;
@ -90,12 +91,14 @@ pub(crate) fn complete_undotted_self(
in_breakable: expr_ctx.in_breakable,
},
},
Some(hir::known::SELF_PARAM),
Some(Name::new_symbol_root(sym::self_)),
field,
&ty,
)
},
|acc, field, ty| acc.add_tuple_field(ctx, Some(hir::known::SELF_PARAM), field, &ty),
|acc, field, ty| {
acc.add_tuple_field(ctx, Some(Name::new_symbol_root(sym::self_)), field, &ty)
},
true,
false,
);
@ -112,7 +115,7 @@ pub(crate) fn complete_undotted_self(
},
},
func,
Some(hir::known::SELF_PARAM),
Some(Name::new_symbol_root(sym::self_)),
None,
)
});

View file

@ -1,6 +1,6 @@
//! Completion of names from the current scope in expression position.
use hir::{ImportPathConfig, ScopeDef};
use hir::{sym, ImportPathConfig, Name, ScopeDef};
use syntax::ast;
use crate::{
@ -190,7 +190,7 @@ pub(crate) fn complete_expr_path(
path_ctx,
strukt,
None,
Some(hir::known::SELF_TYPE),
Some(Name::new_symbol_root(sym::Self_)),
);
}
}
@ -210,7 +210,12 @@ pub(crate) fn complete_expr_path(
acc.add_union_literal(ctx, un, path, None);
if complete_self {
acc.add_union_literal(ctx, un, None, Some(hir::known::SELF_TYPE));
acc.add_union_literal(
ctx,
un,
None,
Some(Name::new_symbol_root(sym::Self_)),
);
}
}
hir::Adt::Enum(e) => {

View file

@ -7,7 +7,7 @@
//! there is no value in lifting these out into the outline module test since they will either not
//! show up for normal completions, or they won't show completions other than lifetimes depending
//! on the fixture input.
use hir::{known, ScopeDef};
use hir::{sym, Name, ScopeDef};
use syntax::{ast, TokenText};
use crate::{
@ -47,7 +47,7 @@ pub(crate) fn complete_lifetime(
}
});
if param_lifetime.is_none() {
acc.add_lifetime(ctx, known::STATIC_LIFETIME);
acc.add_lifetime(ctx, Name::new_symbol_root(sym::tick_static));
}
}

View file

@ -55,9 +55,8 @@ pub(crate) fn complete_use_path(
if !ctx.check_stability(def.attrs(ctx.db).as_deref()) {
continue;
}
let is_name_already_imported = name
.as_text()
.map_or(false, |text| already_imported_names.contains(text.as_str()));
let is_name_already_imported =
already_imported_names.contains(name.as_str());
let add_resolution = match def {
ScopeDef::Unknown if unknown_is_current(&name) => {

View file

@ -823,13 +823,13 @@ fn classify_name_ref(
for item in trait_.items_with_supertraits(sema.db) {
match item {
hir::AssocItem::TypeAlias(assoc_ty) => {
if assoc_ty.name(sema.db).as_str()? == arg_name {
if assoc_ty.name(sema.db).as_str() == arg_name {
override_location = Some(TypeLocation::AssocTypeEq);
return None;
}
},
hir::AssocItem::Const(const_) => {
if const_.name(sema.db)?.as_str()? == arg_name {
if const_.name(sema.db)?.as_str() == arg_name {
override_location = Some(TypeLocation::AssocConstEq);
return None;
}
@ -867,7 +867,7 @@ fn classify_name_ref(
let trait_items = trait_.items_with_supertraits(sema.db);
let assoc_ty = trait_items.iter().find_map(|item| match item {
hir::AssocItem::TypeAlias(assoc_ty) => {
(assoc_ty.name(sema.db).as_str()? == arg_name)
(assoc_ty.name(sema.db).as_str() == arg_name)
.then_some(assoc_ty)
},
_ => None,

View file

@ -280,8 +280,7 @@ pub(crate) fn render_expr(
let mut snippet_formatter = |ty: &hir::Type| {
let arg_name = ty
.as_adt()
.and_then(|adt| adt.name(ctx.db).as_text())
.map(|s| stdx::to_lower_snake_case(s.as_str()))
.map(|adt| stdx::to_lower_snake_case(adt.name(ctx.db).as_str()))
.unwrap_or_else(|| String::from("_"));
let res = format!("${{{i}:{arg_name}}}");
i += 1;
@ -290,8 +289,7 @@ pub(crate) fn render_expr(
let mut label_formatter = |ty: &hir::Type| {
ty.as_adt()
.and_then(|adt| adt.name(ctx.db).as_text())
.map(|s| stdx::to_lower_snake_case(s.as_str()))
.map(|adt| stdx::to_lower_snake_case(adt.name(ctx.db).as_str()))
.unwrap_or_else(|| String::from("..."))
};

View file

@ -188,7 +188,7 @@ fn compute_return_type_match(
CompletionRelevanceReturnType::Constructor
} else if ret_type
.as_adt()
.and_then(|adt| adt.name(db).as_str().map(|name| name.ends_with("Builder")))
.map(|adt| adt.name(db).as_str().ends_with("Builder"))
.unwrap_or(false)
{
// fn([..]) -> [..]Builder
@ -227,11 +227,7 @@ pub(super) fn add_call_parens<'b>(
None => {
let name = match param.ty().as_adt() {
None => "_".to_owned(),
Some(adt) => adt
.name(ctx.db)
.as_text()
.map(|s| to_lower_snake_case(s.as_str()))
.unwrap_or_else(|| "_".to_owned()),
Some(adt) => to_lower_snake_case(adt.name(ctx.db).as_str()),
};
f(&format_args!("${{{}:{name}}}", index + offset))
}
@ -264,7 +260,7 @@ pub(super) fn add_call_parens<'b>(
fn ref_of_param(ctx: &CompletionContext<'_>, arg: &str, ty: &hir::Type) -> &'static str {
if let Some(derefed_ty) = ty.remove_ref() {
for (name, local) in ctx.locals.iter() {
if name.as_text().as_deref() == Some(arg) {
if name.as_str() == arg {
return if local.ty(ctx.db) == derefed_ty {
if ty.is_mutable_reference() {
"&mut "

View file

@ -144,7 +144,7 @@ impl Definition {
Definition::Local(it) => it.name(db),
Definition::GenericParam(it) => it.name(db),
Definition::Label(it) => it.name(db),
Definition::BuiltinLifetime(StaticLifetime) => hir::known::STATIC_LIFETIME,
Definition::BuiltinLifetime(it) => it.name(),
Definition::BuiltinAttr(_) => return None, // FIXME
Definition::ToolModule(_) => return None, // FIXME
Definition::DeriveHelper(it) => it.name(db),

View file

@ -389,16 +389,16 @@ fn import_for_item(
let mut import_path_candidate_segments = import_path_candidate.segments().iter().rev();
let predicate = |it: EitherOrBoth<&SmolStr, &Name>| match it {
// segments match, check next one
EitherOrBoth::Both(a, b) if b.as_str() == Some(&**a) => None,
EitherOrBoth::Both(a, b) if b.as_str() == &**a => None,
// segments mismatch / qualifier is longer than the path, bail out
EitherOrBoth::Both(..) | EitherOrBoth::Left(_) => Some(false),
// all segments match and we have exhausted the qualifier, proceed
EitherOrBoth::Right(_) => Some(true),
};
if item_as_assoc.is_none() {
let item_name = item_name(db, original_item)?.as_text()?;
let item_name = item_name(db, original_item)?;
let last_segment = import_path_candidate_segments.next()?;
if last_segment.as_str() != Some(&*item_name) {
if *last_segment != item_name {
return None;
}
}

View file

@ -472,7 +472,7 @@ fn find_trait_for_assoc_item(
});
for name in names {
if assoc_item_name.as_str() == name.as_text()?.as_str() {
if assoc_item_name.as_str() == name.as_str() {
// It is fine to return the first match because in case of
// multiple possibilities, the exact trait must be disambiguated
// in the definition of trait being implemented, so this search

View file

@ -1,7 +1,7 @@
use either::Either;
use hir::{
db::{ExpandDatabase, HirDatabase},
known, AssocItem, HirDisplay, HirFileIdExt, ImportPathConfig, InFile, Type,
sym, AssocItem, HirDisplay, HirFileIdExt, ImportPathConfig, InFile, Type,
};
use ide_db::{
assists::Assist, famous_defs::FamousDefs, imports::import_assets::item_for_path_search,
@ -210,7 +210,7 @@ fn get_default_constructor(
let has_new_func = ty
.iterate_assoc_items(ctx.sema.db, krate, |assoc_item| {
if let AssocItem::Function(func) = assoc_item {
if func.name(ctx.sema.db) == known::new
if func.name(ctx.sema.db) == sym::new
&& func.assoc_fn_params(ctx.sema.db).is_empty()
{
return Some(());

View file

@ -76,7 +76,7 @@ fn field_fix(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedField) -> Option<A
let expr = d.expr.value.to_node(&root);
let error_range = ctx.sema.original_range_opt(expr.syntax())?;
let field_name = d.name.as_str()?;
let field_name = d.name.as_str();
// Convert the receiver to an ADT
let adt = d.receiver.strip_references().as_adt()?;
let target_module = adt.module(ctx.sema.db);

View file

@ -150,7 +150,7 @@ fn try_lookup_macro_def_in_macro_use(
for mod_def in krate.root_module().declarations(sema.db) {
if let ModuleDef::Macro(mac) = mod_def {
if mac.name(sema.db).as_str() == Some(token.text()) {
if mac.name(sema.db).as_str() == token.text() {
if let Some(nav) = mac.try_to_nav(sema.db) {
return Some(nav.call_site);
}

View file

@ -5,7 +5,7 @@ use std::{
use either::Either;
use hir::{
known, ClosureStyle, HasVisibility, HirDisplay, HirDisplayError, HirWrite, ModuleDef,
sym, ClosureStyle, HasVisibility, HirDisplay, HirDisplayError, HirWrite, ModuleDef,
ModuleDefId, Semantics,
};
use ide_db::{base_db::FileRange, famous_defs::FamousDefs, RootDatabase};
@ -633,7 +633,7 @@ fn hint_iterator(
if ty.impls_trait(db, iter_trait, &[]) {
let assoc_type_item = iter_trait.items(db).into_iter().find_map(|item| match item {
hir::AssocItem::TypeAlias(alias) if alias.name(db) == known::Item => Some(alias),
hir::AssocItem::TypeAlias(alias) if alias.name(db) == sym::Item => Some(alias),
_ => None,
})?;
if let Some(ty) = ty.normalize_trait_assoc_type(db, &[], assoc_type_item) {

View file

@ -46,7 +46,7 @@ pub(crate) fn hints(
}
let name = param.name(sema.db);
let param_name = name.as_str()?;
let param_name = name.as_str();
let should_hide = {
let argument = get_string_representation(&arg)?;

View file

@ -66,8 +66,11 @@ fn discover_tests_in_module(
let mut r = vec![];
for c in module.children(db) {
let module_name =
c.name(db).as_ref().and_then(|n| n.as_str()).unwrap_or("[mod without name]").to_owned();
let module_name = c
.name(db)
.as_ref()
.map(|n| n.as_str().to_owned())
.unwrap_or_else(|| "[mod without name]".to_owned());
let module_id = format!("{prefix_id}::{module_name}");
let module_children = discover_tests_in_module(db, c, module_id.clone(), only_in_this_file);
if !module_children.is_empty() {
@ -94,7 +97,7 @@ fn discover_tests_in_module(
continue;
}
let nav = f.try_to_nav(db).map(|r| r.call_site);
let fn_name = f.name(db).as_str().unwrap_or("[function without name]").to_owned();
let fn_name = f.name(db).as_str().to_owned();
r.push(TestItem {
id: format!("{prefix_id}::{fn_name}"),
kind: TestItemKind::Function,
@ -153,7 +156,7 @@ fn find_module_id_and_test_parents(
let parent = Some(id.clone());
id += "::";
let module_name = &module.name(sema.db);
let module_name = module_name.as_ref().and_then(|n| n.as_str()).unwrap_or("[mod without name]");
let module_name = module_name.as_ref().map(|n| n.as_str()).unwrap_or("[mod without name]");
id += module_name;
let nav = NavigationTarget::from_module_to_decl(sema.db, module).call_site;
r.push(TestItem {

View file

@ -64,11 +64,7 @@ enum FieldOrTupleIdx {
impl FieldOrTupleIdx {
fn name(&self, db: &RootDatabase) -> String {
match *self {
FieldOrTupleIdx::Field(f) => f
.name(db)
.as_str()
.map(|s| s.to_owned())
.unwrap_or_else(|| format!(".{}", f.name(db).as_tuple_index().unwrap())),
FieldOrTupleIdx::Field(f) => f.name(db).as_str().to_owned(),
FieldOrTupleIdx::TupleIdx(i) => format!(".{i}"),
}
}
@ -189,14 +185,7 @@ pub(crate) fn view_memory_layout(
| Definition::SelfType(_) => "[ROOT]".to_owned(),
// def is an item
def => def
.name(db)
.map(|n| {
n.as_str()
.map(|s| s.to_owned())
.unwrap_or_else(|| format!(".{}", n.as_tuple_index().unwrap()))
})
.unwrap_or("[ROOT]".to_owned()),
def => def.name(db).map(|n| n.as_str().to_owned()).unwrap_or("[ROOT]".to_owned()),
};
let typename = ty.display(db).to_string();

View file

@ -21,7 +21,7 @@ type Guard<T> = dashmap::RwLockWriteGuard<
>;
mod symbol;
pub use self::symbol::{symbols, Symbol};
pub use self::symbol::{symbols as sym, Symbol};
pub struct Interned<T: Internable + ?Sized> {
arc: Arc<T>,

View file

@ -1,5 +1,5 @@
//! Attempt at flexible symbol interning, allowing to intern and free strings at runtime while also
//! supporting
//! supporting compile time declaration of symbols that will never be freed.
use std::{
borrow::Borrow,

View file

@ -11,10 +11,13 @@ use crate::{
Symbol,
};
macro_rules! define_symbols {
($($name:ident),* $(,)?) => {
(@WITH_NAME: $($alias:ident = $value:literal),* $(,)? @PLAIN: $($name:ident),* $(,)?) => {
$(
pub const $name: Symbol = Symbol { repr: TaggedArcPtr::non_arc(&stringify!($name)) };
)*
$(
pub const $alias: Symbol = Symbol { repr: TaggedArcPtr::non_arc(&$value) };
)*
pub(super) fn prefill() -> DashMap<SymbolProxy, (), BuildHasherDefault<FxHasher>> {
@ -33,12 +36,45 @@ macro_rules! define_symbols {
let shard_idx_ = dashmap_.determine_shard(hash_ as usize);
dashmap_.shards_mut()[shard_idx_].get_mut().raw_entry_mut().from_hash(hash_, |k| k == &proxy_).insert(proxy_, SharedValue::new(()));
)*
$(
let proxy_ = SymbolProxy($alias.repr);
let hash_ = hash_thing_(dashmap_.hasher(), &proxy_);
let shard_idx_ = dashmap_.determine_shard(hash_ as usize);
dashmap_.shards_mut()[shard_idx_].get_mut().raw_entry_mut().from_hash(hash_, |k| k == &proxy_).insert(proxy_, SharedValue::new(()));
)*
}
dashmap_
}
};
}
define_symbols! {
@WITH_NAME:
self_ = "self",
Self_ = "Self",
tick_static = "'static",
dollar_crate = "$crate",
MISSING_NAME = "[missing name]",
INTEGER_0 = "0",
INTEGER_1 = "1",
INTEGER_2 = "2",
INTEGER_3 = "3",
INTEGER_4 = "4",
INTEGER_5 = "5",
INTEGER_6 = "6",
INTEGER_7 = "7",
INTEGER_8 = "8",
INTEGER_9 = "9",
INTEGER_10 = "10",
INTEGER_11 = "11",
INTEGER_12 = "12",
INTEGER_13 = "13",
INTEGER_14 = "14",
INTEGER_15 = "15",
fn_ = "fn",
@PLAIN:
add_assign,
add,
alloc,
@ -52,10 +88,88 @@ define_symbols! {
bitor,
bitxor_assign,
bitxor,
transmute_opts,
transmute_trait,
coerce_unsized,
dispatch_from_dyn,destruct,
bool,
panic,
begin_panic,
panic_nounwind,
panic_fmt,
panic_misaligned_pointer_dereference,
panic_display,
const_panic_fmt,
panic_bounds_check,
panic_info,
panic_location,
panic_impl,
panic_cannot_unwind,
sized,
unsize,
format_alignment,
start,
format_argument,
format_arguments,
format_count,
format_placeholder,
format_unsafe_arg,
exchange_malloc,
box_free,
drop_in_place,
alloc_layout,
eh_personality,
eh_catch_typeinfo,
phantom_data,
manually_drop,
maybe_uninit,
align_offset,
termination,
tuple_trait,
slice_len_fn,
from_residual,
from_output,
from_yeet,
pointer_like,
const_param_ty,
Poll,
Ready,
Pending,
ResumeTy,
get_context,
Context,
Some,
Err,
Continue,
Break,
into_iter,
new_unchecked,
range_inclusive_new,
CStr,
fn_ptr_trait,
freeze,
coroutine_state,
c_void,
coroutine,
unpin,
pin,
fn_ptr_addr,
structural_teq,
fn_once_output,
copy,
clone,
sync,
discriminant_kind,
Box,
structural_peq,
boxed,
branch,
discriminant_type,
pointee_trait,
metadata_type,
dyn_metadata,
deref_target,
receiver,
call_mut,
call_once,
call,
@ -168,6 +282,7 @@ define_symbols! {
not,
Not,
Ok,
opaque,
ops,
option_env,
option,
@ -204,6 +319,9 @@ define_symbols! {
rust_2018,
rust_2021,
rust_2024,
rustc_coherence_is_core,
rustc_macro_transparency,
semitransparent,
shl_assign,
shl,
shr_assign,
@ -220,6 +338,7 @@ define_symbols! {
test_case,
test,
trace_macros,
transparent,
Try,
u128,
u16,