Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #17604 - Veykril:tt-symbols, r=Veykril
More symbol usage
95 files changed, 676 insertions, 493 deletions
diff --git a/Cargo.lock b/Cargo.lock index c9542ead79..2a1e7c4d59 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,6 +70,7 @@ name = "base-db" version = "0.0.0" dependencies = [ "cfg", + "intern", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "lz4_flex", "rustc-hash", @@ -970,6 +971,7 @@ dependencies = [ "crossbeam-channel", "hir-expand", "ide-db", + "intern", "itertools", "paths", "proc-macro-api", diff --git a/crates/base-db/Cargo.toml b/crates/base-db/Cargo.toml index 4ab99fc33c..1b1ee034ca 100644 --- a/crates/base-db/Cargo.toml +++ b/crates/base-db/Cargo.toml @@ -27,6 +27,7 @@ stdx.workspace = true syntax.workspace = true vfs.workspace = true span.workspace = true +intern.workspace = true [lints] workspace = true diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs index 1d172ab9e4..41b7e271b0 100644 --- a/crates/base-db/src/input.rs +++ b/crates/base-db/src/input.rs @@ -9,10 +9,10 @@ use std::{fmt, mem, ops}; use cfg::CfgOptions; +use intern::Symbol; use la_arena::{Arena, Idx, RawIdx}; use rustc_hash::{FxHashMap, FxHashSet}; use span::Edition; -use syntax::SmolStr; use triomphe::Arc; use vfs::{file_set::FileSet, AbsPathBuf, AnchoredPath, FileId, VfsPath}; @@ -99,8 +99,8 @@ impl fmt::Debug for CrateGraph { pub type CrateId = Idx<CrateData>; -#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct CrateName(SmolStr); +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct CrateName(Symbol); impl CrateName { /// Creates a crate name, checking for dashes in the string provided. @@ -110,16 +110,16 @@ impl CrateName { if name.contains('-') { Err(name) } else { - Ok(Self(SmolStr::new(name))) + Ok(Self(Symbol::intern(name))) } } /// Creates a crate name, unconditionally replacing the dashes with underscores. pub fn normalize_dashes(name: &str) -> CrateName { - Self(SmolStr::new(name.replace('-', "_"))) + Self(Symbol::intern(&name.replace('-', "_"))) } - pub fn as_smol_str(&self) -> &SmolStr { + pub fn symbol(&self) -> &Symbol { &self.0 } } @@ -133,7 +133,7 @@ impl fmt::Display for CrateName { impl ops::Deref for CrateName { type Target = str; fn deref(&self) -> &str { - &self.0 + self.0.as_str() } } @@ -141,11 +141,11 @@ impl ops::Deref for CrateName { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum CrateOrigin { /// Crates that are from the rustc workspace. - Rustc { name: String }, + Rustc { name: Symbol }, /// Crates that are workspace members. - Local { repo: Option<String>, name: Option<String> }, + Local { repo: Option<String>, name: Option<Symbol> }, /// Crates that are non member libraries. - Library { repo: Option<String>, name: String }, + Library { repo: Option<String>, name: Symbol }, /// Crates that are provided by the language, like std, core, proc-macro, ... Lang(LangCrateOrigin), } @@ -201,16 +201,16 @@ impl fmt::Display for LangCrateOrigin { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct CrateDisplayName { // The name we use to display various paths (with `_`). crate_name: CrateName, // The name as specified in Cargo.toml (with `-`). - canonical_name: String, + canonical_name: Symbol, } impl CrateDisplayName { - pub fn canonical_name(&self) -> &str { + pub fn canonical_name(&self) -> &Symbol { &self.canonical_name } pub fn crate_name(&self) -> &CrateName { @@ -220,7 +220,7 @@ impl CrateDisplayName { impl From<CrateName> for CrateDisplayName { fn from(crate_name: CrateName) -> CrateDisplayName { - let canonical_name = crate_name.to_string(); + let canonical_name = crate_name.0.clone(); CrateDisplayName { crate_name, canonical_name } } } @@ -239,9 +239,9 @@ impl ops::Deref for CrateDisplayName { } impl CrateDisplayName { - pub fn from_canonical_name(canonical_name: String) -> CrateDisplayName { - let crate_name = CrateName::normalize_dashes(&canonical_name); - CrateDisplayName { crate_name, canonical_name } + pub fn from_canonical_name(canonical_name: &str) -> CrateDisplayName { + let crate_name = CrateName::normalize_dashes(canonical_name); + CrateDisplayName { crate_name, canonical_name: Symbol::intern(canonical_name) } } } diff --git a/crates/hir-def/src/attr.rs b/crates/hir-def/src/attr.rs index 1a5ac96aa2..723d675347 100644 --- a/crates/hir-def/src/attr.rs +++ b/crates/hir-def/src/attr.rs @@ -1,6 +1,6 @@ //! A higher level attributes based on TokenTree, with also some shortcuts. -use std::{borrow::Cow, hash::Hash, ops, slice::Iter as SliceIter}; +use std::{borrow::Cow, hash::Hash, ops, slice}; use base_db::CrateId; use cfg::{CfgExpr, CfgOptions}; @@ -14,7 +14,7 @@ use la_arena::{ArenaMap, Idx, RawIdx}; use mbe::DelimiterKind; use syntax::{ ast::{self, HasAttrs}, - AstPtr, SmolStr, + AstPtr, }; use triomphe::Arc; @@ -121,12 +121,12 @@ impl Attrs { } impl Attrs { - pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> { + pub fn by_key<'attrs>(&'attrs self, key: &'attrs Symbol) -> AttrQuery<'_> { AttrQuery { attrs: self, key } } pub fn cfg(&self) -> Option<CfgExpr> { - let mut cfgs = self.by_key("cfg").tt_values().map(CfgExpr::parse); + let mut cfgs = self.by_key(&sym::cfg).tt_values().map(CfgExpr::parse); let first = cfgs.next()?; match cfgs.next() { Some(second) => { @@ -138,7 +138,7 @@ impl Attrs { } pub fn cfgs(&self) -> impl Iterator<Item = CfgExpr> + '_ { - self.by_key("cfg").tt_values().map(CfgExpr::parse) + self.by_key(&sym::cfg).tt_values().map(CfgExpr::parse) } pub(crate) fn is_cfg_enabled(&self, cfg_options: &CfgOptions) -> bool { @@ -148,50 +148,50 @@ impl Attrs { } } - pub fn lang(&self) -> Option<&str> { - self.by_key("lang").string_value() + pub fn lang(&self) -> Option<&Symbol> { + self.by_key(&sym::lang).string_value() } pub fn lang_item(&self) -> Option<LangItem> { - self.by_key("lang").string_value().and_then(|it| LangItem::from_symbol(&Symbol::intern(it))) + self.by_key(&sym::lang).string_value().and_then(LangItem::from_symbol) } pub fn has_doc_hidden(&self) -> bool { - self.by_key("doc").tt_values().any(|tt| { + self.by_key(&sym::doc).tt_values().any(|tt| { tt.delimiter.kind == DelimiterKind::Parenthesis && matches!(&*tt.token_trees, [tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] if ident.sym == sym::hidden) }) } pub fn has_doc_notable_trait(&self) -> bool { - self.by_key("doc").tt_values().any(|tt| { + self.by_key(&sym::doc).tt_values().any(|tt| { tt.delimiter.kind == DelimiterKind::Parenthesis && matches!(&*tt.token_trees, [tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] if ident.sym == sym::notable_trait) }) } pub fn doc_exprs(&self) -> impl Iterator<Item = DocExpr> + '_ { - self.by_key("doc").tt_values().map(DocExpr::parse) + self.by_key(&sym::doc).tt_values().map(DocExpr::parse) } - pub fn doc_aliases(&self) -> impl Iterator<Item = SmolStr> + '_ { + pub fn doc_aliases(&self) -> impl Iterator<Item = Symbol> + '_ { self.doc_exprs().flat_map(|doc_expr| doc_expr.aliases().to_vec()) } - pub fn export_name(&self) -> Option<&str> { - self.by_key("export_name").string_value() + pub fn export_name(&self) -> Option<&Symbol> { + self.by_key(&sym::export_name).string_value() } pub fn is_proc_macro(&self) -> bool { - self.by_key("proc_macro").exists() + self.by_key(&sym::proc_macro).exists() } pub fn is_proc_macro_attribute(&self) -> bool { - self.by_key("proc_macro_attribute").exists() + self.by_key(&sym::proc_macro_attribute).exists() } pub fn is_proc_macro_derive(&self) -> bool { - self.by_key("proc_macro_derive").exists() + self.by_key(&sym::proc_macro_derive).exists() } pub fn is_test(&self) -> bool { @@ -210,27 +210,27 @@ impl Attrs { } pub fn is_ignore(&self) -> bool { - self.by_key("ignore").exists() + self.by_key(&sym::ignore).exists() } pub fn is_bench(&self) -> bool { - self.by_key("bench").exists() + self.by_key(&sym::bench).exists() } pub fn is_unstable(&self) -> bool { - self.by_key("unstable").exists() + self.by_key(&sym::unstable).exists() } } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum DocAtom { /// eg. `#[doc(hidden)]` - Flag(SmolStr), + Flag(Symbol), /// eg. `#[doc(alias = "it")]` /// /// Note that a key can have multiple values that are all considered "active" at the same time. /// For example, `#[doc(alias = "x")]` and `#[doc(alias = "y")]`. - KeyValue { key: SmolStr, value: SmolStr }, + KeyValue { key: Symbol, value: Symbol }, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -239,7 +239,7 @@ pub enum DocExpr { /// eg. `#[doc(hidden)]`, `#[doc(alias = "x")]` Atom(DocAtom), /// eg. `#[doc(alias("x", "y"))]` - Alias(Vec<SmolStr>), + Alias(Vec<Symbol>), } impl From<DocAtom> for DocExpr { @@ -253,9 +253,9 @@ impl DocExpr { next_doc_expr(&mut tt.token_trees.iter()).unwrap_or(DocExpr::Invalid) } - pub fn aliases(&self) -> &[SmolStr] { + pub fn aliases(&self) -> &[Symbol] { match self { - DocExpr::Atom(DocAtom::KeyValue { key, value }) if key == "alias" => { + DocExpr::Atom(DocAtom::KeyValue { key, value }) if *key == sym::alias => { std::slice::from_ref(value) } DocExpr::Alias(aliases) => aliases, @@ -264,7 +264,7 @@ impl DocExpr { } } -fn next_doc_expr<S>(it: &mut SliceIter<'_, tt::TokenTree<S>>) -> Option<DocExpr> { +fn next_doc_expr<S>(it: &mut slice::Iter<'_, tt::TokenTree<S>>) -> Option<DocExpr> { let name = match it.next() { None => return None, Some(tt::TokenTree::Leaf(tt::Leaf::Ident(ident))) => ident.sym.clone(), @@ -282,9 +282,7 @@ fn next_doc_expr<S>(it: &mut SliceIter<'_, tt::TokenTree<S>>) -> Option<DocExpr> }))) => { it.next(); it.next(); - // FIXME: escape? raw string? - let value = SmolStr::new(text.as_str()); - DocAtom::KeyValue { key: name.as_str().into(), value }.into() + DocAtom::KeyValue { key: name, value: text.clone() }.into() } _ => return Some(DocExpr::Invalid), } @@ -292,12 +290,12 @@ fn next_doc_expr<S>(it: &mut SliceIter<'_, tt::TokenTree<S>>) -> Option<DocExpr> Some(tt::TokenTree::Subtree(subtree)) => { it.next(); let subs = parse_comma_sep(subtree); - match name.as_str() { - "alias" => DocExpr::Alias(subs), + match &name { + s if *s == sym::alias => DocExpr::Alias(subs), _ => DocExpr::Invalid, } } - _ => DocAtom::Flag(name.as_str().into()).into(), + _ => DocAtom::Flag(name).into(), }; // Eat comma separator @@ -309,16 +307,16 @@ fn next_doc_expr<S>(it: &mut SliceIter<'_, tt::TokenTree<S>>) -> Option<DocExpr> Some(ret) } -fn parse_comma_sep<S>(subtree: &tt::Subtree<S>) -> Vec<SmolStr> { +fn parse_comma_sep<S>(subtree: &tt::Subtree<S>) -> Vec<Symbol> { subtree .token_trees .iter() .filter_map(|tt| match tt { tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { kind: tt::LitKind::Str, - symbol: text, + symbol, .. - })) => Some(SmolStr::new(text.as_str())), + })) => Some(symbol.clone()), _ => None, }) .collect() @@ -565,7 +563,7 @@ impl AttrSourceMap { #[derive(Debug, Clone, Copy)] pub struct AttrQuery<'attr> { attrs: &'attr Attrs, - key: &'static str, + key: &'attr Symbol, } impl<'attr> AttrQuery<'attr> { @@ -573,11 +571,11 @@ impl<'attr> AttrQuery<'attr> { self.attrs().filter_map(|attr| attr.token_tree_value()) } - pub fn string_value(self) -> Option<&'attr str> { + pub fn string_value(self) -> Option<&'attr Symbol> { self.attrs().find_map(|attr| attr.string_value()) } - pub fn string_value_with_span(self) -> Option<(&'attr str, span::Span)> { + pub fn string_value_with_span(self) -> Option<(&'attr Symbol, span::Span)> { self.attrs().find_map(|attr| attr.string_value_with_span()) } @@ -591,9 +589,7 @@ impl<'attr> AttrQuery<'attr> { pub fn attrs(self) -> impl Iterator<Item = &'attr Attr> + Clone { let key = self.key; - self.attrs - .iter() - .filter(move |attr| attr.path.as_ident().map_or(false, |s| s.to_smol_str() == key)) + self.attrs.iter().filter(move |attr| attr.path.as_ident().map_or(false, |s| *s == *key)) } /// Find string value for a specific key inside token tree @@ -602,10 +598,10 @@ impl<'attr> AttrQuery<'attr> { /// #[doc(html_root_url = "url")] /// ^^^^^^^^^^^^^ key /// ``` - pub fn find_string_value_in_tt(self, key: &'attr str) -> Option<&str> { + pub fn find_string_value_in_tt(self, key: &'attr Symbol) -> Option<&str> { self.tt_values().find_map(|tt| { let name = tt.token_trees.iter() - .skip_while(|tt| !matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { sym, ..} )) if sym.as_str() == key)) + .skip_while(|tt| !matches!(tt, tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { sym, ..} )) if *sym == *key)) .nth(2); match name { @@ -660,6 +656,7 @@ mod tests { //! This module contains tests for doc-expression parsing. //! Currently, it tests `#[doc(hidden)]` and `#[doc(alias)]`. + use intern::Symbol; use triomphe::Arc; use base_db::FileId; @@ -685,24 +682,29 @@ mod tests { #[test] fn test_doc_expr_parser() { - assert_parse_result("#![doc(hidden)]", DocAtom::Flag("hidden".into()).into()); + assert_parse_result("#![doc(hidden)]", DocAtom::Flag(Symbol::intern("hidden")).into()); assert_parse_result( r#"#![doc(alias = "foo")]"#, - DocAtom::KeyValue { key: "alias".into(), value: "foo".into() }.into(), + DocAtom::KeyValue { key: Symbol::intern("alias"), value: Symbol::intern("foo") }.into(), ); - assert_parse_result(r#"#![doc(alias("foo"))]"#, DocExpr::Alias(["foo".into()].into())); + assert_parse_result( + r#"#![doc(alias("foo"))]"#, + DocExpr::Alias([Symbol::intern("foo")].into()), + ); assert_parse_result( r#"#![doc(alias("foo", "bar", "baz"))]"#, - DocExpr::Alias(["foo".into(), "bar".into(), "baz".into()].into()), + DocExpr::Alias( + [Symbol::intern("foo"), Symbol::intern("bar"), Symbol::intern("baz")].into(), + ), ); assert_parse_result( r#" #[doc(alias("Bar", "Qux"))] struct Foo;"#, - DocExpr::Alias(["Bar".into(), "Qux".into()].into()), + DocExpr::Alias([Symbol::intern("Bar"), Symbol::intern("Qux")].into()), ); } } diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs index b96745022a..b6d43af2eb 100644 --- a/crates/hir-def/src/body/lower.rs +++ b/crates/hir-def/src/body/lower.rs @@ -8,7 +8,7 @@ use hir_expand::{ name::{AsName, Name}, ExpandError, InFile, }; -use intern::{sym, Interned}; +use intern::{sym, Interned, Symbol}; use rustc_hash::FxHashMap; use smallvec::SmallVec; use span::AstIdMap; @@ -1623,30 +1623,29 @@ impl ExprCollector<'_> { } } - let lit_pieces = - fmt.template - .iter() - .enumerate() - .filter_map(|(i, piece)| { - match piece { - FormatArgsPiece::Literal(s) => Some( - self.alloc_expr_desugared(Expr::Literal(Literal::String(s.clone()))), - ), - &FormatArgsPiece::Placeholder(_) => { - // Inject empty string before placeholders when not already preceded by a literal piece. - if i == 0 - || matches!(fmt.template[i - 1], FormatArgsPiece::Placeholder(_)) - { - Some(self.alloc_expr_desugared(Expr::Literal(Literal::String( - "".into(), - )))) - } else { - None - } + let lit_pieces = fmt + .template + .iter() + .enumerate() + .filter_map(|(i, piece)| { + match piece { + FormatArgsPiece::Literal(s) => { + Some(self.alloc_expr_desugared(Expr::Literal(Literal::String(s.clone())))) + } + &FormatArgsPiece::Placeholder(_) => { + // Inject empty string before placeholders when not already preceded by a literal piece. + if i == 0 || matches!(fmt.template[i - 1], FormatArgsPiece::Placeholder(_)) + { + Some(self.alloc_expr_desugared(Expr::Literal(Literal::String( + Symbol::empty(), + )))) + } else { + None } } - }) - .collect(); + } + }) + .collect(); let lit_pieces = self.alloc_expr_desugared(Expr::Array(Array::ElementList { elements: lit_pieces, is_assignee_expr: false, diff --git a/crates/hir-def/src/body/scope.rs b/crates/hir-def/src/body/scope.rs index fd685235e1..3fc244a1e8 100644 --- a/crates/hir-def/src/body/scope.rs +++ b/crates/hir-def/src/body/scope.rs @@ -338,7 +338,7 @@ mod tests { let actual = scopes .scope_chain(scope) .flat_map(|scope| scopes.entries(scope)) - .map(|it| it.name().to_smol_str()) + .map(|it| it.name().as_str()) .collect::<Vec<_>>() .join("\n"); let expected = expected.join("\n"); diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs index e2bb02c0c1..a887612707 100644 --- a/crates/hir-def/src/data.rs +++ b/crates/hir-def/src/data.rs @@ -6,7 +6,7 @@ use base_db::CrateId; use hir_expand::{ name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefKind, }; -use intern::{sym, Interned}; +use intern::{sym, Interned, Symbol}; use smallvec::SmallVec; use syntax::{ast, Parse}; use triomphe::Arc; @@ -38,7 +38,7 @@ pub struct FunctionData { pub ret_type: Interned<TypeRef>, pub attrs: Attrs, pub visibility: RawVisibility, - pub abi: Option<Interned<str>>, + pub abi: Option<Symbol>, pub legacy_const_generics_indices: Box<[u32]>, pub rustc_allow_incoherent_impl: bool, flags: FnFlags, @@ -92,12 +92,12 @@ impl FunctionData { let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()); let legacy_const_generics_indices = attrs - .by_key("rustc_legacy_const_generics") + .by_key(&sym::rustc_legacy_const_generics) .tt_values() .next() .map(parse_rustc_legacy_const_generics) .unwrap_or_default(); - let rustc_allow_incoherent_impl = attrs.by_key("rustc_allow_incoherent_impl").exists(); + let rustc_allow_incoherent_impl = attrs.by_key(&sym::rustc_allow_incoherent_impl).exists(); Arc::new(FunctionData { name: func.name.clone(), @@ -200,8 +200,8 @@ impl TypeAliasData { ModItem::from(loc.id.value).into(), ); let rustc_has_incoherent_inherent_impls = - attrs.by_key("rustc_has_incoherent_inherent_impls").exists(); - let rustc_allow_incoherent_impl = attrs.by_key("rustc_allow_incoherent_impl").exists(); + attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists(); + let rustc_allow_incoherent_impl = attrs.by_key(&sym::rustc_allow_incoherent_impl).exists(); Arc::new(TypeAliasData { name: typ.name.clone(), @@ -251,10 +251,10 @@ impl TraitData { let visibility = item_tree[tr_def.visibility].clone(); let attrs = item_tree.attrs(db, module_id.krate(), ModItem::from(tree_id.value).into()); let skip_array_during_method_dispatch = - attrs.by_key("rustc_skip_array_during_method_dispatch").exists(); + attrs.by_key(&sym::rustc_skip_array_during_method_dispatch).exists(); let rustc_has_incoherent_inherent_impls = - attrs.by_key("rustc_has_incoherent_inherent_impls").exists(); - let fundamental = attrs.by_key("fundamental").exists(); + attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists(); + let fundamental = attrs.by_key(&sym::fundamental).exists(); let mut collector = AssocItemCollector::new(db, module_id, tree_id.file_id(), ItemContainerId::TraitId(tr)); collector.collect(&item_tree, tree_id.tree_id(), &tr_def.items); @@ -393,7 +393,7 @@ impl Macro2Data { let helpers = item_tree .attrs(db, loc.container.krate(), ModItem::from(loc.id.value).into()) - .by_key("rustc_builtin_macro") + .by_key(&sym::rustc_builtin_macro) .tt_values() .next() .and_then(|attr| parse_macro_name_and_helper_attrs(&attr.token_trees)) @@ -423,7 +423,7 @@ impl MacroRulesData { let macro_export = item_tree .attrs(db, loc.container.krate(), ModItem::from(loc.id.value).into()) - .by_key("macro_export") + .by_key(&sym::macro_export) .exists(); Arc::new(MacroRulesData { name: makro.name.clone(), macro_export }) @@ -526,7 +526,7 @@ impl ConstData { let rustc_allow_incoherent_impl = item_tree .attrs(db, loc.container.module(db).krate(), ModItem::from(loc.id.value).into()) - .by_key("rustc_allow_incoherent_impl") + .by_key(&sym::rustc_allow_incoherent_impl) .exists(); Arc::new(ConstData { diff --git a/crates/hir-def/src/data/adt.rs b/crates/hir-def/src/data/adt.rs index 3942c2a98a..cc6e408b65 100644 --- a/crates/hir-def/src/data/adt.rs +++ b/crates/hir-def/src/data/adt.rs @@ -95,7 +95,7 @@ fn repr_from_value( item_tree: &ItemTree, of: AttrOwner, ) -> Option<ReprOptions> { - item_tree.attrs(db, krate, of).by_key("repr").tt_values().find_map(parse_repr_tt) + item_tree.attrs(db, krate, of).by_key(&sym::repr).tt_values().find_map(parse_repr_tt) } fn parse_repr_tt(tt: &Subtree) -> Option<ReprOptions> { @@ -194,10 +194,10 @@ impl StructData { let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()); let mut flags = StructFlags::NO_FLAGS; - if attrs.by_key("rustc_has_incoherent_inherent_impls").exists() { + if attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists() { flags |= StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL; } - if attrs.by_key("fundamental").exists() { + if attrs.by_key(&sym::fundamental).exists() { flags |= StructFlags::IS_FUNDAMENTAL; } if let Some(lang) = attrs.lang_item() { @@ -248,10 +248,10 @@ impl StructData { let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into()); let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()); let mut flags = StructFlags::NO_FLAGS; - if attrs.by_key("rustc_has_incoherent_inherent_impls").exists() { + if attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists() { flags |= StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL; } - if attrs.by_key("fundamental").exists() { + if attrs.by_key(&sym::fundamental).exists() { flags |= StructFlags::IS_FUNDAMENTAL; } @@ -287,7 +287,7 @@ impl EnumData { let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into()); let rustc_has_incoherent_inherent_impls = item_tree .attrs(db, loc.container.krate, ModItem::from(loc.id.value).into()) - .by_key("rustc_has_incoherent_inherent_impls") + .by_key(&sym::rustc_has_incoherent_inherent_impls) .exists(); let enum_ = &item_tree[loc.id.value]; diff --git a/crates/hir-def/src/hir.rs b/crates/hir-def/src/hir.rs index d306f9be65..d7eb80a88b 100644 --- a/crates/hir-def/src/hir.rs +++ b/crates/hir-def/src/hir.rs @@ -18,7 +18,7 @@ pub mod type_ref; use std::fmt; use hir_expand::name::Name; -use intern::Interned; +use intern::{Interned, Symbol}; use la_arena::{Idx, RawIdx}; use rustc_apfloat::ieee::{Half as f16, Quad as f128}; use smallvec::SmallVec; @@ -60,41 +60,41 @@ pub type LabelId = Idx<Label>; // We leave float values as a string to avoid double rounding. // For PartialEq, string comparison should work, as ordering is not important // https://github.com/rust-lang/rust-analyzer/issues/12380#issuecomment-1137284360 -#[derive(Default, Debug, Clone, Eq, PartialEq)] -pub struct FloatTypeWrapper(Box<str>); +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct FloatTypeWrapper(Symbol); // FIXME(#17451): Use builtin types once stabilised. impl FloatTypeWrapper { - pub fn new(value: String) -> Self { - Self(value.into()) + pub fn new(sym: Symbol) -> Self { + Self(sym) } pub fn to_f128(&self) -> f128 { - self.0.parse().unwrap_or_default() + self.0.as_str().parse().unwrap_or_default() } pub fn to_f64(&self) -> f64 { - self.0.parse().unwrap_or_default() + self.0.as_str().parse().unwrap_or_default() } pub fn to_f32(&self) -> f32 { - self.0.parse().unwrap_or_default() + self.0.as_str().parse().unwrap_or_default() } pub fn to_f16(&self) -> f16 { - self.0.parse().unwrap_or_default() + self.0.as_str().parse().unwrap_or_default() } } impl fmt::Display for FloatTypeWrapper { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&self.0) + f.write_str(self.0.as_str()) } } #[derive(Debug, Clone, Eq, PartialEq)] pub enum Literal { - String(Box<str>), + String(Symbol), ByteString(Box<[u8]>), CString(Box<[u8]>), Char(char), @@ -130,7 +130,10 @@ impl From<ast::LiteralKind> for Literal { match ast_lit_kind { LiteralKind::IntNumber(lit) => { if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) { - Literal::Float(FloatTypeWrapper::new(lit.value_string()), builtin) + Literal::Float( + FloatTypeWrapper::new(Symbol::intern(&lit.value_string())), + builtin, + ) } else if let builtin @ Some(_) = lit.suffix().and_then(BuiltinUint::from_suffix) { Literal::Uint(lit.value().unwrap_or(0), builtin) } else { @@ -140,14 +143,14 @@ impl From<ast::LiteralKind> for Literal { } LiteralKind::FloatNumber(lit) => { let ty = lit.suffix().and_then(BuiltinFloat::from_suffix); - Literal::Float(FloatTypeWrapper::new(lit.value_string()), ty) + Literal::Float(FloatTypeWrapper::new(Symbol::intern(&lit.value_string())), ty) } LiteralKind::ByteString(bs) => { let text = bs.value().map_or_else(|_| Default::default(), Box::from); Literal::ByteString(text) } LiteralKind::String(s) => { - let text = s.value().map_or_else(|_| Default::default(), Box::from); + let text = s.value().map_or_else(|_| Symbol::empty(), |it| Symbol::intern(&it)); Literal::String(text) } LiteralKind::CString(s) => { diff --git a/crates/hir-def/src/hir/format_args.rs b/crates/hir-def/src/hir/format_args.rs index cf176e86db..390e7da677 100644 --- a/crates/hir-def/src/hir/format_args.rs +++ b/crates/hir-def/src/hir/format_args.rs @@ -1,7 +1,7 @@ //! Parses `format_args` input. -use std::mem; use hir_expand::name::Name; +use intern::Symbol; use rustc_parse_format as parse; use span::SyntaxContextId; use stdx::TupleExt; @@ -29,7 +29,7 @@ pub struct FormatArguments { #[derive(Debug, Clone, PartialEq, Eq)] pub enum FormatArgsPiece { - Literal(Box<str>), + Literal(Symbol), Placeholder(FormatPlaceholder), } @@ -291,9 +291,8 @@ pub(crate) fn parse( parse::Piece::NextArgument(arg) => { let parse::Argument { position, position_span, format } = *arg; if !unfinished_literal.is_empty() { - template.push(FormatArgsPiece::Literal( - mem::take(&mut unfinished_literal).into_boxed_str(), - )); + template.push(FormatArgsPiece::Literal(Symbol::intern(&unfinished_literal))); + unfinished_literal.clear(); } let span = parser.arg_places.get(placeholder_index).and_then(|&s| to_span(s)); @@ -413,7 +412,7 @@ pub(crate) fn parse( } if !unfinished_literal.is_empty() { - template.push(FormatArgsPiece::Literal(unfinished_literal.into_boxed_str())); + template.push(FormatArgsPiece::Literal(Symbol::intern(&unfinished_literal))); } if !invalid_refs.is_empty() { diff --git a/crates/hir-def/src/hir/type_ref.rs b/crates/hir-def/src/hir/type_ref.rs index 7272ed98ce..9b05432258 100644 --- a/crates/hir-def/src/hir/type_ref.rs +++ b/crates/hir-def/src/hir/type_ref.rs @@ -9,7 +9,7 @@ use hir_expand::{ name::{AsName, Name}, AstId, }; -use intern::Interned; +use intern::{sym, Interned, Symbol}; use syntax::ast::{self, HasGenericArgs, HasName, IsString}; use crate::{ @@ -122,9 +122,9 @@ pub enum TypeRef { /// A fn pointer. Last element of the vector is the return type. Fn( Vec<(Option<Name>, TypeRef)>, - bool, /*varargs*/ - bool, /*is_unsafe*/ - Option<Interned<str>>, /* abi */ + bool, /*varargs*/ + bool, /*is_unsafe*/ + Option<Symbol>, /* abi */ ), ImplTrait(Vec<Interned<TypeBound>>), DynTrait(Vec<Interned<TypeBound>>), @@ -230,11 +230,11 @@ impl TypeRef { } else { Vec::new() }; - fn lower_abi(abi: ast::Abi) -> Interned<str> { + fn lower_abi(abi: ast::Abi) -> Symbol { match abi.abi_string() { - Some(tok) => Interned::new_str(tok.text_without_quotes()), + Some(tok) => Symbol::intern(tok.text_without_quotes()), // `extern` default to be `extern "C"`. - _ => Interned::new_str("C"), + _ => sym::C.clone(), } } diff --git a/crates/hir-def/src/import_map.rs b/crates/hir-def/src/import_map.rs index 2b2db21a9f..8cc022e4c6 100644 --- a/crates/hir-def/src/import_map.rs +++ b/crates/hir-def/src/import_map.rs @@ -9,6 +9,7 @@ use itertools::Itertools; use rustc_hash::FxHashSet; use smallvec::SmallVec; use stdx::{format_to, TupleExt}; +use syntax::ToSmolStr; use triomphe::Arc; use crate::{ @@ -81,9 +82,9 @@ impl ImportMap { .iter() // We've only collected items, whose name cannot be tuple field so unwrapping is fine. .flat_map(|(&item, (info, _))| { - info.iter() - .enumerate() - .map(move |(idx, info)| (item, info.name.to_smol_str(), idx as u32)) + info.iter().enumerate().map(move |(idx, info)| { + (item, info.name.display(db.upcast()).to_smolstr(), idx as u32) + }) }) .collect(); importables.sort_by(|(_, l_info, _), (_, r_info, _)| { @@ -412,7 +413,7 @@ pub fn search_dependencies( for map in &import_maps { op = op.add(map.fst.search(&automaton)); } - search_maps(&import_maps, op.union(), query) + search_maps(db, &import_maps, op.union(), query) } SearchMode::Fuzzy => { let automaton = fst::automaton::Subsequence::new(&query.lowercased); @@ -420,7 +421,7 @@ pub fn search_dependencies( for map in &import_maps { op = op.add(map.fst.search(&automaton)); } - search_maps(&import_maps, op.union(), query) + search_maps(db, &import_maps, op.union(), query) } SearchMode::Prefix => { let automaton = fst::automaton::Str::new(&query.lowercased).starts_with(); @@ -428,12 +429,13 @@ pub fn search_dependencies( for map in &import_maps { op = op.add(map.fst.search(&automaton)); } - search_maps(&import_maps, op.union(), query) + search_maps(db, &import_maps, op.union(), query) } } } fn search_maps( + db: &dyn DefDatabase, import_maps: &[Arc<ImportMap>], mut stream: fst::map::Union<'_>, query: &Query, @@ -459,7 +461,7 @@ fn search_maps( query.search_mode.check( &query.query, query.case_sensitive, - &info.name.to_smol_str(), + &info.name.display(db.upcast()).to_smolstr(), ) }); res.extend(iter.map(TupleExt::head)); diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index 7650dfe9f3..479beea4a9 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -46,7 +46,7 @@ use ast::{AstNode, StructKind}; use base_db::CrateId; use either::Either; use hir_expand::{attrs::RawAttrs, name::Name, ExpandTo, HirFileId, InFile}; -use intern::Interned; +use intern::{Interned, Symbol}; use la_arena::{Arena, Idx, IdxRange, RawIdx}; use once_cell::sync::OnceCell; use rustc_hash::FxHashMap; @@ -712,7 +712,7 @@ pub struct ExternCrate { #[derive(Debug, Clone, Eq, PartialEq)] pub struct ExternBlock { - pub abi: Option<Interned<str>>, + pub abi: Option<Symbol>, pub ast_id: FileAstId<ast::ExternBlock>, pub children: Box<[ModItem]>, } @@ -722,7 +722,7 @@ pub struct Function { pub name: Name, pub visibility: RawVisibilityId, pub explicit_generic_params: Interned<GenericParams>, - pub abi: Option<Interned<str>>, + pub abi: Option<Symbol>, pub params: IdxRange<Param>, pub ret_type: Interned<TypeRef>, pub ast_id: FileAstId<ast::Fn>, diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs index 5c80da9304..67092ae0c0 100644 --- a/crates/hir-def/src/item_tree/lower.rs +++ b/crates/hir-def/src/item_tree/lower.rs @@ -3,7 +3,7 @@ use std::collections::hash_map::Entry; use hir_expand::{mod_path::path, name::AsName, span_map::SpanMapRef, HirFileId}; -use intern::sym; +use intern::{sym, Symbol}; use la_arena::Arena; use rustc_hash::FxHashMap; use span::{AstIdMap, SyntaxContextId}; @@ -766,11 +766,11 @@ enum HasImplicitSelf { No, } -fn lower_abi(abi: ast::Abi) -> Interned<str> { +fn lower_abi(abi: ast::Abi) -> Symbol { match abi.abi_string() { - Some(tok) => Interned::new_str(tok.text_without_quotes()), + Some(tok) => Symbol::intern(tok.text_without_quotes()), // `extern` default to be `extern "C"`. - _ => Interned::new_str("C"), + _ => sym::C.clone(), } } diff --git a/crates/hir-def/src/lang_item.rs b/crates/hir-def/src/lang_item.rs index 07b27659ab..a09fd658ae 100644 --- a/crates/hir-def/src/lang_item.rs +++ b/crates/hir-def/src/lang_item.rs @@ -5,7 +5,6 @@ use hir_expand::name::Name; use intern::{sym, Symbol}; use rustc_hash::FxHashMap; -use syntax::SmolStr; use triomphe::Arc; use crate::{ @@ -253,9 +252,9 @@ macro_rules! language_item_table { } impl LangItem { - pub fn name(self) -> SmolStr { + pub fn name(self) -> &'static str { match self { - $( LangItem::$variant => SmolStr::new(stringify!($name)), )* + $( LangItem::$variant => stringify!($name), )* } } diff --git a/crates/hir-def/src/macro_expansion_tests/mod.rs b/crates/hir-def/src/macro_expansion_tests/mod.rs index dc964b3c9a..b6c6e4b397 100644 --- a/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -24,6 +24,7 @@ use hir_expand::{ span_map::SpanMapRef, InFile, MacroFileId, MacroFileIdExt, }; +use intern::Symbol; use span::Span; use stdx::{format_to, format_to_acc}; use syntax::{ @@ -55,7 +56,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream "# .into(), ProcMacro { - name: "identity_when_valid".into(), + name: Symbol::intern("identity_when_valid"), kind: ProcMacroKind::Attr, expander: sync::Arc::new(IdentityWhenValidProcMacroExpander), disabled: false, diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index a614d99de6..07c408fd9e 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -82,7 +82,7 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI .iter() .enumerate() .map(|(idx, it)| { - let name = Name::new(&it.name, tt::IdentIsRaw::No, ctx); + let name = Name::new_symbol(it.name.clone(), ctx); ( name, if !db.expand_proc_attr_macros() { @@ -296,13 +296,13 @@ impl DefCollector<'_> { match () { () if *attr_name == sym::recursion_limit.clone() => { if let Some(limit) = attr.string_value() { - if let Ok(limit) = limit.parse() { + if let Ok(limit) = limit.as_str().parse() { crate_data.recursion_limit = Some(limit); } } } () if *attr_name == sym::crate_type.clone() => { - if let Some("proc-macro") = attr.string_value() { + if attr.string_value() == Some(&sym::proc_dash_macro) { self.is_proc_macro = true; } } @@ -1599,7 +1599,7 @@ impl ModCollector<'_, '_> { id: ItemTreeId::new(self.tree_id, item_tree_id), } .intern(db); - let is_prelude = attrs.by_key("prelude_import").exists(); + let is_prelude = attrs.by_key(&sym::prelude_import).exists(); Import::from_use( self.item_tree, ItemTreeId::new(self.tree_id, item_tree_id), @@ -1624,7 +1624,7 @@ impl ModCollector<'_, '_> { self.process_macro_use_extern_crate( item_tree_id, id, - attrs.by_key("macro_use").attrs(), + attrs.by_key(&sym::macro_use).attrs(), ); } @@ -1897,8 +1897,8 @@ impl ModCollector<'_, '_> { } fn collect_module(&mut self, module_id: FileItemTreeId<Mod>, attrs: &Attrs) { - let path_attr = attrs.by_key("path").string_value_unescape(); - let is_macro_use = attrs.by_key("macro_use").exists(); + let path_attr = attrs.by_key(&sym::path).string_value_unescape(); + let is_macro_use = attrs.by_key(&sym::macro_use).exists(); let module = &self.item_tree[module_id]; match &module.kind { // inline module, just recurse @@ -1974,7 +1974,7 @@ impl ModCollector<'_, '_> { let is_macro_use = is_macro_use || item_tree .top_level_attrs(db, krate) - .by_key("macro_use") + .by_key(&sym::macro_use) .exists(); if is_macro_use { self.import_all_legacy_macros(module_id); @@ -2124,7 +2124,7 @@ impl ModCollector<'_, '_> { let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into()); let ast_id = InFile::new(self.file_id(), mac.ast_id.upcast()); - let export_attr = attrs.by_key("macro_export"); + let export_attr = attrs.by_key(&sym::macro_export); let is_export = export_attr.exists(); let local_inner = if is_export { @@ -2137,17 +2137,17 @@ impl ModCollector<'_, '_> { }; // Case 1: builtin macros - let expander = if attrs.by_key("rustc_builtin_macro").exists() { + let expander = if attrs.by_key(&sym::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_with_span() { + let name = match attrs.by_key(&sym::rustc_builtin_macro).string_value_with_span() { Some((it, span)) => { - name = Name::new(it, tt::IdentIsRaw::No, span.ctx); + name = Name::new_symbol(it.clone(), span.ctx); &name } None => { let explicit_name = - attrs.by_key("rustc_builtin_macro").tt_values().next().and_then(|tt| { + attrs.by_key(&sym::rustc_builtin_macro).tt_values().next().and_then(|tt| { match tt.token_trees.first() { Some(tt::TokenTree::Leaf(tt::Leaf::Ident(name))) => Some(name), _ => None, @@ -2177,7 +2177,7 @@ impl ModCollector<'_, '_> { // Case 2: normal `macro_rules!` macro MacroExpander::Declarative }; - let allow_internal_unsafe = attrs.by_key("allow_internal_unsafe").exists(); + let allow_internal_unsafe = attrs.by_key(&sym::allow_internal_unsafe).exists(); let mut flags = MacroRulesLocFlags::empty(); flags.set(MacroRulesLocFlags::LOCAL_INNER, local_inner); @@ -2207,14 +2207,14 @@ impl ModCollector<'_, '_> { // Case 1: builtin macros let mut helpers_opt = None; let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into()); - let expander = if attrs.by_key("rustc_builtin_macro").exists() { + let expander = if attrs.by_key(&sym::rustc_builtin_macro).exists() { if let Some(expander) = find_builtin_macro(&mac.name) { match expander { Either::Left(it) => MacroExpander::BuiltIn(it), Either::Right(it) => MacroExpander::BuiltInEager(it), } } else if let Some(expander) = find_builtin_derive(&mac.name) { - if let Some(attr) = attrs.by_key("rustc_builtin_macro").tt_values().next() { + if let Some(attr) = attrs.by_key(&sym::rustc_builtin_macro).tt_values().next() { // NOTE: The item *may* have both `#[rustc_builtin_macro]` and `#[proc_macro_derive]`, // in which case rustc ignores the helper attributes from the latter, but it // "doesn't make sense in practice" (see rust-lang/rust#87027). @@ -2247,7 +2247,7 @@ impl ModCollector<'_, '_> { // Case 2: normal `macro` MacroExpander::Declarative }; - let allow_internal_unsafe = attrs.by_key("allow_internal_unsafe").exists(); + let allow_internal_unsafe = attrs.by_key(&sym::allow_internal_unsafe).exists(); let macro_id = Macro2Loc { container: module, diff --git a/crates/hir-def/src/nameres/mod_resolution.rs b/crates/hir-def/src/nameres/mod_resolution.rs index 696fb6a961..6b34fe50ca 100644 --- a/crates/hir-def/src/nameres/mod_resolution.rs +++ b/crates/hir-def/src/nameres/mod_resolution.rs @@ -3,6 +3,7 @@ use arrayvec::ArrayVec; use base_db::{AnchoredPath, FileId}; use hir_expand::{name::Name, HirFileIdExt, MacroFileIdExt}; use limit::Limit; +use syntax::ToSmolStr as _; use crate::{db::DefDatabase, HirFileId}; @@ -33,7 +34,7 @@ impl ModDir { let path = match attr_path { None => { let mut path = self.dir_path.clone(); - path.push(&name.unescaped().to_smol_str()); + path.push(&name.unescaped().display_no_db().to_smolstr()); path } Some(attr_path) => { diff --git a/crates/hir-def/src/nameres/proc_macro.rs b/crates/hir-def/src/nameres/proc_macro.rs index 4789b1f014..fd0b52bc7d 100644 --- a/crates/hir-def/src/nameres/proc_macro.rs +++ b/crates/hir-def/src/nameres/proc_macro.rs @@ -36,8 +36,8 @@ impl Attrs { Some(ProcMacroDef { name: func_name.clone(), kind: ProcMacroKind::Bang }) } else if self.is_proc_macro_attribute() { Some(ProcMacroDef { name: func_name.clone(), kind: ProcMacroKind::Attr }) - } else if self.by_key("proc_macro_derive").exists() { - let derive = self.by_key("proc_macro_derive").tt_values().next()?; + } else if self.by_key(&sym::proc_macro_derive).exists() { + let derive = self.by_key(&sym::proc_macro_derive).tt_values().next()?; let def = parse_macro_name_and_helper_attrs(&derive.token_trees) .map(|(name, helpers)| ProcMacroDef { name, kind: ProcMacroKind::Derive { helpers } }); diff --git a/crates/hir-def/src/path.rs b/crates/hir-def/src/path.rs index ff5d39cf53..f90bc954a9 100644 --- a/crates/hir-def/src/path.rs +++ b/crates/hir-def/src/path.rs @@ -13,7 +13,7 @@ use crate::{ }; use hir_expand::name::Name; use intern::Interned; -use syntax::ast; +use syntax::{ast, ToSmolStr}; pub use hir_expand::mod_path::{path, ModPath, PathKind}; @@ -29,7 +29,7 @@ impl Display for ImportAlias { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { ImportAlias::Underscore => f.write_str("_"), - ImportAlias::Alias(name) => f.write_str(&name.to_smol_str()), + ImportAlias::Alias(name) => f.write_str(&name.display_no_db().to_smolstr()), } } } diff --git a/crates/hir-def/src/pretty.rs b/crates/hir-def/src/pretty.rs index d08e063976..3ee88b536f 100644 --- a/crates/hir-def/src/pretty.rs +++ b/crates/hir-def/src/pretty.rs @@ -200,7 +200,7 @@ pub(crate) fn print_type_ref( } if let Some(abi) = abi { buf.write_str("extern ")?; - buf.write_str(abi)?; + buf.write_str(abi.as_str())?; buf.write_char(' ')?; } write!(buf, "fn(")?; diff --git a/crates/hir-expand/src/attrs.rs b/crates/hir-expand/src/attrs.rs index 8ef7b7049a..777e415418 100644 --- a/crates/hir-expand/src/attrs.rs +++ b/crates/hir-expand/src/attrs.rs @@ -4,7 +4,7 @@ use std::{borrow::Cow, fmt, ops}; use base_db::CrateId; use cfg::CfgExpr; use either::Either; -use intern::{sym, Interned}; +use intern::{sym, Interned, Symbol}; use mbe::{ desugar_doc_comment_text, syntax_node_to_token_tree, DelimiterKind, DocCommentDesugarMode, @@ -310,26 +310,26 @@ impl Attr { impl Attr { /// #[path = "string"] - pub fn string_value(&self) -> Option<&str> { + pub fn string_value(&self) -> Option<&Symbol> { match self.input.as_deref()? { AttrInput::Literal(tt::Literal { symbol: text, kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), .. - }) => Some(text.as_str()), + }) => Some(text), _ => None, } } /// #[path = "string"] - pub fn string_value_with_span(&self) -> Option<(&str, span::Span)> { + pub fn string_value_with_span(&self) -> Option<(&Symbol, span::Span)> { match self.input.as_deref()? { AttrInput::Literal(tt::Literal { symbol: text, kind: tt::LitKind::Str | tt::LitKind::StrRaw(_), span, suffix: _, - }) => Some((text.as_str(), *span)), + }) => Some((text, *span)), _ => None, } } diff --git a/crates/hir-expand/src/name.rs b/crates/hir-expand/src/name.rs index 64c094bd28..d012d272d7 100644 --- a/crates/hir-expand/src/name.rs +++ b/crates/hir-expand/src/name.rs @@ -4,7 +4,7 @@ use std::fmt; use intern::{sym, Symbol}; use span::SyntaxContextId; -use syntax::{ast, format_smolstr, utils::is_raw_identifier, SmolStr}; +use syntax::{ast, utils::is_raw_identifier}; /// `Name` is a wrapper around string, which is used in hir for both references /// and declarations. In theory, names should also carry hygiene info, but we are @@ -59,21 +59,14 @@ impl PartialEq<Name> for Symbol { pub struct UnescapedName<'a>(&'a Name); 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 { - let it = self.0.symbol.as_str(); - if let Some(stripped) = it.strip_prefix("r#") { - SmolStr::new(stripped) - } else { - it.into() - } - } - pub fn display(&self, db: &dyn crate::db::ExpandDatabase) -> impl fmt::Display + '_ { _ = db; UnescapedDisplay { name: self } } + #[doc(hidden)] + pub fn display_no_db(&self) -> impl fmt::Display + '_ { + UnescapedDisplay { name: self } + } } impl Name { @@ -88,7 +81,7 @@ impl Name { _ = ctx; Name { symbol: if raw.yes() { - Symbol::intern(&format_smolstr!("{}{text}", raw.as_str())) + Symbol::intern(&format!("{}{text}", raw.as_str())) } else { Symbol::intern(text) }, @@ -118,9 +111,7 @@ impl Name { // 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)) - } + None if is_raw_identifier(raw_text) => Name::new_text(&format!("r#{}", raw_text)), _ => Name::new_text(raw_text), } } @@ -151,7 +142,7 @@ 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!("<ra@gennew>{idx}")) } /// Returns the tuple index this name represents if it is a tuple field. @@ -164,14 +155,6 @@ impl Name { 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 { - self.symbol.as_str().into() - } - pub fn unescaped(&self) -> UnescapedName<'_> { UnescapedName(self) } @@ -185,6 +168,12 @@ impl Name { Display { name: self } } + // FIXME: Remove this + #[doc(hidden)] + pub fn display_no_db(&self) -> impl fmt::Display + '_ { + Display { name: self } + } + pub fn symbol(&self) -> &Symbol { &self.symbol } diff --git a/crates/hir-expand/src/proc_macro.rs b/crates/hir-expand/src/proc_macro.rs index def2578b0e..39599bfe02 100644 --- a/crates/hir-expand/src/proc_macro.rs +++ b/crates/hir-expand/src/proc_macro.rs @@ -4,10 +4,10 @@ use core::fmt; use std::{panic::RefUnwindSafe, sync}; use base_db::{CrateId, Env}; +use intern::Symbol; use rustc_hash::FxHashMap; use span::Span; use stdx::never; -use syntax::SmolStr; use triomphe::Arc; use crate::{db::ExpandDatabase, tt, ExpandError, ExpandResult}; @@ -53,7 +53,7 @@ pub type ProcMacros = FxHashMap<CrateId, ProcMacroLoadResult>; #[derive(Debug, Clone)] pub struct ProcMacro { - pub name: SmolStr, + pub name: Symbol, pub kind: ProcMacroKind, pub expander: sync::Arc<dyn ProcMacroExpander>, pub disabled: bool, diff --git a/crates/hir-ty/src/diagnostics/decl_check.rs b/crates/hir-ty/src/diagnostics/decl_check.rs index 5175e098fe..b093440060 100644 --- a/crates/hir-ty/src/diagnostics/decl_check.rs +++ b/crates/hir-ty/src/diagnostics/decl_check.rs @@ -24,10 +24,11 @@ use hir_expand::{ name::{AsName, Name}, HirFileId, MacroFileIdExt, }; +use intern::sym; use stdx::{always, never}; use syntax::{ ast::{self, HasName}, - AstNode, AstPtr, + AstNode, AstPtr, ToSmolStr, }; use crate::db::HirDatabase; @@ -163,8 +164,8 @@ impl<'a> DeclValidator<'a> { let is_allowed = |def_id| { let attrs = self.db.attrs(def_id); // don't bug the user about directly no_mangle annotated stuff, they can't do anything about it - (!recursing && attrs.by_key("no_mangle").exists()) - || attrs.by_key("allow").tt_values().any(|tt| { + (!recursing && attrs.by_key(&sym::no_mangle).exists()) + || attrs.by_key(&sym::allow).tt_values().any(|tt| { let allows = tt.to_string(); allows.contains(allow_name) || allows.contains(allow::BAD_STYLE) @@ -325,7 +326,9 @@ impl<'a> DeclValidator<'a> { let bind_name = &body.bindings[*id].name; let replacement = Replacement { current_name: bind_name.clone(), - suggested_text: to_lower_snake_case(&bind_name.to_smol_str())?, + suggested_text: to_lower_snake_case( + &bind_name.display_no_db().to_smolstr(), + )?, expected_case: CaseType::LowerSnakeCase, }; Some((pat_id, replacement)) @@ -405,10 +408,12 @@ impl<'a> DeclValidator<'a> { let mut struct_fields_replacements = fields .iter() .filter_map(|(_, field)| { - to_lower_snake_case(&field.name.to_smol_str()).map(|new_name| Replacement { - current_name: field.name.clone(), - suggested_text: new_name, - expected_case: CaseType::LowerSnakeCase, + to_lower_snake_case(&field.name.display_no_db().to_smolstr()).map(|new_name| { + Replacement { + current_name: field.name.clone(), + suggested_text: new_name, + expected_case: CaseType::LowerSnakeCase, + } }) }) .peekable(); @@ -497,7 +502,7 @@ impl<'a> DeclValidator<'a> { .variants .iter() .filter_map(|(_, name)| { - to_camel_case(&name.to_smol_str()).map(|new_name| Replacement { + to_camel_case(&name.display_no_db().to_smolstr()).map(|new_name| Replacement { current_name: name.clone(), suggested_text: new_name, expected_case: CaseType::UpperCamelCase, @@ -564,10 +569,12 @@ impl<'a> DeclValidator<'a> { let mut variant_field_replacements = fields .iter() .filter_map(|(_, field)| { - to_lower_snake_case(&field.name.to_smol_str()).map(|new_name| Replacement { - current_name: field.name.clone(), - suggested_text: new_name, - expected_case: CaseType::LowerSnakeCase, + to_lower_snake_case(&field.name.display_no_db().to_smolstr()).map(|new_name| { + Replacement { + current_name: field.name.clone(), + suggested_text: new_name, + expected_case: CaseType::LowerSnakeCase, + } }) }) .peekable(); @@ -704,9 +711,11 @@ impl<'a> DeclValidator<'a> { CaseType::UpperSnakeCase => to_upper_snake_case, CaseType::UpperCamelCase => to_camel_case, }; - let Some(replacement) = to_expected_case_type(&name.to_smol_str()).map(|new_name| { - Replacement { current_name: name.clone(), suggested_text: new_name, expected_case } - }) else { + let Some(replacement) = + to_expected_case_type(&name.display(self.db.upcast()).to_smolstr()).map(|new_name| { + Replacement { current_name: name.clone(), suggested_text: new_name, expected_case } + }) + else { return; }; diff --git a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index 1374d0c38b..ff62344012 100644 --- a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs @@ -101,7 +101,7 @@ impl<'db> MatchCheckCtx<'db> { /// Returns whether the given ADT is from another crate declared `#[non_exhaustive]`. fn is_foreign_non_exhaustive(&self, adt: hir_def::AdtId) -> bool { let is_local = adt.krate(self.db.upcast()) == self.module.krate(); - !is_local && self.db.attrs(adt.into()).by_key("non_exhaustive").exists() + !is_local && self.db.attrs(adt.into()).by_key(&sym::non_exhaustive).exists() } fn variant_id_for_adt( diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index f15f6575b7..a433ecfd77 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -1935,7 +1935,7 @@ impl HirDisplay for TypeRef { } if let Some(abi) = abi { f.write_str("extern \"")?; - f.write_str(abi)?; + f.write_str(abi.as_str())?; f.write_str("\" ")?; } write!(f, "fn(")?; @@ -2044,7 +2044,7 @@ impl HirDisplay for Path { .display_name .as_ref() .map(|name| name.canonical_name()) - .unwrap_or("$crate"); + .unwrap_or(&sym::dollar_crate); write!(f, "{name}")? } } diff --git a/crates/hir-ty/src/inhabitedness.rs b/crates/hir-ty/src/inhabitedness.rs index f5fb2ffd78..c0a781b17e 100644 --- a/crates/hir-ty/src/inhabitedness.rs +++ b/crates/hir-ty/src/inhabitedness.rs @@ -6,6 +6,7 @@ use chalk_ir::{ DebruijnIndex, }; use hir_def::{visibility::Visibility, AdtId, EnumVariantId, HasModule, ModuleId, VariantId}; +use intern::sym; use rustc_hash::FxHashSet; use crate::{ @@ -118,7 +119,7 @@ impl UninhabitedFrom<'_> { subst: &Substitution, ) -> ControlFlow<VisiblyUninhabited> { let is_local = variant.krate(self.db.upcast()) == self.target_mod.krate(); - if !is_local && self.db.attrs(variant.into()).by_key("non_exhaustive").exists() { + if !is_local && self.db.attrs(variant.into()).by_key(&sym::non_exhaustive).exists() { return CONTINUE_OPAQUELY_INHABITED; } diff --git a/crates/hir-ty/src/layout/adt.rs b/crates/hir-ty/src/layout/adt.rs index 4cc7dffc24..3463e69097 100644 --- a/crates/hir-ty/src/layout/adt.rs +++ b/crates/hir-ty/src/layout/adt.rs @@ -8,6 +8,7 @@ use hir_def::{ layout::{Integer, LayoutCalculator, ReprOptions, TargetDataLayout}, AdtId, VariantId, }; +use intern::sym; use rustc_index::IndexVec; use smallvec::SmallVec; use triomphe::Arc; @@ -129,7 +130,10 @@ fn layout_scalar_valid_range(db: &dyn HirDatabase, def: AdtId) -> (Bound<u128>, } Bound::Unbounded }; - (get("rustc_layout_scalar_valid_range_start"), get("rustc_layout_scalar_valid_range_end")) + ( + get(&sym::rustc_layout_scalar_valid_range_start), + get(&sym::rustc_layout_scalar_valid_range_end), + ) } pub fn layout_of_adt_recover( diff --git a/crates/hir-ty/src/layout/tests.rs b/crates/hir-ty/src/layout/tests.rs index 35ea13eb11..e2ddb1bb22 100644 --- a/crates/hir-ty/src/layout/tests.rs +++ b/crates/hir-ty/src/layout/tests.rs @@ -3,6 +3,7 @@ use either::Either; use hir_def::db::DefDatabase; use project_model::{target_data_layout::RustcDataLayoutConfig, Sysroot}; use rustc_hash::FxHashMap; +use syntax::ToSmolStr; use test_fixture::WithFixture; use triomphe::Arc; @@ -40,14 +41,20 @@ fn eval_goal(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutErro let adt_or_type_alias_id = scope.declarations().find_map(|x| match x { hir_def::ModuleDefId::AdtId(x) => { let name = match x { - hir_def::AdtId::StructId(x) => db.struct_data(x).name.to_smol_str(), - hir_def::AdtId::UnionId(x) => db.union_data(x).name.to_smol_str(), - hir_def::AdtId::EnumId(x) => db.enum_data(x).name.to_smol_str(), + hir_def::AdtId::StructId(x) => { + db.struct_data(x).name.display_no_db().to_smolstr() + } + hir_def::AdtId::UnionId(x) => { + db.union_data(x).name.display_no_db().to_smolstr() + } + hir_def::AdtId::EnumId(x) => { + db.enum_data(x).name.display_no_db().to_smolstr() + } }; (name == "Goal").then_some(Either::Left(x)) } hir_def::ModuleDefId::TypeAliasId(x) => { - let name = db.type_alias_data(x).name.to_smol_str(); + let name = db.type_alias_data(x).name.display_no_db().to_smolstr(); (name == "Goal").then_some(Either::Right(x)) } _ => None, @@ -87,14 +94,19 @@ fn eval_expr(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutErro .declarations() .find_map(|x| match x { hir_def::ModuleDefId::FunctionId(x) => { - let name = db.function_data(x).name.to_smol_str(); + let name = db.function_data(x).name.display_no_db().to_smolstr(); (name == "main").then_some(x) } _ => None, }) .unwrap(); let hir_body = db.body(function_id.into()); - let b = hir_body.bindings.iter().find(|x| x.1.name.to_smol_str() == "goal").unwrap().0; + let b = hir_body + .bindings + .iter() + .find(|x| x.1.name.display_no_db().to_smolstr() == "goal") + .unwrap() + .0; let infer = db.infer(function_id.into()); let goal_ty = infer.type_of_binding[b].clone(); db.layout_of_ty(goal_ty, db.trait_environment(function_id.into())) diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs index aabf11f268..2f93ce3181 100644 --- a/crates/hir-ty/src/lib.rs +++ b/crates/hir-ty/src/lib.rs @@ -62,7 +62,7 @@ use chalk_ir::{ use either::Either; use hir_def::{hir::ExprId, type_ref::Rawness, CallableDefId, GeneralConstId, TypeOrConstParamId}; use hir_expand::name::Name; -use intern::sym; +use intern::{sym, Symbol}; use la_arena::{Arena, Idx}; use mir::{MirEvalError, VTableMap}; use rustc_hash::{FxHashMap, FxHashSet}; @@ -423,45 +423,45 @@ impl Hash for FnAbi { } impl FnAbi { - #[allow(clippy::should_implement_trait)] - pub fn from_str(s: &str) -> FnAbi { + #[rustfmt::skip] + pub fn from_symbol(s: &Symbol) -> FnAbi { match s { - "aapcs-unwind" => FnAbi::AapcsUnwind, - "aapcs" => FnAbi::Aapcs, - "avr-interrupt" => FnAbi::AvrInterrupt, - "avr-non-blocking-interrupt" => FnAbi::AvrNonBlockingInterrupt, - "C-cmse-nonsecure-call" => FnAbi::CCmseNonsecureCall, - "C-unwind" => FnAbi::CUnwind, - "C" => FnAbi::C, - "cdecl-unwind" => FnAbi::CDeclUnwind, - "cdecl" => FnAbi::CDecl, - "efiapi" => FnAbi::Efiapi, - "fastcall-unwind" => FnAbi::FastcallUnwind, - "fastcall" => FnAbi::Fastcall, - "msp430-interrupt" => FnAbi::Msp430Interrupt, - "platform-intrinsic" => FnAbi::PlatformIntrinsic, - "ptx-kernel" => FnAbi::PtxKernel, - "riscv-interrupt-m" => FnAbi::RiscvInterruptM, - "riscv-interrupt-s" => FnAbi::RiscvInterruptS, - "rust-call" => FnAbi::RustCall, - "rust-cold" => FnAbi::RustCold, - "rust-intrinsic" => FnAbi::RustIntrinsic, - "Rust" => FnAbi::Rust, - "stdcall-unwind" => FnAbi::StdcallUnwind, - "stdcall" => FnAbi::Stdcall, - "system-unwind" => FnAbi::SystemUnwind, - "system" => FnAbi::System, - "sysv64-unwind" => FnAbi::Sysv64Unwind, - "sysv64" => FnAbi::Sysv64, - "thiscall-unwind" => FnAbi::ThiscallUnwind, - "thiscall" => FnAbi::Thiscall, - "unadjusted" => FnAbi::Unadjusted, - "vectorcall-unwind" => FnAbi::VectorcallUnwind, - "vectorcall" => FnAbi::Vectorcall, - "wasm" => FnAbi::Wasm, - "win64-unwind" => FnAbi::Win64Unwind, - "win64" => FnAbi::Win64, - "x86-interrupt" => FnAbi::X86Interrupt, + s if *s == sym::aapcs_dash_unwind => FnAbi::AapcsUnwind, + s if *s == sym::aapcs => FnAbi::Aapcs, + s if *s == sym::avr_dash_interrupt => FnAbi::AvrInterrupt, + s if *s == sym::avr_dash_non_dash_blocking_dash_interrupt => FnAbi::AvrNonBlockingInterrupt, + s if *s == sym::C_dash_cmse_dash_nonsecure_dash_call => FnAbi::CCmseNonsecureCall, + s if *s == sym::C_dash_unwind => FnAbi::CUnwind, + s if *s == sym::C => FnAbi::C, + s if *s == sym::cdecl_dash_unwind => FnAbi::CDeclUnwind, + s if *s == sym::cdecl => FnAbi::CDecl, + s if *s == sym::efiapi => FnAbi::Efiapi, + s if *s == sym::fastcall_dash_unwind => FnAbi::FastcallUnwind, + s if *s == sym::fastcall => FnAbi::Fastcall, + s if *s == sym::msp430_dash_interrupt => FnAbi::Msp430Interrupt, + s if *s == sym::platform_dash_intrinsic => FnAbi::PlatformIntrinsic, + s if *s == sym::ptx_dash_kernel => FnAbi::PtxKernel, + s if *s == sym::riscv_dash_interrupt_dash_m => FnAbi::RiscvInterruptM, + s if *s == sym::riscv_dash_interrupt_dash_s => FnAbi::RiscvInterruptS, + s if *s == sym::rust_dash_call => FnAbi::RustCall, + s if *s == sym::rust_dash_cold => FnAbi::RustCold, + s if *s == sym::rust_dash_intrinsic => FnAbi::RustIntrinsic, + s if *s == sym::Rust => FnAbi::Rust, + s if *s == sym::stdcall_dash_unwind => FnAbi::StdcallUnwind, + s if *s == sym::stdcall => FnAbi::Stdcall, + s if *s == sym::system_dash_unwind => FnAbi::SystemUnwind, + s if *s == sym::system => FnAbi::System, + s if *s == sym::sysv64_dash_unwind => FnAbi::Sysv64Unwind, + s if *s == sym::sysv64 => FnAbi::Sysv64, + s if *s == sym::thiscall_dash_unwind => FnAbi::ThiscallUnwind, + s if *s == sym::thiscall => FnAbi::Thiscall, + s if *s == sym::unadjusted => FnAbi::Unadjusted, + s if *s == sym::vectorcall_dash_unwind => FnAbi::VectorcallUnwind, + s if *s == sym::vectorcall => FnAbi::Vectorcall, + s if *s == sym::wasm => FnAbi::Wasm, + s if *s == sym::win64_dash_unwind => FnAbi::Win64Unwind, + s if *s == sym::win64 => FnAbi::Win64, + s if *s == sym::x86_dash_interrupt => FnAbi::X86Interrupt, _ => FnAbi::Unknown, } } diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index d421e72d36..444628ff52 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -298,7 +298,7 @@ impl<'a> TyLoweringContext<'a> { TyKind::Function(FnPointer { num_binders: 0, // FIXME lower `for<'a> fn()` correctly sig: FnSig { - abi: abi.as_deref().map_or(FnAbi::Rust, FnAbi::from_str), + abi: abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol), safety: if is_unsafe { Safety::Unsafe } else { Safety::Safe }, variadic, }, @@ -1858,7 +1858,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { ret, data.is_varargs(), if data.has_unsafe_kw() { Safety::Unsafe } else { Safety::Safe }, - data.abi.as_deref().map_or(FnAbi::Rust, FnAbi::from_str), + data.abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol), ); make_binders(db, &generics, sig) } diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs index fad74c2448..d3ddc883a8 100644 --- a/crates/hir-ty/src/method_resolution.rs +++ b/crates/hir-ty/src/method_resolution.rs @@ -13,6 +13,7 @@ use hir_def::{ ModuleId, TraitId, }; use hir_expand::name::Name; +use intern::sym; use rustc_hash::{FxHashMap, FxHashSet}; use smallvec::{smallvec, SmallVec}; use span::Edition; @@ -200,7 +201,7 @@ impl TraitImpls { // FIXME: Reservation impls should be considered during coherence checks. If we are // (ever) to implement coherence checks, this filtering should be done by the trait // solver. - if db.attrs(impl_id.into()).by_key("rustc_reservation_impl").exists() { + if db.attrs(impl_id.into()).by_key(&sym::rustc_reservation_impl).exists() { continue; } let target_trait = match db.impl_trait(impl_id) { diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index 32b7d6dc11..8c146aae97 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -15,7 +15,7 @@ use hir_def::{ StaticId, VariantId, }; use hir_expand::{mod_path::path, name::Name, HirFileIdExt, InFile}; -use intern::{sym, Interned}; +use intern::sym; use la_arena::ArenaMap; use rustc_abi::TargetDataLayout; use rustc_apfloat::{ diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs index 6818759310..bd43a62341 100644 --- a/crates/hir-ty/src/mir/eval/shim.rs +++ b/crates/hir-ty/src/mir/eval/shim.rs @@ -15,9 +15,9 @@ use crate::{ error_lifetime, mir::eval::{ 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, + InternedClosure, Interner, Interval, IntervalAndTy, IntervalOrOwned, ItemContainerId, + LangItem, Layout, Locals, Lookup, MirEvalError, MirSpan, Mutability, Result, Substitution, + Ty, TyBuilder, TyExt, }, }; @@ -54,12 +54,12 @@ impl Evaluator<'_> { let function_data = self.db.function_data(def); let is_intrinsic = match &function_data.abi { - Some(abi) => *abi == Interned::new_str("rust-intrinsic"), + Some(abi) => *abi == sym::rust_dash_intrinsic, None => match def.lookup(self.db.upcast()).container { hir_def::ItemContainerId::ExternBlockId(block) => { let id = block.lookup(self.db.upcast()).id; - id.item_tree(self.db.upcast())[id.value].abi.as_deref() - == Some("rust-intrinsic") + id.item_tree(self.db.upcast())[id.value].abi.as_ref() + == Some(&sym::rust_dash_intrinsic) } _ => false, }, @@ -76,12 +76,12 @@ impl Evaluator<'_> { return Ok(true); } let is_platform_intrinsic = match &function_data.abi { - Some(abi) => *abi == Interned::new_str("platform-intrinsic"), + Some(abi) => *abi == sym::platform_dash_intrinsic, None => match def.lookup(self.db.upcast()).container { hir_def::ItemContainerId::ExternBlockId(block) => { let id = block.lookup(self.db.upcast()).id; - id.item_tree(self.db.upcast())[id.value].abi.as_deref() - == Some("platform-intrinsic") + id.item_tree(self.db.upcast())[id.value].abi.as_ref() + == Some(&sym::platform_dash_intrinsic) } _ => false, }, @@ -100,7 +100,7 @@ impl Evaluator<'_> { let is_extern_c = match def.lookup(self.db.upcast()).container { hir_def::ItemContainerId::ExternBlockId(block) => { let id = block.lookup(self.db.upcast()).id; - id.item_tree(self.db.upcast())[id.value].abi.as_deref() == Some("C") + id.item_tree(self.db.upcast())[id.value].abi.as_ref() == Some(&sym::C) } _ => false, }; @@ -314,7 +314,7 @@ impl Evaluator<'_> { use LangItem::*; let attrs = self.db.attrs(def.into()); - if attrs.by_key("rustc_const_panic_str").exists() { + if attrs.by_key(&sym::rustc_const_panic_str).exists() { // `#[rustc_const_panic_str]` is treated like `lang = "begin_panic"` by rustc CTFE. return Some(LangItem::BeginPanic); } diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index 1b8c772d80..1f3c85f0fd 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -1406,6 +1406,7 @@ impl<'ctx> MirLowerCtx<'ctx> { const USIZE_SIZE: usize = mem::size_of::<usize>(); let bytes: Box<[_]> = match l { hir_def::hir::Literal::String(b) => { + let b = b.as_str(); let mut data = [0; { 2 * USIZE_SIZE }]; data[..USIZE_SIZE].copy_from_slice(&0usize.to_le_bytes()); data[USIZE_SIZE..].copy_from_slice(&b.len().to_le_bytes()); diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs index 738e842146..fbec332885 100644 --- a/crates/hir-ty/src/utils.rs +++ b/crates/hir-ty/src/utils.rs @@ -18,6 +18,7 @@ use hir_def::{ TypeOrConstParamId, }; use hir_expand::name::Name; +use intern::sym; use rustc_abi::TargetDataLayout; use rustc_hash::FxHashSet; use smallvec::{smallvec, SmallVec}; @@ -254,7 +255,7 @@ pub fn is_fn_unsafe_to_call(db: &dyn HirDatabase, func: FunctionId) -> bool { let data = db.function_data(func); if data.has_unsafe_kw() { // Functions that are `#[rustc_deprecated_safe_2024]` are safe to call before 2024. - if db.attrs(func.into()).by_key("rustc_deprecated_safe_2024").exists() { + if db.attrs(func.into()).by_key(&sym::rustc_deprecated_safe_2024).exists() { // FIXME: Properly check the caller span and mark it as unsafe after 2024. return false; } @@ -268,11 +269,11 @@ pub fn is_fn_unsafe_to_call(db: &dyn HirDatabase, func: FunctionId) -> bool { let id = block.lookup(db.upcast()).id; let is_intrinsic = - id.item_tree(db.upcast())[id.value].abi.as_deref() == Some("rust-intrinsic"); + id.item_tree(db.upcast())[id.value].abi.as_ref() == Some(&sym::rust_dash_intrinsic); if is_intrinsic { // Intrinsics are unsafe unless they have the rustc_safe_intrinsic attribute - !data.attrs.by_key("rustc_safe_intrinsic").exists() + !data.attrs.by_key(&sym::rustc_safe_intrinsic).exists() } else { // Extern items are always unsafe true diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index 72e79af75d..a0dbead221 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs @@ -82,8 +82,7 @@ impl HirDisplay for Function { f.write_str("unsafe ")?; } if let Some(abi) = &data.abi { - // FIXME: String escape? - write!(f, "extern \"{}\" ", &**abi)?; + write!(f, "extern \"{}\" ", abi.as_str())?; } write!(f, "fn {}", data.name.display(f.db.upcast()))?; diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 9f33c50670..dece4edb88 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -82,7 +82,7 @@ use span::{Edition, MacroCallId}; use stdx::{impl_from, never}; use syntax::{ ast::{self, HasAttrs as _, HasName}, - format_smolstr, AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, TextRange, T, + format_smolstr, AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, TextRange, ToSmolStr, T, }; use triomphe::Arc; @@ -259,7 +259,7 @@ impl Crate { pub fn get_html_root_url(self: &Crate, db: &dyn HirDatabase) -> Option<String> { // Look for #![doc(html_root_url = "...")] let attrs = db.attrs(AttrDefId::ModuleId(self.root_module().into())); - let doc_url = attrs.by_key("doc").find_string_value_in_tt("html_root_url"); + let doc_url = attrs.by_key(&sym::doc).find_string_value_in_tt(&sym::html_root_url); doc_url.map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/") } @@ -677,9 +677,9 @@ impl Module { TypeOrConstParamId { parent, local_id }, )) }); - let res = type_params - .chain(lifetime_params) - .any(|p| db.attrs(AttrDefId::GenericParamId(p)).by_key("may_dangle").exists()); + let res = type_params.chain(lifetime_params).any(|p| { + db.attrs(AttrDefId::GenericParamId(p)).by_key(&sym::may_dangle).exists() + }); Some(res) })() .unwrap_or(false); @@ -2088,14 +2088,14 @@ impl Function { /// is this a `fn main` or a function with an `export_name` of `main`? pub fn is_main(self, db: &dyn HirDatabase) -> bool { let data = db.function_data(self.id); - data.attrs.export_name() == Some("main") - || self.module(db).is_crate_root() && data.name.to_smol_str() == "main" + data.attrs.export_name() == Some(&sym::main) + || self.module(db).is_crate_root() && data.name == sym::main } /// Is this a function with an `export_name` of `main`? pub fn exported_main(self, db: &dyn HirDatabase) -> bool { let data = db.function_data(self.id); - data.attrs.export_name() == Some("main") + data.attrs.export_name() == Some(&sym::main) } /// Does this function have the ignore attribute? @@ -4607,7 +4607,7 @@ impl Type { ) -> impl Iterator<Item = SmolStr> + 'a { // iterate the lifetime self.as_adt() - .and_then(|a| a.lifetime(db).map(|lt| lt.name.to_smol_str())) + .and_then(|a| a.lifetime(db).map(|lt| lt.name.display_no_db().to_smolstr())) .into_iter() // add the type and const parameters .chain(self.type_and_const_arguments(db)) diff --git a/crates/hir/src/symbols.rs b/crates/hir/src/symbols.rs index a6e69d7992..cdfeae1b28 100644 --- a/crates/hir/src/symbols.rs +++ b/crates/hir/src/symbols.rs @@ -10,7 +10,7 @@ use hir_def::{ }; use hir_expand::{HirFileId, InFile}; use hir_ty::{db::HirDatabase, display::HirDisplay}; -use syntax::{ast::HasName, AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr}; +use syntax::{ast::HasName, AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, ToSmolStr}; use crate::{Module, ModuleDef, Semantics}; @@ -258,10 +258,18 @@ impl<'a> SymbolCollector<'a> { fn def_with_body_id_name(&self, body_id: DefWithBodyId) -> Option<SmolStr> { match body_id { - DefWithBodyId::FunctionId(id) => Some(self.db.function_data(id).name.to_smol_str()), - DefWithBodyId::StaticId(id) => Some(self.db.static_data(id).name.to_smol_str()), - DefWithBodyId::ConstId(id) => Some(self.db.const_data(id).name.as_ref()?.to_smol_str()), - DefWithBodyId::VariantId(id) => Some(self.db.enum_variant_data(id).name.to_smol_str()), + DefWithBodyId::FunctionId(id) => { + Some(self.db.function_data(id).name.display_no_db().to_smolstr()) + } + DefWithBodyId::StaticId(id) => { + Some(self.db.static_data(id).name.display_no_db().to_smolstr()) + } + DefWithBodyId::ConstId(id) => { + Some(self.db.const_data(id).name.as_ref()?.display_no_db().to_smolstr()) + } + DefWithBodyId::VariantId(id) => { + Some(self.db.enum_variant_data(id).name.display_no_db().to_smolstr()) + } DefWithBodyId::InTypeConstId(_) => Some("in type const".into()), } } @@ -293,7 +301,7 @@ impl<'a> SymbolCollector<'a> { if let Some(attrs) = def.attrs(self.db) { for alias in attrs.doc_aliases() { self.symbols.push(FileSymbol { - name: alias, + name: alias.as_str().into(), def, loc: dec_loc.clone(), container_name: self.current_container_name.clone(), @@ -330,7 +338,7 @@ impl<'a> SymbolCollector<'a> { if let Some(attrs) = def.attrs(self.db) { for alias in attrs.doc_aliases() { self.symbols.push(FileSymbol { - name: alias, + name: alias.as_str().into(), def, loc: dec_loc.clone(), container_name: self.current_container_name.clone(), diff --git a/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/crates/ide-assists/src/handlers/add_missing_match_arms.rs index 4eb29a2378..e1bf6b27bc 100644 --- a/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -1,7 +1,7 @@ use std::iter::{self, Peekable}; use either::Either; -use hir::{Adt, Crate, HasAttrs, HasSource, ImportPathConfig, ModuleDef, Semantics}; +use hir::{sym, Adt, Crate, HasAttrs, HasSource, ImportPathConfig, ModuleDef, Semantics}; use ide_db::RootDatabase; use ide_db::{famous_defs::FamousDefs, helpers::mod_path_to_ast}; use itertools::Itertools; @@ -381,7 +381,7 @@ impl ExtendedEnum { fn is_non_exhaustive(self, db: &RootDatabase, krate: Crate) -> bool { match self { ExtendedEnum::Enum(e) => { - e.attrs(db).by_key("non_exhaustive").exists() && e.module(db).krate() != krate + e.attrs(db).by_key(&sym::non_exhaustive).exists() && e.module(db).krate() != krate } _ => false, } diff --git a/crates/ide-assists/src/handlers/destructure_struct_binding.rs b/crates/ide-assists/src/handlers/destructure_struct_binding.rs index 62bb6dff21..da902f7e10 100644 --- a/crates/ide-assists/src/handlers/destructure_struct_binding.rs +++ b/crates/ide-assists/src/handlers/destructure_struct_binding.rs @@ -1,4 +1,4 @@ -use hir::{HasVisibility, ImportPathConfig}; +use hir::{sym, HasVisibility, ImportPathConfig}; use ide_db::{ assists::{AssistId, AssistKind}, defs::Definition, @@ -7,7 +7,7 @@ use ide_db::{ FxHashMap, FxHashSet, }; use itertools::Itertools; -use syntax::{ast, ted, AstNode, SmolStr, SyntaxNode}; +use syntax::{ast, ted, AstNode, SmolStr, SyntaxNode, ToSmolStr}; use text_edit::TextRange; use crate::{ @@ -98,7 +98,7 @@ fn collect_data(ident_pat: ast::IdentPat, ctx: &AssistContext<'_>) -> Option<Str let kind = struct_type.kind(ctx.db()); let struct_def_path = module.find_path(ctx.db(), struct_def, cfg)?; - let is_non_exhaustive = struct_def.attrs(ctx.db())?.by_key("non_exhaustive").exists(); + let is_non_exhaustive = struct_def.attrs(ctx.db())?.by_key(&sym::non_exhaustive).exists(); let is_foreign_crate = struct_def.module(ctx.db()).map_or(false, |m| m.krate() != module.krate()); @@ -251,7 +251,7 @@ fn generate_field_names(ctx: &AssistContext<'_>, data: &StructEditData) -> Vec<( .visible_fields .iter() .map(|field| { - let field_name = field.name(ctx.db()).to_smol_str(); + let field_name = field.name(ctx.db()).display_no_db().to_smolstr(); let new_name = new_field_name(field_name.clone(), &data.names_in_scope); (field_name, new_name) }) diff --git a/crates/ide-assists/src/handlers/fill_record_pattern_fields.rs b/crates/ide-assists/src/handlers/fill_record_pattern_fields.rs index 2887e0c3e5..758f50d3f4 100644 --- a/crates/ide-assists/src/handlers/fill_record_pattern_fields.rs +++ b/crates/ide-assists/src/handlers/fill_record_pattern_fields.rs @@ -1,6 +1,6 @@ use syntax::{ ast::{self, make}, - AstNode, + AstNode, ToSmolStr, }; use crate::{AssistContext, AssistId, Assists}; @@ -45,8 +45,9 @@ pub(crate) fn fill_record_pattern_fields(acc: &mut Assists, ctx: &AssistContext< let new_field_list = make::record_pat_field_list(old_field_list.fields(), None).clone_for_update(); for (f, _) in missing_fields.iter() { - let field = - make::record_pat_field_shorthand(make::name_ref(&f.name(ctx.sema.db).to_smol_str())); + let field = make::record_pat_field_shorthand(make::name_ref( + &f.name(ctx.sema.db).display_no_db().to_smolstr(), + )); new_field_list.add_field(field.clone_for_update()); } diff --git a/crates/ide-assists/src/handlers/fix_visibility.rs b/crates/ide-assists/src/handlers/fix_visibility.rs index 589591a677..759750a550 100644 --- a/crates/ide-assists/src/handlers/fix_visibility.rs +++ b/crates/ide-assists/src/handlers/fix_visibility.rs @@ -4,7 +4,7 @@ use hir::{ use ide_db::base_db::FileId; use syntax::{ ast::{self, edit_in_place::HasVisibilityEdit, make, HasVisibility as _}, - AstNode, TextRange, + AstNode, TextRange, ToSmolStr, }; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -48,7 +48,7 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>) let (_, def) = module .scope(ctx.db(), None) .into_iter() - .find(|(name, _)| name.to_smol_str() == name_ref.text().as_str())?; + .find(|(name, _)| name.display_no_db().to_smolstr() == name_ref.text().as_str())?; let ScopeDef::ModuleDef(def) = def else { return None; }; diff --git a/crates/ide-assists/src/handlers/generate_delegate_trait.rs b/crates/ide-assists/src/handlers/generate_delegate_trait.rs index 78def51a4a..5a3457e5b7 100644 --- a/crates/ide-assists/src/handlers/generate_delegate_trait.rs +++ b/crates/ide-assists/src/handlers/generate_delegate_trait.rs @@ -22,7 +22,7 @@ use syntax::{ WherePred, }, ted::{self, Position}, - AstNode, NodeOrToken, SmolStr, SyntaxKind, + AstNode, NodeOrToken, SmolStr, SyntaxKind, ToSmolStr, }; // Assist: generate_delegate_trait @@ -170,11 +170,11 @@ impl Delegee { for m in it.module(db).path_to_root(db).iter().rev() { if let Some(name) = m.name(db) { - s.push_str(&format!("{}::", name.to_smol_str())); + s.push_str(&format!("{}::", name.display_no_db().to_smolstr())); } } - s.push_str(&it.name(db).to_smol_str()); + s.push_str(&it.name(db).display_no_db().to_smolstr()); s } } @@ -259,7 +259,7 @@ fn generate_impl( strukt_params.clone(), strukt_params.map(|params| params.to_generic_args()), delegee.is_auto(db), - make::ty(&delegee.name(db).to_smol_str()), + make::ty(&delegee.name(db).display_no_db().to_smolstr()), strukt_ty, bound_def.where_clause(), ast_strukt.where_clause(), @@ -349,7 +349,8 @@ fn generate_impl( let type_gen_args = strukt_params.clone().map(|params| params.to_generic_args()); - let path_type = make::ty(&trait_.name(db).to_smol_str()).clone_for_update(); + let path_type = + make::ty(&trait_.name(db).display_no_db().to_smolstr()).clone_for_update(); transform_impl(ctx, ast_strukt, &old_impl, &transform_args, path_type.syntax())?; // 3) Generate delegate trait impl diff --git a/crates/ide-assists/src/handlers/move_module_to_file.rs b/crates/ide-assists/src/handlers/move_module_to_file.rs index 9af8411f4c..802dca9fad 100644 --- a/crates/ide-assists/src/handlers/move_module_to_file.rs +++ b/crates/ide-assists/src/handlers/move_module_to_file.rs @@ -1,7 +1,7 @@ use std::iter; use ast::edit::IndentLevel; -use hir::HasAttrs; +use hir::{sym, HasAttrs}; use ide_db::base_db::AnchoredPathBuf; use itertools::Itertools; use stdx::format_to; @@ -57,7 +57,7 @@ pub(crate) fn move_module_to_file(acc: &mut Assists, ctx: &AssistContext<'_>) -> if !parent_module.is_mod_rs(db) && parent_module .attrs(db) - .by_key("path") + .by_key(&sym::path) .string_value_unescape() .is_none() => { diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs index ee27d8611e..414b096ad4 100644 --- a/crates/ide-completion/src/completions.rs +++ b/crates/ide-completion/src/completions.rs @@ -26,7 +26,7 @@ use std::iter; use hir::{sym, HasAttrs, ImportPathConfig, Name, ScopeDef, Variant}; use ide_db::{imports::import_assets::LocatedImport, RootDatabase, SymbolKind}; -use syntax::{ast, SmolStr}; +use syntax::{ast, SmolStr, ToSmolStr}; use crate::{ context::{ @@ -541,13 +541,21 @@ impl Completions { } pub(crate) fn add_lifetime(&mut self, ctx: &CompletionContext<'_>, name: hir::Name) { - CompletionItem::new(SymbolKind::LifetimeParam, ctx.source_range(), name.to_smol_str()) - .add_to(self, ctx.db) + CompletionItem::new( + SymbolKind::LifetimeParam, + ctx.source_range(), + name.display_no_db().to_smolstr(), + ) + .add_to(self, ctx.db) } pub(crate) fn add_label(&mut self, ctx: &CompletionContext<'_>, name: hir::Name) { - CompletionItem::new(SymbolKind::Label, ctx.source_range(), name.to_smol_str()) - .add_to(self, ctx.db) + CompletionItem::new( + SymbolKind::Label, + ctx.source_range(), + name.display_no_db().to_smolstr(), + ) + .add_to(self, ctx.db) } pub(crate) fn add_variant_pat( diff --git a/crates/ide-completion/src/completions/attribute/derive.rs b/crates/ide-completion/src/completions/attribute/derive.rs index 90dac1902a..0127a42824 100644 --- a/crates/ide-completion/src/completions/attribute/derive.rs +++ b/crates/ide-completion/src/completions/attribute/derive.rs @@ -2,7 +2,7 @@ use hir::ScopeDef; use ide_db::{documentation::HasDocs, SymbolKind}; use itertools::Itertools; -use syntax::SmolStr; +use syntax::{SmolStr, ToSmolStr}; use crate::{ context::{CompletionContext, ExistingDerives, PathCompletionCtx, Qualified}, @@ -62,7 +62,7 @@ pub(crate) fn complete_derive_path( _ => return acc.add_macro(ctx, path_ctx, mac, name), }; - let name_ = name.to_smol_str(); + let name_ = name.display_no_db().to_smolstr(); let find = DEFAULT_DERIVE_DEPENDENCIES .iter() .find(|derive_completion| derive_completion.label == name_); @@ -75,7 +75,7 @@ pub(crate) fn complete_derive_path( !existing_derives .iter() .map(|it| it.name(ctx.db)) - .any(|it| it.to_smol_str() == dependency) + .any(|it| it.display_no_db().to_smolstr() == dependency) }, )); let lookup = components.join(", "); diff --git a/crates/ide-completion/src/completions/extern_crate.rs b/crates/ide-completion/src/completions/extern_crate.rs index b67d82c20d..2427f4e49f 100644 --- a/crates/ide-completion/src/completions/extern_crate.rs +++ b/crates/ide-completion/src/completions/extern_crate.rs @@ -2,6 +2,7 @@ use hir::Name; use ide_db::{documentation::HasDocs, SymbolKind}; +use syntax::ToSmolStr; use crate::{context::CompletionContext, CompletionItem, CompletionItemKind}; @@ -18,7 +19,7 @@ pub(crate) fn complete_extern_crate(acc: &mut Completions, ctx: &CompletionConte let mut item = CompletionItem::new( CompletionItemKind::SymbolKind(SymbolKind::Module), ctx.source_range(), - name.to_smol_str(), + name.display_no_db().to_smolstr(), ); item.set_documentation(module.docs(ctx.db)); diff --git a/crates/ide-completion/src/completions/flyimport.rs b/crates/ide-completion/src/completions/flyimport.rs index 3a8b9c0cb9..e803072fa8 100644 --- a/crates/ide-completion/src/completions/flyimport.rs +++ b/crates/ide-completion/src/completions/flyimport.rs @@ -5,7 +5,7 @@ use ide_db::imports::{ insert_use::ImportScope, }; use itertools::Itertools; -use syntax::{ast, AstNode, SyntaxNode, T}; +use syntax::{ast, AstNode, SyntaxNode, ToSmolStr, T}; use crate::{ context::{ @@ -424,7 +424,7 @@ fn compute_fuzzy_completion_order_key( cov_mark::hit!(certain_fuzzy_order_test); let import_name = match proposed_mod_path.segments().last() { // FIXME: nasty alloc, this is a hot path! - Some(name) => name.to_smol_str().to_ascii_lowercase(), + Some(name) => name.display_no_db().to_smolstr().to_ascii_lowercase(), None => return usize::MAX, }; match import_name.match_indices(user_input_lowercased).next() { diff --git a/crates/ide-completion/src/completions/format_string.rs b/crates/ide-completion/src/completions/format_string.rs index 559a9bcba2..23affc3659 100644 --- a/crates/ide-completion/src/completions/format_string.rs +++ b/crates/ide-completion/src/completions/format_string.rs @@ -3,7 +3,7 @@ use hir::{ModuleDef, ScopeDef}; use ide_db::{syntax_helpers::format_string::is_format_string, SymbolKind}; use itertools::Itertools; -use syntax::{ast, AstToken, TextRange, TextSize}; +use syntax::{ast, AstToken, TextRange, TextSize, ToSmolStr}; use crate::{context::CompletionContext, CompletionItem, CompletionItemKind, Completions}; @@ -32,8 +32,12 @@ pub(crate) fn format_string( let source_range = TextRange::new(brace_offset, cursor); ctx.locals.iter().sorted_by_key(|&(k, _)| k.clone()).for_each(|(name, _)| { - CompletionItem::new(CompletionItemKind::Binding, source_range, name.to_smol_str()) - .add_to(acc, ctx.db); + CompletionItem::new( + CompletionItemKind::Binding, + source_range, + name.display_no_db().to_smolstr(), + ) + .add_to(acc, ctx.db); }); ctx.scope.process_all_names(&mut |name, scope| { if let ScopeDef::ModuleDef(module_def) = scope { @@ -46,7 +50,7 @@ pub(crate) fn format_string( CompletionItem::new( CompletionItemKind::SymbolKind(symbol_kind), source_range, - name.to_smol_str(), + name.display_no_db().to_smolstr(), ) .add_to(acc, ctx.db); } diff --git a/crates/ide-completion/src/completions/item_list/trait_impl.rs b/crates/ide-completion/src/completions/item_list/trait_impl.rs index c48672e80a..f9dc62562f 100644 --- a/crates/ide-completion/src/completions/item_list/trait_impl.rs +++ b/crates/ide-completion/src/completions/item_list/trait_impl.rs @@ -38,7 +38,7 @@ use ide_db::{ }; use syntax::{ ast::{self, edit_in_place::AttrsOwnerEdit, HasTypeBounds}, - format_smolstr, AstNode, SmolStr, SyntaxElement, SyntaxKind, TextRange, T, + format_smolstr, AstNode, SmolStr, SyntaxElement, SyntaxKind, TextRange, ToSmolStr, T, }; use text_edit::TextEdit; @@ -252,7 +252,7 @@ fn add_type_alias_impl( type_alias: hir::TypeAlias, impl_def: hir::Impl, ) { - let alias_name = type_alias.name(ctx.db).unescaped().to_smol_str(); + let alias_name = type_alias.name(ctx.db).unescaped().display(ctx.db).to_smolstr(); let label = format_smolstr!("type {alias_name} ="); @@ -314,7 +314,7 @@ fn add_const_impl( const_: hir::Const, impl_def: hir::Impl, ) { - let const_name = const_.name(ctx.db).map(|n| n.to_smol_str()); + let const_name = const_.name(ctx.db).map(|n| n.display_no_db().to_smolstr()); if let Some(const_name) = const_name { if let Some(source) = ctx.sema.source(const_) { diff --git a/crates/ide-completion/src/completions/lifetime.rs b/crates/ide-completion/src/completions/lifetime.rs index f31352f49f..03fe93c563 100644 --- a/crates/ide-completion/src/completions/lifetime.rs +++ b/crates/ide-completion/src/completions/lifetime.rs @@ -8,7 +8,7 @@ //! show up for normal completions, or they won't show completions other than lifetimes depending //! on the fixture input. use hir::{sym, Name, ScopeDef}; -use syntax::{ast, TokenText}; +use syntax::{ast, ToSmolStr, TokenText}; use crate::{ completions::Completions, @@ -41,7 +41,7 @@ pub(crate) fn complete_lifetime( if matches!( res, ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) - if param_lifetime != Some(&*name.to_smol_str()) + if param_lifetime != Some(&*name.display_no_db().to_smolstr()) ) { acc.add_lifetime(ctx, name); } diff --git a/crates/ide-completion/src/completions/mod_.rs b/crates/ide-completion/src/completions/mod_.rs index f307ba9eb3..c0333b1d0a 100644 --- a/crates/ide-completion/src/completions/mod_.rs +++ b/crates/ide-completion/src/completions/mod_.rs @@ -7,7 +7,7 @@ use ide_db::{ base_db::{SourceDatabaseExt, VfsPath}, FxHashSet, RootDatabase, SymbolKind, }; -use syntax::{ast, AstNode, SyntaxKind}; +use syntax::{ast, AstNode, SyntaxKind, ToSmolStr}; use crate::{context::CompletionContext, CompletionItem, Completions}; @@ -139,7 +139,7 @@ fn directory_to_look_for_submodules( module_chain_to_containing_module_file(module, db) .into_iter() .filter_map(|module| module.name(db)) - .try_fold(base_directory, |path, name| path.join(&name.to_smol_str())) + .try_fold(base_directory, |path, name| path.join(&name.display_no_db().to_smolstr())) } fn module_chain_to_containing_module_file( diff --git a/crates/ide-completion/src/completions/use_.rs b/crates/ide-completion/src/completions/use_.rs index 5fe6cd0e90..8e5b55360d 100644 --- a/crates/ide-completion/src/completions/use_.rs +++ b/crates/ide-completion/src/completions/use_.rs @@ -48,7 +48,7 @@ pub(crate) fn complete_use_path( let unknown_is_current = |name: &hir::Name| { matches!( name_ref, - Some(name_ref) if name_ref.syntax().text() == name.to_smol_str().as_str() + Some(name_ref) if name_ref.syntax().text() == name.as_str() ) }; for (name, def) in module_scope { diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs index 5782a4423a..55f39440ee 100644 --- a/crates/ide-completion/src/context.rs +++ b/crates/ide-completion/src/context.rs @@ -519,7 +519,7 @@ impl CompletionContext<'_> { I: hir::HasAttrs + Copy, { let attrs = item.attrs(self.db); - attrs.doc_aliases().collect() + attrs.doc_aliases().map(|it| it.as_str().into()).collect() } /// Check if an item is `#[doc(hidden)]`. @@ -543,7 +543,7 @@ impl CompletionContext<'_> { /// Whether the given trait is an operator trait or not. pub(crate) fn is_ops_trait(&self, trait_: hir::Trait) -> bool { match trait_.attrs(self.db).lang() { - Some(lang) => OP_TRAIT_LANG_NAMES.contains(&lang), + Some(lang) => OP_TRAIT_LANG_NAMES.contains(&lang.as_str()), None => false, } } @@ -643,7 +643,7 @@ impl CompletionContext<'_> { pub(crate) fn doc_aliases_in_scope(&self, scope_def: ScopeDef) -> Vec<SmolStr> { if let Some(attrs) = scope_def.attrs(self.db) { - attrs.doc_aliases().collect() + attrs.doc_aliases().map(|it| it.as_str().into()).collect() } else { vec![] } diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index 15c20f1186..abcff62341 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -10,14 +10,14 @@ pub(crate) mod type_alias; pub(crate) mod union_literal; pub(crate) mod variant; -use hir::{AsAssocItem, HasAttrs, HirDisplay, ImportPathConfig, ModuleDef, ScopeDef, Type}; +use hir::{sym, AsAssocItem, HasAttrs, HirDisplay, ImportPathConfig, ModuleDef, ScopeDef, Type}; use ide_db::{ documentation::{Documentation, HasDocs}, helpers::item_name, imports::import_assets::LocatedImport, RootDatabase, SnippetCap, SymbolKind, }; -use syntax::{ast, format_smolstr, AstNode, SmolStr, SyntaxKind, TextRange}; +use syntax::{ast, format_smolstr, AstNode, SmolStr, SyntaxKind, TextRange, ToSmolStr}; use text_edit::TextEdit; use crate::{ @@ -95,7 +95,7 @@ impl<'a> RenderContext<'a> { fn is_deprecated(&self, def: impl HasAttrs) -> bool { let attrs = def.attrs(self.db()); - attrs.by_key("deprecated").exists() + attrs.by_key(&sym::deprecated).exists() } fn is_deprecated_assoc_item(&self, as_assoc_item: impl AsAssocItem) -> bool { @@ -133,7 +133,8 @@ pub(crate) fn render_field( let db = ctx.db(); let is_deprecated = ctx.is_deprecated(field); let name = field.name(db); - let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str()); + let (name, escaped_name) = + (name.unescaped().display(db).to_smolstr(), name.display_no_db().to_smolstr()); let mut item = CompletionItem::new( SymbolKind::Field, ctx.source_range(), @@ -399,10 +400,10 @@ fn render_resolution_path( let config = completion.config; let requires_import = import_to_add.is_some(); - let name = local_name.to_smol_str(); + let name = local_name.display_no_db().to_smolstr(); let mut item = render_resolution_simple_(ctx, &local_name, import_to_add, resolution); if local_name.is_escaped() { - item.insert_text(local_name.to_smol_str()); + item.insert_text(local_name.display_no_db().to_smolstr()); } // Add `<>` for generic types let type_path_no_ty_args = matches!( @@ -484,8 +485,11 @@ fn render_resolution_simple_( let ctx = ctx.import_to_add(import_to_add); let kind = res_to_kind(resolution); - let mut item = - CompletionItem::new(kind, ctx.source_range(), local_name.unescaped().to_smol_str()); + let mut item = CompletionItem::new( + kind, + ctx.source_range(), + local_name.unescaped().display(db).to_smolstr(), + ); item.set_relevance(ctx.completion_relevance()) .set_documentation(scope_def_docs(db, resolution)) .set_deprecated(scope_def_is_deprecated(&ctx, resolution)); diff --git a/crates/ide-completion/src/render/const_.rs b/crates/ide-completion/src/render/const_.rs index a6a1c79e66..3bfec0de6b 100644 --- a/crates/ide-completion/src/render/const_.rs +++ b/crates/ide-completion/src/render/const_.rs @@ -2,6 +2,7 @@ use hir::{AsAssocItem, HirDisplay}; use ide_db::SymbolKind; +use syntax::ToSmolStr; use crate::{item::CompletionItem, render::RenderContext}; @@ -13,7 +14,8 @@ pub(crate) fn render_const(ctx: RenderContext<'_>, const_: hir::Const) -> Option fn render(ctx: RenderContext<'_>, const_: hir::Const) -> Option<CompletionItem> { let db = ctx.db(); let name = const_.name(db)?; - let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str()); + let (name, escaped_name) = + (name.unescaped().display(db).to_smolstr(), name.display(db).to_smolstr()); let detail = const_.display(db).to_string(); let mut item = CompletionItem::new(SymbolKind::Const, ctx.source_range(), name); @@ -24,7 +26,7 @@ fn render(ctx: RenderContext<'_>, const_: hir::Const) -> Option<CompletionItem> if let Some(actm) = const_.as_assoc_item(db) { if let Some(trt) = actm.container_or_implemented_trait(db) { - item.trait_name(trt.name(db).to_smol_str()); + item.trait_name(trt.name(db).display_no_db().to_smolstr()); } } item.insert_text(escaped_name); diff --git a/crates/ide-completion/src/render/function.rs b/crates/ide-completion/src/render/function.rs index cdfe231701..05b2d0ae38 100644 --- a/crates/ide-completion/src/render/function.rs +++ b/crates/ide-completion/src/render/function.rs @@ -4,7 +4,7 @@ use hir::{db::HirDatabase, AsAssocItem, HirDisplay}; use ide_db::{SnippetCap, SymbolKind}; use itertools::Itertools; use stdx::{format_to, to_lower_snake_case}; -use syntax::{format_smolstr, AstNode, SmolStr}; +use syntax::{format_smolstr, AstNode, SmolStr, ToSmolStr}; use crate::{ context::{CompletionContext, DotAccess, DotAccessKind, PathCompletionCtx, PathKind}, @@ -64,7 +64,7 @@ fn render( ), format_smolstr!("{}.{}", receiver.display(ctx.db()), name.display(ctx.db())), ), - _ => (name.unescaped().to_smol_str(), name.to_smol_str()), + _ => (name.unescaped().display(db).to_smolstr(), name.display(db).to_smolstr()), }; let has_self_param = func.self_param(db).is_some(); let mut item = CompletionItem::new( @@ -148,7 +148,7 @@ fn render( item.set_documentation(ctx.docs(func)) .set_deprecated(ctx.is_deprecated(func) || ctx.is_deprecated_assoc_item(func)) .detail(detail) - .lookup_by(name.unescaped().to_smol_str()); + .lookup_by(name.unescaped().display(db).to_smolstr()); if let Some((cap, (self_param, params))) = complete_call_parens { add_call_parens(&mut item, completion, cap, call, escaped_call, self_param, params); @@ -161,7 +161,7 @@ fn render( None => { if let Some(actm) = assoc_item { if let Some(trt) = actm.container_or_implemented_trait(db) { - item.trait_name(trt.name(db).to_smol_str()); + item.trait_name(trt.name(db).display_no_db().to_smolstr()); } } } @@ -219,7 +219,7 @@ pub(super) fn add_call_parens<'b>( params.iter().enumerate().format_with(", ", |(index, param), f| { match param.name(ctx.db) { Some(n) => { - let smol_str = n.to_smol_str(); + let smol_str = n.display_no_db().to_smolstr(); let text = smol_str.as_str().trim_start_matches('_'); let ref_ = ref_of_param(ctx, text, param.ty()); f(&format_args!("${{{}:{ref_}{text}}}", index + offset)) diff --git a/crates/ide-completion/src/render/macro_.rs b/crates/ide-completion/src/render/macro_.rs index a6c8c0e853..de715bcbfa 100644 --- a/crates/ide-completion/src/render/macro_.rs +++ b/crates/ide-completion/src/render/macro_.rs @@ -2,7 +2,7 @@ use hir::HirDisplay; use ide_db::{documentation::Documentation, SymbolKind}; -use syntax::{format_smolstr, SmolStr}; +use syntax::{format_smolstr, SmolStr, ToSmolStr}; use crate::{ context::{PathCompletionCtx, PathKind, PatternContext}, @@ -46,7 +46,8 @@ fn render( ctx.source_range() }; - let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str()); + let (name, escaped_name) = + (name.unescaped().display(ctx.db()).to_smolstr(), name.display(ctx.db()).to_smolstr()); let docs = ctx.docs(macro_); let docs_str = docs.as_ref().map(Documentation::as_str).unwrap_or_default(); let is_fn_like = macro_.is_fn_like(completion.db); diff --git a/crates/ide-completion/src/render/pattern.rs b/crates/ide-completion/src/render/pattern.rs index 942670be2a..598b8762b6 100644 --- a/crates/ide-completion/src/render/pattern.rs +++ b/crates/ide-completion/src/render/pattern.rs @@ -3,7 +3,7 @@ use hir::{db::HirDatabase, Name, StructKind}; use ide_db::{documentation::HasDocs, SnippetCap}; use itertools::Itertools; -use syntax::SmolStr; +use syntax::{SmolStr, ToSmolStr}; use crate::{ context::{ParamContext, ParamKind, PathCompletionCtx, PatternContext}, @@ -31,7 +31,8 @@ pub(crate) fn render_struct_pat( } let name = local_name.unwrap_or_else(|| strukt.name(ctx.db())); - let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str()); + let (name, escaped_name) = + (name.unescaped().display(ctx.db()).to_smolstr(), name.display(ctx.db()).to_smolstr()); let kind = strukt.kind(ctx.db()); let label = format_literal_label(name.as_str(), kind, ctx.snippet_cap()); let lookup = format_literal_lookup(name.as_str(), kind); @@ -63,7 +64,11 @@ pub(crate) fn render_variant_pat( ), None => { let name = local_name.unwrap_or_else(|| variant.name(ctx.db())); - (name.unescaped().to_smol_str(), name.to_smol_str()) + let it = ( + name.unescaped().display(ctx.db()).to_smolstr(), + name.display(ctx.db()).to_smolstr(), + ); + it } }; @@ -184,7 +189,7 @@ fn render_record_as_pat( None => { format!( "{name} {{ {}{} }}", - fields.map(|field| field.name(db).to_smol_str()).format(", "), + fields.map(|field| field.name(db).display_no_db().to_smolstr()).format(", "), if fields_omitted { ", .." } else { "" }, name = name ) diff --git a/crates/ide-completion/src/render/type_alias.rs b/crates/ide-completion/src/render/type_alias.rs index 47254e6a18..b81caf2422 100644 --- a/crates/ide-completion/src/render/type_alias.rs +++ b/crates/ide-completion/src/render/type_alias.rs @@ -2,7 +2,7 @@ use hir::{AsAssocItem, HirDisplay}; use ide_db::SymbolKind; -use syntax::SmolStr; +use syntax::{SmolStr, ToSmolStr}; use crate::{item::CompletionItem, render::RenderContext}; @@ -32,11 +32,11 @@ fn render( let name = type_alias.name(db); let (name, escaped_name) = if with_eq { ( - SmolStr::from_iter([&name.unescaped().to_smol_str(), " = "]), - SmolStr::from_iter([&name.to_smol_str(), " = "]), + SmolStr::from_iter([&name.unescaped().display(db).to_smolstr(), " = "]), + SmolStr::from_iter([&name.display_no_db().to_smolstr(), " = "]), ) } else { - (name.unescaped().to_smol_str(), name.to_smol_str()) + (name.unescaped().display(db).to_smolstr(), name.display_no_db().to_smolstr()) }; let detail = type_alias.display(db).to_string(); @@ -48,7 +48,7 @@ fn render( if let Some(actm) = type_alias.as_assoc_item(db) { if let Some(trt) = actm.container_or_implemented_trait(db) { - item.trait_name(trt.name(db).to_smol_str()); + item.trait_name(trt.name(db).display_no_db().to_smolstr()); } } item.insert_text(escaped_name); diff --git a/crates/ide-completion/src/render/union_literal.rs b/crates/ide-completion/src/render/union_literal.rs index 93e943dbed..ca7593c122 100644 --- a/crates/ide-completion/src/render/union_literal.rs +++ b/crates/ide-completion/src/render/union_literal.rs @@ -3,6 +3,7 @@ use hir::{HirDisplay, Name, StructKind}; use ide_db::SymbolKind; use itertools::Itertools; +use syntax::ToSmolStr; use crate::{ render::{ @@ -26,8 +27,12 @@ pub(crate) fn render_union_literal( (name.unescaped().display(ctx.db()).to_string(), name.display(ctx.db()).to_string()) } }; - let label = format_literal_label(&name.to_smol_str(), StructKind::Record, ctx.snippet_cap()); - let lookup = format_literal_lookup(&name.to_smol_str(), StructKind::Record); + let label = format_literal_label( + &name.display_no_db().to_smolstr(), + StructKind::Record, + ctx.snippet_cap(), + ); + let lookup = format_literal_lookup(&name.display_no_db().to_smolstr(), StructKind::Record); let mut item = CompletionItem::new( CompletionItemKind::SymbolKind(SymbolKind::Union), ctx.source_range(), @@ -47,7 +52,10 @@ pub(crate) fn render_union_literal( format!( "{} {{ ${{1|{}|}}: ${{2:()}} }}$0", escaped_qualified_name, - fields.iter().map(|field| field.name(ctx.db()).to_smol_str()).format(",") + fields + .iter() + .map(|field| field.name(ctx.db()).display_no_db().to_smolstr()) + .format(",") ) } else { format!( diff --git a/crates/ide-completion/src/render/variant.rs b/crates/ide-completion/src/render/variant.rs index 28238de455..bc2df9e39f 100644 --- a/crates/ide-completion/src/render/variant.rs +++ b/crates/ide-completion/src/render/variant.rs @@ -1,7 +1,7 @@ //! Code common to structs, unions, and enum variants. use crate::context::CompletionContext; -use hir::{db::HirDatabase, HasAttrs, HasCrate, HasVisibility, HirDisplay, StructKind}; +use hir::{db::HirDatabase, sym, HasAttrs, HasCrate, HasVisibility, HirDisplay, StructKind}; use ide_db::SnippetCap; use itertools::Itertools; use syntax::SmolStr; @@ -86,7 +86,7 @@ pub(crate) fn visible_fields( .copied() .collect::<Vec<_>>(); let has_invisible_field = n_fields - fields.len() > 0; - let is_foreign_non_exhaustive = item.attrs(ctx.db).by_key("non_exhaustive").exists() + let is_foreign_non_exhaustive = item.attrs(ctx.db).by_key(&sym::non_exhaustive).exists() && item.krate(ctx.db) != module.krate(); let fields_omitted = has_invisible_field || is_foreign_non_exhaustive; Some((fields, fields_omitted)) diff --git a/crates/ide-db/src/defs.rs b/crates/ide-db/src/defs.rs index a53c156b5d..991bef344a 100644 --- a/crates/ide-db/src/defs.rs +++ b/crates/ide-db/src/defs.rs @@ -17,7 +17,7 @@ use hir::{ use stdx::{format_to, impl_from}; use syntax::{ ast::{self, AstNode}, - match_ast, SyntaxKind, SyntaxNode, SyntaxToken, + match_ast, SyntaxKind, SyntaxNode, SyntaxToken, ToSmolStr, }; use crate::documentation::{Documentation, HasDocs}; @@ -670,7 +670,7 @@ impl NameRefClass { hir::AssocItem::TypeAlias(it) => Some(it), _ => None, }) - .find(|alias| alias.name(sema.db).to_smol_str() == name_ref.text().as_str()) + .find(|alias| alias.name(sema.db).display_no_db().to_smolstr() == name_ref.text().as_str()) { return Some(NameRefClass::Definition(Definition::TypeAlias(ty))); } diff --git a/crates/ide-db/src/documentation.rs b/crates/ide-db/src/documentation.rs index 1b9b78f691..5e443badf9 100644 --- a/crates/ide-db/src/documentation.rs +++ b/crates/ide-db/src/documentation.rs @@ -2,7 +2,7 @@ use either::Either; use hir::{ db::{DefDatabase, HirDatabase}, - resolve_doc_path_on, AttrId, AttrSourceMap, AttrsWithOwner, HasAttrs, InFile, + resolve_doc_path_on, sym, AttrId, AttrSourceMap, AttrsWithOwner, HasAttrs, InFile, }; use itertools::Itertools; use syntax::{ @@ -92,7 +92,7 @@ pub fn docs_with_rangemap( attrs: &AttrsWithOwner, ) -> Option<(Documentation, DocsRangeMap)> { let docs = attrs - .by_key("doc") + .by_key(&sym::doc) .attrs() .filter_map(|attr| attr.string_value_unescape().map(|s| (s, attr.id))); let indent = doc_indent(attrs); @@ -134,7 +134,7 @@ pub fn docs_with_rangemap( } pub fn docs_from_attrs(attrs: &hir::Attrs) -> Option<String> { - let docs = attrs.by_key("doc").attrs().filter_map(|attr| attr.string_value_unescape()); + let docs = attrs.by_key(&sym::doc).attrs().filter_map(|attr| attr.string_value_unescape()); let indent = doc_indent(attrs); let mut buf = String::new(); for doc in docs { @@ -270,7 +270,7 @@ fn get_doc_string_in_attr(it: &ast::Attr) -> Option<ast::String> { fn doc_indent(attrs: &hir::Attrs) -> usize { let mut min = !0; - for val in attrs.by_key("doc").attrs().filter_map(|attr| attr.string_value_unescape()) { + for val in attrs.by_key(&sym::doc).attrs().filter_map(|attr| attr.string_value_unescape()) { if let Some(m) = val.lines().filter_map(|line| line.chars().position(|c| !c.is_whitespace())).min() { diff --git a/crates/ide-db/src/famous_defs.rs b/crates/ide-db/src/famous_defs.rs index 51ac0b7191..1a16a567f3 100644 --- a/crates/ide-db/src/famous_defs.rs +++ b/crates/ide-db/src/famous_defs.rs @@ -2,6 +2,7 @@ use base_db::{CrateOrigin, LangCrateOrigin, SourceDatabase}; use hir::{Crate, Enum, Function, Macro, Module, ScopeDef, Semantics, Trait}; +use syntax::ToSmolStr; use crate::RootDatabase; @@ -198,15 +199,18 @@ impl FamousDefs<'_, '_> { for segment in path { module = module.children(db).find_map(|child| { let name = child.name(db)?; - if name.to_smol_str() == segment { + if name.display_no_db().to_smolstr() == segment { Some(child) } else { None } })?; } - let def = - module.scope(db, None).into_iter().find(|(name, _def)| name.to_smol_str() == trait_)?.1; + let def = module + .scope(db, None) + .into_iter() + .find(|(name, _def)| name.display_no_db().to_smolstr() == trait_)? + .1; Some(def) } } diff --git a/crates/ide-db/src/helpers.rs b/crates/ide-db/src/helpers.rs index c069e1c25b..0e7ee13717 100644 --- a/crates/ide-db/src/helpers.rs +++ b/crates/ide-db/src/helpers.rs @@ -6,7 +6,7 @@ use base_db::{FileId, SourceDatabaseExt}; use hir::{Crate, DescendPreference, ItemInNs, ModuleDef, Name, Semantics}; use syntax::{ ast::{self, make}, - AstToken, SyntaxKind, SyntaxToken, TokenAtOffset, + AstToken, SyntaxKind, SyntaxToken, ToSmolStr, TokenAtOffset, }; use crate::{ @@ -50,9 +50,9 @@ pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path { } segments.extend( - path.segments() - .iter() - .map(|segment| make::path_segment(make::name_ref(&segment.to_smol_str()))), + path.segments().iter().map(|segment| { + make::path_segment(make::name_ref(&segment.display_no_db().to_smolstr())) + }), ); make::path_from_segments(segments, is_abs) } diff --git a/crates/ide-db/src/imports/import_assets.rs b/crates/ide-db/src/imports/import_assets.rs index 38cb4a162c..3bb5ac1b10 100644 --- a/crates/ide-db/src/imports/import_assets.rs +++ b/crates/ide-db/src/imports/import_assets.rs @@ -9,7 +9,7 @@ use itertools::{EitherOrBoth, Itertools}; use rustc_hash::{FxHashMap, FxHashSet}; use syntax::{ ast::{self, make, HasName}, - AstNode, SmolStr, SyntaxNode, + AstNode, SmolStr, SyntaxNode, ToSmolStr, }; use crate::{ @@ -459,7 +459,7 @@ fn find_import_for_segment( unresolved_first_segment: &str, ) -> Option<ItemInNs> { let segment_is_name = item_name(db, original_item) - .map(|name| name.to_smol_str() == unresolved_first_segment) + .map(|name| name.display_no_db().to_smolstr() == unresolved_first_segment) .unwrap_or(false); Some(if segment_is_name { @@ -483,7 +483,7 @@ fn module_with_segment_name( }; while let Some(module) = current_module { if let Some(module_name) = module.name(db) { - if module_name.to_smol_str() == segment_name { + if module_name.display_no_db().to_smolstr() == segment_name { return Some(module); } } diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs index e1cfe04898..b7b8c5a66f 100644 --- a/crates/ide-db/src/search.rs +++ b/crates/ide-db/src/search.rs @@ -8,14 +8,14 @@ use std::mem; use base_db::{salsa::Database, FileId, FileRange, SourceDatabase, SourceDatabaseExt}; use hir::{ - AsAssocItem, DefWithBody, DescendPreference, HasAttrs, HasSource, HirFileIdExt, InFile, + sym, AsAssocItem, DefWithBody, DescendPreference, HasAttrs, HasSource, HirFileIdExt, InFile, InRealFile, ModuleSource, PathResolution, Semantics, Visibility, }; use memchr::memmem::Finder; use nohash_hasher::IntMap; use once_cell::unsync::Lazy; use parser::SyntaxKind; -use syntax::{ast, match_ast, AstNode, AstToken, SyntaxElement, TextRange, TextSize}; +use syntax::{ast, match_ast, AstNode, AstToken, SyntaxElement, TextRange, TextSize, ToSmolStr}; use triomphe::Arc; use crate::{ @@ -333,7 +333,7 @@ impl Definition { if let Definition::Macro(macro_def) = self { return match macro_def.kind(db) { hir::MacroKind::Declarative => { - if macro_def.attrs(db).by_key("macro_export").exists() { + if macro_def.attrs(db).by_key(&sym::macro_export).exists() { SearchScope::reverse_dependencies(db, module.krate()) } else { SearchScope::krate(db, module.krate()) @@ -456,7 +456,7 @@ impl<'a> FindUsages<'a> { module .krate() .display_name(self.sema.db) - .map(|crate_name| crate_name.crate_name().as_smol_str().clone()) + .map(|crate_name| crate_name.crate_name().symbol().as_str().into()) } _ => { let self_kw_refs = || { @@ -468,7 +468,10 @@ impl<'a> FindUsages<'a> { }; // We need to unescape the name in case it is written without "r#" in earlier // editions of Rust where it isn't a keyword. - self.def.name(sema.db).or_else(self_kw_refs).map(|it| it.unescaped().to_smol_str()) + self.def + .name(sema.db) + .or_else(self_kw_refs) + .map(|it| it.unescaped().display(sema.db).to_smolstr()) } }; let name = match &name { diff --git a/crates/ide-db/src/ty_filter.rs b/crates/ide-db/src/ty_filter.rs index 46f47f258b..5b566c5067 100644 --- a/crates/ide-db/src/ty_filter.rs +++ b/crates/ide-db/src/ty_filter.rs @@ -5,7 +5,10 @@ use std::iter; use hir::Semantics; -use syntax::ast::{self, make, Pat}; +use syntax::{ + ast::{self, make, Pat}, + ToSmolStr, +}; use crate::RootDatabase; @@ -26,7 +29,7 @@ impl TryEnum { _ => return None, }; TryEnum::ALL.iter().find_map(|&var| { - if enum_.name(sema.db).to_smol_str() == var.type_name() { + if enum_.name(sema.db).display_no_db().to_smolstr() == var.type_name() { return Some(var); } None diff --git a/crates/ide-db/src/use_trivial_constructor.rs b/crates/ide-db/src/use_trivial_constructor.rs index a915391ad9..965f432407 100644 --- a/crates/ide-db/src/use_trivial_constructor.rs +++ b/crates/ide-db/src/use_trivial_constructor.rs @@ -1,7 +1,10 @@ //! Functionality for generating trivial constructors use hir::StructKind; -use syntax::ast::{make, Expr, Path}; +use syntax::{ + ast::{make, Expr, Path}, + ToSmolStr, +}; /// given a type return the trivial constructor (if one exists) pub fn use_trivial_constructor( @@ -15,7 +18,9 @@ pub fn use_trivial_constructor( if variant.kind(db) == hir::StructKind::Unit { let path = make::path_qualified( path, - make::path_segment(make::name_ref(&variant.name(db).to_smol_str())), + make::path_segment(make::name_ref( + &variant.name(db).display_no_db().to_smolstr(), + )), ); return Some(make::expr_path(path)); diff --git a/crates/ide-diagnostics/src/handlers/missing_fields.rs b/crates/ide-diagnostics/src/handlers/missing_fields.rs index a41bf457a9..ea7908525a 100644 --- a/crates/ide-diagnostics/src/handlers/missing_fields.rs +++ b/crates/ide-diagnostics/src/handlers/missing_fields.rs @@ -11,7 +11,7 @@ use stdx::format_to; use syntax::{ algo, ast::{self, make}, - AstNode, SyntaxNode, SyntaxNodePtr, + AstNode, SyntaxNode, SyntaxNodePtr, ToSmolStr, }; use text_edit::TextEdit; @@ -146,7 +146,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass } }; let field = make::record_expr_field( - make::name_ref(&f.name(ctx.sema.db).to_smol_str()), + make::name_ref(&f.name(ctx.sema.db).display_no_db().to_smolstr()), field_expr, ); new_field_list.add_field(field.clone_for_update()); @@ -160,7 +160,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass let new_field_list = old_field_list.clone_for_update(); for (f, _) in missing_fields.iter() { let field = make::record_pat_field_shorthand(make::name_ref( - &f.name(ctx.sema.db).to_smol_str(), + &f.name(ctx.sema.db).display_no_db().to_smolstr(), )); new_field_list.add_field(field.clone_for_update()); } diff --git a/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs b/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs index 8c50960684..6d756484eb 100644 --- a/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs +++ b/crates/ide-diagnostics/src/handlers/trait_impl_redundant_assoc_item.rs @@ -4,6 +4,7 @@ use ide_db::{ label::Label, source_change::SourceChangeBuilder, }; +use syntax::ToSmolStr; use text_edit::TextRange; use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext}; @@ -21,7 +22,7 @@ pub(crate) fn trait_impl_redundant_assoc_item( let assoc_item = d.assoc_item.1; let default_range = d.impl_.syntax_node_ptr().text_range(); - let trait_name = d.trait_.name(db).to_smol_str(); + let trait_name = d.trait_.name(db).display_no_db().to_smolstr(); let (redundant_item_name, diagnostic_range, redundant_item_def) = match assoc_item { hir::AssocItem::Function(id) => { @@ -45,7 +46,10 @@ pub(crate) fn trait_impl_redundant_assoc_item( ( format!("`type {redundant_assoc_item_name}`"), type_alias.source(db).map(|it| it.syntax().text_range()).unwrap_or(default_range), - format!("\n type {};", type_alias.name(ctx.sema.db).to_smol_str()), + format!( + "\n type {};", + type_alias.name(ctx.sema.db).display_no_db().to_smolstr() + ), ) } }; diff --git a/crates/ide-diagnostics/src/handlers/unlinked_file.rs b/crates/ide-diagnostics/src/handlers/unlinked_file.rs index 77ffd0fd96..2c90577120 100644 --- a/crates/ide-diagnostics/src/handlers/unlinked_file.rs +++ b/crates/ide-diagnostics/src/handlers/unlinked_file.rs @@ -11,7 +11,7 @@ use ide_db::{ use paths::Utf8Component; use syntax::{ ast::{self, edit::IndentLevel, HasModuleItem, HasName}, - AstNode, TextRange, + AstNode, TextRange, ToSmolStr, }; use text_edit::TextEdit; @@ -106,7 +106,8 @@ fn fixes(ctx: &DiagnosticsContext<'_>, file_id: FileId) -> Option<Vec<Assist>> { // shouldn't occur _ => continue 'crates, }; - match current.children.iter().find(|(name, _)| name.to_smol_str() == seg) { + match current.children.iter().find(|(name, _)| name.display_no_db().to_smolstr() == seg) + { Some((_, &child)) => current = &crate_def_map[child], None => continue 'crates, } @@ -156,7 +157,11 @@ fn fixes(ctx: &DiagnosticsContext<'_>, file_id: FileId) -> Option<Vec<Assist>> { // try finding a parent that has an inline tree from here on let mut current = module; for s in stack.iter().rev() { - match module.children.iter().find(|(name, _)| name.to_smol_str() == s) { + match module + .children + .iter() + .find(|(name, _)| name.display_no_db().to_smolstr() == s) + { Some((_, child)) => { current = &crate_def_map[*child]; } diff --git a/crates/ide-diagnostics/src/handlers/unresolved_method.rs b/crates/ide-diagnostics/src/handlers/unresolved_method.rs index 46722f43d4..41f4b57508 100644 --- a/crates/ide-diagnostics/src/handlers/unresolved_method.rs +++ b/crates/ide-diagnostics/src/handlers/unresolved_method.rs @@ -7,7 +7,7 @@ use ide_db::{ }; use syntax::{ ast::{self, make, HasArgList}, - AstNode, SmolStr, TextRange, + format_smolstr, AstNode, SmolStr, TextRange, ToSmolStr, }; use text_edit::TextEdit; @@ -154,14 +154,16 @@ fn assoc_func_fix(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedMethodCall) - _ => false, }; - let mut receiver_type_adt_name = receiver_type.as_adt()?.name(db).to_smol_str().to_string(); + let mut receiver_type_adt_name = + receiver_type.as_adt()?.name(db).display_no_db().to_smolstr(); let generic_parameters: Vec<SmolStr> = receiver_type.generic_parameters(db).collect(); // if receiver should be pass as first arg in the assoc func, // we could omit generic parameters cause compiler can deduce it automatically if !need_to_take_receiver_as_first_arg && !generic_parameters.is_empty() { let generic_parameters = generic_parameters.join(", "); - receiver_type_adt_name = format!("{receiver_type_adt_name}::<{generic_parameters}>"); + receiver_type_adt_name = + format_smolstr!("{receiver_type_adt_name}::<{generic_parameters}>"); } let method_name = call.name_ref()?; diff --git a/crates/ide-ssr/src/resolving.rs b/crates/ide-ssr/src/resolving.rs index d3c1af1f31..9feb096677 100644 --- a/crates/ide-ssr/src/resolving.rs +++ b/crates/ide-ssr/src/resolving.rs @@ -238,7 +238,7 @@ impl<'db> ResolutionScope<'db> { None, |assoc_item| { let item_name = assoc_item.name(self.scope.db)?; - if item_name.to_smol_str().as_str() == name.text() { + if item_name.as_str() == name.text() { Some(hir::PathResolution::Def(assoc_item.into())) } else { None diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index f42613637b..7214c89a1e 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs @@ -11,7 +11,8 @@ use stdx::format_to; use url::Url; use hir::{ - db::HirDatabase, Adt, AsAssocItem, AssocItem, AssocItemContainer, DescendPreference, HasAttrs, + db::HirDatabase, sym, Adt, AsAssocItem, AssocItem, AssocItemContainer, DescendPreference, + HasAttrs, }; use ide_db::{ base_db::{CrateOrigin, LangCrateOrigin, ReleaseChannel, SourceDatabase}, @@ -593,12 +594,14 @@ fn filename_and_frag_for_def( }, Definition::Module(m) => match m.name(db) { // `#[doc(keyword = "...")]` is internal used only by rust compiler - Some(name) => match m.attrs(db).by_key("doc").find_string_value_in_tt("keyword") { - Some(kw) => { - format!("keyword.{}.html", kw.trim_matches('"')) + Some(name) => { + match m.attrs(db).by_key(&sym::doc).find_string_value_in_tt(&sym::keyword) { + Some(kw) => { + format!("keyword.{}.html", kw) + } + None => format!("{}/index.html", name.display(db.upcast())), } - None => format!("{}/index.html", name.display(db.upcast())), - }, + } None => String::from("index.html"), }, Definition::Trait(t) => format!("trait.{}.html", t.name(db).display(db.upcast())), diff --git a/crates/ide/src/fetch_crates.rs b/crates/ide/src/fetch_crates.rs index 14c2655f84..712615c49a 100644 --- a/crates/ide/src/fetch_crates.rs +++ b/crates/ide/src/fetch_crates.rs @@ -38,5 +38,5 @@ fn crate_info(data: &ide_db::base_db::CrateData) -> CrateInfo { } fn crate_name(data: &ide_db::base_db::CrateData) -> Option<String> { - data.display_name.as_ref().map(|it| it.canonical_name().to_owned()) + data.display_name.as_ref().map(|it| it.canonical_name().as_str().to_owned()) } diff --git a/crates/ide/src/inlay_hints/implicit_drop.rs b/crates/ide/src/inlay_hints/implicit_drop.rs index 31f0c79037..fcfbbbd626 100644 --- a/crates/ide/src/inlay_hints/implicit_drop.rs +++ b/crates/ide/src/inlay_hints/implicit_drop.rs @@ -14,7 +14,7 @@ use ide_db::{base_db::FileRange, RootDatabase}; use syntax::{ ast::{self, AstNode}, - match_ast, + match_ast, ToSmolStr, }; use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind}; @@ -88,7 +88,7 @@ pub(super) fn hints( .and_then(|d| { Some(FileRange { file_id: d.file_id.file_id()?, range: d.value.text_range() }) }); - let name = binding.name.to_smol_str(); + let name = binding.name.display_no_db().to_smolstr(); if name.starts_with("<ra@") { continue; // Ignore desugared variables } diff --git a/crates/ide/src/inlay_hints/param_name.rs b/crates/ide/src/inlay_hints/param_name.rs index 2e2a64c552..01d8dfbc78 100644 --- a/crates/ide/src/inlay_hints/param_name.rs +++ b/crates/ide/src/inlay_hints/param_name.rs @@ -10,7 +10,10 @@ use hir::{Callable, Semantics}; use ide_db::{base_db::FileRange, RootDatabase}; use stdx::to_lower_snake_case; -use syntax::ast::{self, AstNode, HasArgList, HasName, UnaryOp}; +use syntax::{ + ast::{self, AstNode, HasArgList, HasName, UnaryOp}, + ToSmolStr, +}; use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, InlayKind}; @@ -118,7 +121,7 @@ fn should_hide_param_name_hint( } let fn_name = match callable.kind() { - hir::CallableKind::Function(it) => Some(it.name(sema.db).to_smol_str()), + hir::CallableKind::Function(it) => Some(it.name(sema.db).display_no_db().to_smolstr()), _ => None, }; let fn_name = fn_name.as_deref(); diff --git a/crates/ide/src/moniker.rs b/crates/ide/src/moniker.rs index 68854c33ce..81d5b52796 100644 --- a/crates/ide/src/moniker.rs +++ b/crates/ide/src/moniker.rs @@ -408,7 +408,7 @@ pub(crate) fn def_to_moniker( }), ), }; - PackageInformation { name, repo, version } + PackageInformation { name: name.as_str().to_owned(), repo, version } }, }) } diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs index bfd62e7624..21b32f776d 100644 --- a/crates/ide/src/navigation_target.rs +++ b/crates/ide/src/navigation_target.rs @@ -17,7 +17,7 @@ use ide_db::{ use stdx::never; use syntax::{ ast::{self, HasName}, - format_smolstr, AstNode, SmolStr, SyntaxNode, TextRange, + format_smolstr, AstNode, SmolStr, SyntaxNode, TextRange, ToSmolStr, }; /// `NavigationTarget` represents an element in the editor's UI which you can @@ -98,7 +98,7 @@ impl NavigationTarget { db: &RootDatabase, module: hir::Module, ) -> UpmappingResult<NavigationTarget> { - let name = module.name(db).map(|it| it.to_smol_str()).unwrap_or_default(); + let name = module.name(db).map(|it| it.display_no_db().to_smolstr()).unwrap_or_default(); match module.declaration_source(db) { Some(InFile { value, file_id }) => { orig_range_with_focus(db, file_id, value.syntax(), value.name()).map( @@ -190,7 +190,7 @@ impl TryToNav for FileSymbol { .is_alias .then(|| self.def.name(db)) .flatten() - .map_or_else(|| self.name.clone(), |it| it.to_smol_str()), + .map_or_else(|| self.name.clone(), |it| it.display_no_db().to_smolstr()), alias: self.is_alias.then(|| self.name.clone()), kind: Some(hir::ModuleDefId::from(self.def).into()), full_range, @@ -274,9 +274,9 @@ pub(crate) trait ToNavFromAst: Sized { fn container_name(db: &RootDatabase, t: impl HasContainer) -> Option<SmolStr> { match t.container(db) { - hir::ItemContainer::Trait(it) => Some(it.name(db).to_smol_str()), + hir::ItemContainer::Trait(it) => Some(it.name(db).display_no_db().to_smolstr()), // FIXME: Handle owners of blocks correctly here - hir::ItemContainer::Module(it) => it.name(db).map(|name| name.to_smol_str()), + hir::ItemContainer::Module(it) => it.name(db).map(|name| name.display_no_db().to_smolstr()), _ => None, } } @@ -367,7 +367,7 @@ impl ToNav for hir::Module { fn to_nav(&self, db: &RootDatabase) -> UpmappingResult<NavigationTarget> { let InFile { file_id, value } = self.definition_source(db); - let name = self.name(db).map(|it| it.to_smol_str()).unwrap_or_default(); + let name = self.name(db).map(|it| it.display_no_db().to_smolstr()).unwrap_or_default(); let (syntax, focus) = match &value { ModuleSource::SourceFile(node) => (node.syntax(), None), ModuleSource::Module(node) => (node.syntax(), node.name()), @@ -424,7 +424,10 @@ impl TryToNav for hir::ExternCrateDecl { |(FileRange { file_id, range: full_range }, focus_range)| { let mut res = NavigationTarget::from_syntax( file_id, - self.alias_or_name(db).unwrap_or_else(|| self.name(db)).to_smol_str(), + self.alias_or_name(db) + .unwrap_or_else(|| self.name(db)) + .display_no_db() + .to_smolstr(), focus_range, full_range, SymbolKind::Module, @@ -532,7 +535,7 @@ impl ToNav for LocalSource { orig_range_with_focus(db, file_id, node, name).map( |(FileRange { file_id, range: full_range }, focus_range)| { - let name = local.name(db).to_smol_str(); + let name = local.name(db).display_no_db().to_smolstr(); let kind = if local.is_self(db) { SymbolKind::SelfParam } else if local.is_param(db) { @@ -565,7 +568,7 @@ impl ToNav for hir::Local { impl TryToNav for hir::Label { fn try_to_nav(&self, db: &RootDatabase) -> Option<UpmappingResult<NavigationTarget>> { let InFile { file_id, value } = self.source(db)?; - let name = self.name(db).to_smol_str(); + let name = self.name(db).display_no_db().to_smolstr(); Some(orig_range_with_focus(db, file_id, value.syntax(), value.lifetime()).map( |(FileRange { file_id, range: full_range }, focus_range)| NavigationTarget { @@ -586,7 +589,7 @@ impl TryToNav for hir::Label { impl TryToNav for hir::TypeParam { fn try_to_nav(&self, db: &RootDatabase) -> Option<UpmappingResult<NavigationTarget>> { let InFile { file_id, value } = self.merge().source(db)?; - let name = self.name(db).to_smol_str(); + let name = self.name(db).display_no_db().to_smolstr(); let value = match value { Either::Left(ast::TypeOrConstParam::Type(x)) => Either::Left(x), @@ -628,7 +631,7 @@ impl TryToNav for hir::TypeOrConstParam { impl TryToNav for hir::LifetimeParam { fn try_to_nav(&self, db: &RootDatabase) -> Option<UpmappingResult<NavigationTarget>> { let InFile { file_id, value } = self.source(db)?; - let name = self.name(db).to_smol_str(); + let name = self.name(db).display_no_db().to_smolstr(); Some(orig_range(db, file_id, value.syntax()).map( |(FileRange { file_id, range: full_range }, focus_range)| NavigationTarget { @@ -649,7 +652,7 @@ impl TryToNav for hir::LifetimeParam { impl TryToNav for hir::ConstParam { fn try_to_nav(&self, db: &RootDatabase) -> Option<UpmappingResult<NavigationTarget>> { let InFile { file_id, value } = self.merge().source(db)?; - let name = self.name(db).to_smol_str(); + let name = self.name(db).display_no_db().to_smolstr(); let value = match value { Either::Left(ast::TypeOrConstParam::Const(x)) => x, diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs index 3d08e2f371..e5f8632871 100644 --- a/crates/ide/src/rename.rs +++ b/crates/ide/src/rename.rs @@ -16,6 +16,7 @@ use itertools::Itertools; use stdx::{always, never}; use syntax::{ ast, utils::is_raw_identifier, AstNode, SmolStr, SyntaxKind, SyntaxNode, TextRange, TextSize, + ToSmolStr, }; use text_edit::TextEdit; @@ -266,7 +267,7 @@ fn find_definitions( // if the name differs from the definitions name it has to be an alias if def .name(sema.db) - .map_or(false, |it| it.to_smol_str() != name_ref.text().as_str()) + .map_or(false, |it| it.display_no_db().to_smolstr() != name_ref.text().as_str()) { Err(format_err!("Renaming aliases is currently unsupported")) } else { diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index 362d3238a9..f309b98f58 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs @@ -19,7 +19,7 @@ use span::TextSize; use stdx::{always, format_to}; use syntax::{ ast::{self, AstNode}, - SmolStr, SyntaxNode, + SmolStr, SyntaxNode, ToSmolStr, }; use crate::{references, FileId, NavigationTarget, ToNav, TryToNav}; @@ -332,7 +332,7 @@ pub(crate) fn runnable_fn( }; canonical_path .map(TestId::Path) - .unwrap_or(TestId::Name(def.name(sema.db).to_smol_str())) + .unwrap_or(TestId::Name(def.name(sema.db).display_no_db().to_smolstr())) }; if def.is_test(sema.db) { @@ -481,7 +481,8 @@ fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option<Runnable> { Some(path) })(); - let test_id = path.map_or_else(|| TestId::Name(def_name.to_smol_str()), TestId::Path); + let test_id = + path.map_or_else(|| TestId::Name(def_name.display_no_db().to_smolstr()), TestId::Path); let mut nav = match def { Definition::Module(def) => NavigationTarget::from_module_to_decl(db, def), diff --git a/crates/ide/src/signature_help.rs b/crates/ide/src/signature_help.rs index c5eaacdb10..fe6688c053 100644 --- a/crates/ide/src/signature_help.rs +++ b/crates/ide/src/signature_help.rs @@ -19,7 +19,7 @@ use syntax::{ algo, ast::{self, AstChildren, HasArgList}, match_ast, AstNode, Direction, NodeOrToken, SyntaxElementChildren, SyntaxNode, SyntaxToken, - TextRange, TextSize, T, + TextRange, TextSize, ToSmolStr, T, }; use crate::RootDatabase; @@ -379,7 +379,7 @@ fn add_assoc_type_bindings( for item in tr.items_with_supertraits(db) { if let AssocItem::TypeAlias(ty) = item { - let name = ty.name(db).to_smol_str(); + let name = ty.name(db).display_no_db().to_smolstr(); if !present_bindings.contains(&*name) { buf.clear(); format_to!(buf, "{} = …", name); diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs index f9b8a22a3c..c80bb7413f 100644 --- a/crates/ide/src/syntax_highlighting/inject.rs +++ b/crates/ide/src/syntax_highlighting/inject.rs @@ -3,7 +3,7 @@ use std::mem; use either::Either; -use hir::{InFile, Semantics}; +use hir::{sym, InFile, Semantics}; use ide_db::{ active_parameter::ActiveParameter, base_db::FileId, defs::Definition, documentation::docs_with_rangemap, rust_doc::is_rust_fence, SymbolKind, @@ -153,7 +153,7 @@ pub(super) fn doc_comment( let mut new_comments = Vec::new(); let mut string; - for attr in attributes.by_key("doc").attrs() { + for attr in attributes.by_key(&sym::doc).attrs() { let InFile { file_id, value: src } = attrs_source_map.source_of(attr); if file_id != src_file_id { continue; @@ -271,7 +271,7 @@ fn find_doc_string_in_attr(attr: &hir::Attr, it: &ast::Attr) -> Option<ast::Stri // #[cfg_attr(..., doc = "", ...)] None => { // We gotta hunt the string token manually here - let text = attr.string_value()?; + let text = attr.string_value()?.as_str(); // FIXME: We just pick the first string literal that has the same text as the doc attribute // This means technically we might highlight the wrong one it.syntax() diff --git a/crates/intern/src/symbol/symbols.rs b/crates/intern/src/symbol/symbols.rs index 04c70e4fae..1454d825b7 100644 --- a/crates/intern/src/symbol/symbols.rs +++ b/crates/intern/src/symbol/symbols.rs @@ -12,7 +12,7 @@ use crate::{ }; macro_rules! define_symbols { - (@WITH_NAME: $($alias:ident = $value:literal),* $(,)? @PLAIN: $($name:ident),* $(,)?) => { + (@WITH_NAME: $($alias:ident = $value:literal,)* @PLAIN: $($name:ident,)*) => { // Ideally we would be emitting `const` here, but then we no longer have stable addresses // which is what we are relying on for equality! In the future if consts can refer to // statics we should swap these for `const`s and have the the string literal being pointed @@ -56,15 +56,6 @@ macro_rules! define_symbols { define_symbols! { @WITH_NAME: - __empty = "", - unsafe_ = "unsafe", - in_ = "in", - super_ = "super", - self_ = "self", - Self_ = "Self", - tick_static = "'static", - dollar_crate = "$crate", - MISSING_NAME = "[missing name]", INTEGER_0 = "0", INTEGER_1 = "1", INTEGER_2 = "2", @@ -81,6 +72,15 @@ define_symbols! { INTEGER_13 = "13", INTEGER_14 = "14", INTEGER_15 = "15", + __empty = "", + unsafe_ = "unsafe", + in_ = "in", + super_ = "super", + self_ = "self", + Self_ = "Self", + tick_static = "'static", + dollar_crate = "$crate", + MISSING_NAME = "[missing name]", fn_ = "fn", crate_ = "crate", underscore = "_", @@ -88,16 +88,43 @@ define_symbols! { false_ = "false", let_ = "let", const_ = "const", + proc_dash_macro = "proc-macro", + aapcs_dash_unwind = "aapcs-unwind", + avr_dash_interrupt = "avr-interrupt", + avr_dash_non_dash_blocking_dash_interrupt = "avr-non-blocking-interrupt", + C_dash_cmse_dash_nonsecure_dash_call = "C-cmse-nonsecure-call", + C_dash_unwind = "C-unwind", + cdecl_dash_unwind = "cdecl-unwind", + fastcall_dash_unwind = "fastcall-unwind", + msp430_dash_interrupt = "msp430-interrupt", + platform_dash_intrinsic = "platform-intrinsic", + ptx_dash_kernel = "ptx-kernel", + riscv_dash_interrupt_dash_m = "riscv-interrupt-m", + riscv_dash_interrupt_dash_s = "riscv-interrupt-s", + rust_dash_call = "rust-call", + rust_dash_cold = "rust-cold", + rust_dash_intrinsic = "rust-intrinsic", + stdcall_dash_unwind = "stdcall-unwind", + system_dash_unwind = "system-unwind", + sysv64_dash_unwind = "sysv64-unwind", + thiscall_dash_unwind = "thiscall-unwind", + vectorcall_dash_unwind = "vectorcall-unwind", + win64_dash_unwind = "win64-unwind", + x86_dash_interrupt = "x86-interrupt", @PLAIN: __ra_fixup, + aapcs, add_assign, add, + alias, align_offset, align, all, alloc_layout, alloc, + allow_internal_unsafe, + allow, any, as_str, asm, @@ -122,6 +149,7 @@ define_symbols! { call_mut, call_once, call, + cdecl, Center, cfg_accessible, cfg_attr, @@ -154,6 +182,7 @@ define_symbols! { Debug, default, Default, + deprecated, deref_mut, deref_target, deref, @@ -168,6 +197,7 @@ define_symbols! { drop_in_place, drop, dyn_metadata, + efiapi, eh_catch_typeinfo, eh_personality, env, @@ -176,10 +206,12 @@ define_symbols! { Err, exchange_malloc, exhaustive_patterns, + export_name, f128, f16, f32, f64, + fastcall, feature, file, filter_map, @@ -203,6 +235,7 @@ define_symbols! { from_residual, from_usize, from_yeet, + fundamental, future_trait, future, Future, @@ -213,6 +246,7 @@ define_symbols! { gt, Hash, hidden, + html_root_url, i128, i16, i32, @@ -238,6 +272,8 @@ define_symbols! { iter_mut, iter, Iterator, + keyword, + lang, le, Left, len, @@ -246,8 +282,12 @@ define_symbols! { local_inner_macros, log_syntax, lt, + macro_export, macro_rules, + macro_use, + main, manually_drop, + may_dangle, maybe_uninit, metadata_type, min_exhaustive_patterns, @@ -273,7 +313,9 @@ define_symbols! { new, next, no_core, + no_mangle, no_std, + non_exhaustive, none, None, not, @@ -305,6 +347,7 @@ define_symbols! { partial_ord, PartialEq, PartialOrd, + path, Pending, phantom_data, pieces, @@ -313,7 +356,11 @@ define_symbols! { pointer_like, poll, Poll, + prelude_import, prelude, + proc_macro_attribute, + proc_macro_derive, + proc_macro, quote, range_inclusive_new, Range, @@ -329,6 +376,7 @@ define_symbols! { register_tool, rem_assign, rem, + repr, result, Result, ResumeTy, @@ -338,8 +386,20 @@ define_symbols! { rust_2021, rust_2024, rust_analyzer, + Rust, + rustc_allow_incoherent_impl, + rustc_builtin_macro, rustc_coherence_is_core, + rustc_const_panic_str, + rustc_deprecated_safe_2024, + rustc_has_incoherent_inherent_impls, + rustc_layout_scalar_valid_range_end, + rustc_layout_scalar_valid_range_start, + rustc_legacy_const_generics, rustc_macro_transparency, + rustc_reservation_impl, + rustc_safe_intrinsic, + rustc_skip_array_during_method_dispatch, semitransparent, shl_assign, shl, @@ -352,6 +412,7 @@ define_symbols! { start, std_panic, std, + stdcall, str, string, String, @@ -361,10 +422,13 @@ define_symbols! { sub_assign, sub, sync, + system, + sysv64, Target, termination, test_case, test, + thiscall, trace_macros, transmute_opts, transmute_trait, @@ -376,6 +440,7 @@ define_symbols! { u32, u64, u8, + unadjusted, Unknown, unpin, unreachable_2015, @@ -383,7 +448,11 @@ define_symbols! { unreachable, unsafe_cell, unsize, + unstable, usize, v1, - va_list + va_list, + vectorcall, + wasm, + win64, } diff --git a/crates/load-cargo/Cargo.toml b/crates/load-cargo/Cargo.toml index b6f90ec53b..64ed93bbb1 100644 --- a/crates/load-cargo/Cargo.toml +++ b/crates/load-cargo/Cargo.toml @@ -27,6 +27,7 @@ span.workspace = true tt.workspace = true vfs-notify.workspace = true vfs.workspace = true +intern.workspace = true [features] in-rust-tree = ["hir-expand/in-rust-tree"] diff --git a/crates/load-cargo/src/lib.rs b/crates/load-cargo/src/lib.rs index de68b86714..b7ddbc9665 100644 --- a/crates/load-cargo/src/lib.rs +++ b/crates/load-cargo/src/lib.rs @@ -428,14 +428,19 @@ fn expander_to_proc_macro( expander: proc_macro_api::ProcMacro, ignored_macros: &[Box<str>], ) -> ProcMacro { - let name = From::from(expander.name()); + let name = expander.name(); let kind = match expander.kind() { proc_macro_api::ProcMacroKind::CustomDerive => ProcMacroKind::CustomDerive, proc_macro_api::ProcMacroKind::Bang => ProcMacroKind::Bang, proc_macro_api::ProcMacroKind::Attr => ProcMacroKind::Attr, }; - let disabled = ignored_macros.iter().any(|replace| **replace == name); - ProcMacro { name, kind, expander: sync::Arc::new(Expander(expander)), disabled } + let disabled = ignored_macros.iter().any(|replace| **replace == *name); + ProcMacro { + name: intern::Symbol::intern(name), + kind, + expander: sync::Arc::new(Expander(expander)), + disabled, + } } #[derive(Debug)] diff --git a/crates/project-model/src/project_json.rs b/crates/project-model/src/project_json.rs index 4a916e570b..4b55f9d2b9 100644 --- a/crates/project-model/src/project_json.rs +++ b/crates/project-model/src/project_json.rs @@ -224,6 +224,7 @@ impl ProjectJson { Crate { display_name: crate_data .display_name + .as_deref() .map(CrateDisplayName::from_canonical_name), root_module, edition: crate_data.edition.into(), diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index e006b70362..dd7a11ca85 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -894,7 +894,10 @@ fn project_json_to_crate_graph( .collect(); override_cfg.apply( &mut cfg_options, - display_name.as_ref().map(|it| it.canonical_name()).unwrap_or_default(), + display_name + .as_ref() + .map(|it| it.canonical_name().as_str()) + .unwrap_or_default(), ); let crate_graph_crate_id = crate_graph.add_crate_root( file_id, @@ -917,7 +920,7 @@ fn project_json_to_crate_graph( if *is_proc_macro { if let Some(path) = proc_macro_dylib_path.clone() { let node = Ok(( - display_name.as_ref().map(|it| it.canonical_name().to_owned()), + display_name.as_ref().map(|it| it.canonical_name().as_str().to_owned()), path, )); proc_macros.insert(crate_graph_crate_id, node); @@ -1014,12 +1017,12 @@ fn cargo_to_crate_graph( if pkg_data.is_local { CrateOrigin::Local { repo: pkg_data.repository.clone(), - name: Some(pkg_data.name.clone()), + name: Some(Symbol::intern(&pkg_data.name)), } } else { CrateOrigin::Library { repo: pkg_data.repository.clone(), - name: pkg_data.name.clone(), + name: Symbol::intern(&pkg_data.name), } }, ); @@ -1157,9 +1160,7 @@ fn detached_file_to_crate_graph( return (crate_graph, FxHashMap::default()); } }; - let display_name = detached_file - .file_stem() - .map(|file_stem| CrateDisplayName::from_canonical_name(file_stem.to_owned())); + let display_name = detached_file.file_stem().map(CrateDisplayName::from_canonical_name); let detached_file_crate = crate_graph.add_crate_root( file_id, Edition::CURRENT, @@ -1232,7 +1233,7 @@ fn handle_rustc_crates( file_id, &rustc_workspace[tgt].name, kind, - CrateOrigin::Rustc { name: rustc_workspace[pkg].name.clone() }, + CrateOrigin::Rustc { name: Symbol::intern(&rustc_workspace[pkg].name) }, ); pkg_to_lib_crate.insert(pkg, crate_id); // Add dependencies on core / std / alloc for this crate @@ -1329,7 +1330,7 @@ fn add_target_crate_root( let crate_id = crate_graph.add_crate_root( file_id, edition, - Some(CrateDisplayName::from_canonical_name(cargo_name.to_owned())), + Some(CrateDisplayName::from_canonical_name(cargo_name)), Some(pkg.version.to_string()), Arc::new(cfg_options), potential_cfg_options.map(Arc::new), @@ -1402,7 +1403,7 @@ fn sysroot_to_crate_graph( // patch the origin if c.origin.is_local() { let lang_crate = LangCrateOrigin::from( - c.display_name.as_ref().map_or("", |it| it.canonical_name()), + c.display_name.as_ref().map_or("", |it| it.canonical_name().as_str()), ); c.origin = CrateOrigin::Lang(lang_crate); match lang_crate { @@ -1459,8 +1460,7 @@ fn sysroot_to_crate_graph( .filter_map(|krate| { let file_id = load(&stitched[krate].root)?; - let display_name = - CrateDisplayName::from_canonical_name(stitched[krate].name.clone()); + let display_name = CrateDisplayName::from_canonical_name(&stitched[krate].name); let crate_id = crate_graph.add_crate_root( file_id, Edition::CURRENT, diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index 90316f3b89..a0f1c941dd 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -621,7 +621,7 @@ impl flags::AnalysisStats { module .krate() .display_name(db) - .map(|it| it.canonical_name().to_owned()) + .map(|it| it.canonical_name().as_str().to_owned()) .into_iter() .chain( module @@ -912,7 +912,7 @@ impl flags::AnalysisStats { module .krate() .display_name(db) - .map(|it| it.canonical_name().to_owned()) + .map(|it| it.canonical_name().as_str().to_owned()) .into_iter() .chain( module diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs index 177f48b986..abff16b6f5 100644 --- a/crates/syntax/src/lib.rs +++ b/crates/syntax/src/lib.rs @@ -65,7 +65,7 @@ pub use rowan::{ TokenAtOffset, WalkEvent, }; pub use rustc_lexer::unescape; -pub use smol_str::{format_smolstr, SmolStr}; +pub use smol_str::{format_smolstr, SmolStr, ToSmolStr}; /// `Parse` is the result of the parsing: a syntax tree and a collection of /// errors. diff --git a/crates/test-fixture/src/lib.rs b/crates/test-fixture/src/lib.rs index e910094c77..d9f9fb82be 100644 --- a/crates/test-fixture/src/lib.rs +++ b/crates/test-fixture/src/lib.rs @@ -267,7 +267,7 @@ impl ChangeFixture { let core_crate = crate_graph.add_crate_root( core_file, Edition::CURRENT, - Some(CrateDisplayName::from_canonical_name("core".to_owned())), + Some(CrateDisplayName::from_canonical_name("core")), None, Default::default(), Default::default(), @@ -314,7 +314,7 @@ impl ChangeFixture { let proc_macros_crate = crate_graph.add_crate_root( proc_lib_file, Edition::CURRENT, - Some(CrateDisplayName::from_canonical_name("proc_macros".to_owned())), + Some(CrateDisplayName::from_canonical_name("proc_macros")), None, Default::default(), Default::default(), @@ -370,7 +370,7 @@ pub fn identity(_attr: TokenStream, item: TokenStream) -> TokenStream { "# .into(), ProcMacro { - name: "identity".into(), + name: Symbol::intern("identity"), kind: ProcMacroKind::Attr, expander: sync::Arc::new(IdentityProcMacroExpander), disabled: false, @@ -385,7 +385,7 @@ pub fn derive_identity(item: TokenStream) -> TokenStream { "# .into(), ProcMacro { - name: "DeriveIdentity".into(), + name: Symbol::intern("DeriveIdentity"), kind: ProcMacroKind::CustomDerive, expander: sync::Arc::new(IdentityProcMacroExpander), disabled: false, @@ -400,7 +400,7 @@ pub fn input_replace(attr: TokenStream, _item: TokenStream) -> TokenStream { "# .into(), ProcMacro { - name: "input_replace".into(), + name: Symbol::intern("input_replace"), kind: ProcMacroKind::Attr, expander: sync::Arc::new(AttributeInputReplaceProcMacroExpander), disabled: false, @@ -415,7 +415,7 @@ pub fn mirror(input: TokenStream) -> TokenStream { "# .into(), ProcMacro { - name: "mirror".into(), + name: Symbol::intern("mirror"), kind: ProcMacroKind::Bang, expander: sync::Arc::new(MirrorProcMacroExpander), disabled: false, @@ -430,7 +430,7 @@ pub fn shorten(input: TokenStream) -> TokenStream { "# .into(), ProcMacro { - name: "shorten".into(), + name: Symbol::intern("shorten"), kind: ProcMacroKind::Bang, expander: sync::Arc::new(ShortenProcMacroExpander), disabled: false, @@ -448,7 +448,8 @@ fn filter_test_proc_macros( let mut proc_macros = Vec::new(); for (c, p) in proc_macro_defs { - if !proc_macro_names.iter().any(|name| name == &stdx::to_lower_snake_case(&p.name)) { + if !proc_macro_names.iter().any(|name| name == &stdx::to_lower_snake_case(p.name.as_str())) + { continue; } proc_macros.push(p); @@ -530,7 +531,7 @@ fn parse_crate( let origin = match LangCrateOrigin::from(&*name) { LangCrateOrigin::Other => { - let name = name.clone(); + let name = Symbol::intern(&name); if non_workspace_member { CrateOrigin::Library { repo, name } } else { |