diff --git a/Cargo.lock b/Cargo.lock index afd1bbe6bcc..02490d4a8db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1500,9 +1500,12 @@ checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" [[package]] name = "smol_str" -version = "0.1.18" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b203e79e90905594272c1c97c7af701533d42adaab0beb3859018e477d54a3b0" +checksum = "61d15c83e300cce35b7c8cd39ff567c1ef42dde6d4a1a38dbdbf9a59902261bd" +dependencies = [ + "serde", +] [[package]] name = "snap" diff --git a/crates/cfg/src/lib.rs b/crates/cfg/src/lib.rs index 417ba609197..f867a903b01 100644 --- a/crates/cfg/src/lib.rs +++ b/crates/cfg/src/lib.rs @@ -66,24 +66,21 @@ impl CfgOptions { } } - pub fn get_cfg_keys(&self) -> Vec<&SmolStr> { - self.enabled - .iter() - .map(|x| match x { - CfgAtom::Flag(key) => key, - CfgAtom::KeyValue { key, .. } => key, - }) - .collect() + pub fn get_cfg_keys(&self) -> impl Iterator { + self.enabled.iter().map(|x| match x { + CfgAtom::Flag(key) => key, + CfgAtom::KeyValue { key, .. } => key, + }) } - pub fn get_cfg_values(&self, cfg_key: &str) -> Vec<&SmolStr> { - self.enabled - .iter() - .filter_map(|x| match x { - CfgAtom::KeyValue { key, value } if cfg_key == key => Some(value), - _ => None, - }) - .collect() + pub fn get_cfg_values<'a>( + &'a self, + cfg_key: &'a str, + ) -> impl Iterator + 'a { + self.enabled.iter().filter_map(move |x| match x { + CfgAtom::KeyValue { key, value } if cfg_key == key => Some(value), + _ => None, + }) } } diff --git a/crates/ide_completion/src/completions/attribute.rs b/crates/ide_completion/src/completions/attribute.rs index 2482418ae6a..e86f38aaa41 100644 --- a/crates/ide_completion/src/completions/attribute.rs +++ b/crates/ide_completion/src/completions/attribute.rs @@ -104,7 +104,7 @@ fn complete_new_attribute(acc: &mut Completions, ctx: &CompletionContext, attrib let mut item = CompletionItem::new( CompletionItemKind::Attribute, ctx.source_range(), - name.to_string(), + name.to_smol_str(), ); if let Some(docs) = mac.docs(ctx.sema.db) { item.documentation(docs); diff --git a/crates/ide_completion/src/completions/attribute/cfg.rs b/crates/ide_completion/src/completions/attribute/cfg.rs index c83e1718ece..1a10531a1bd 100644 --- a/crates/ide_completion/src/completions/attribute/cfg.rs +++ b/crates/ide_completion/src/completions/attribute/cfg.rs @@ -31,13 +31,11 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext) { Some("target_endian") => ["little", "big"].into_iter().for_each(add_completion), Some(name) => { if let Some(krate) = ctx.krate { - krate.potential_cfg(ctx.db).get_cfg_values(&name).iter().for_each(|s| { - let mut item = CompletionItem::new( - CompletionItemKind::Attribute, - ctx.source_range(), - s.as_str(), - ); - item.insert_text(format!(r#""{}""#, s)); + krate.potential_cfg(ctx.db).get_cfg_values(&name).cloned().for_each(|s| { + let insert_text = format!(r#""{}""#, s); + let mut item = + CompletionItem::new(CompletionItemKind::Attribute, ctx.source_range(), s); + item.insert_text(insert_text); acc.add(item.build()); }) @@ -45,12 +43,9 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext) { } None => { if let Some(krate) = ctx.krate { - krate.potential_cfg(ctx.db).get_cfg_keys().iter().for_each(|s| { - let item = CompletionItem::new( - CompletionItemKind::Attribute, - ctx.source_range(), - s.as_str(), - ); + krate.potential_cfg(ctx.db).get_cfg_keys().cloned().for_each(|s| { + let item = + CompletionItem::new(CompletionItemKind::Attribute, ctx.source_range(), s); acc.add(item.build()); }) } diff --git a/crates/ide_completion/src/completions/attribute/derive.rs b/crates/ide_completion/src/completions/attribute/derive.rs index 33b84819325..b9032318ece 100644 --- a/crates/ide_completion/src/completions/attribute/derive.rs +++ b/crates/ide_completion/src/completions/attribute/derive.rs @@ -3,7 +3,7 @@ use hir::{HasAttrs, MacroDef, MacroKind}; use ide_db::helpers::{import_assets::ImportAssets, insert_use::ImportScope, FamousDefs}; use itertools::Itertools; use rustc_hash::FxHashSet; -use syntax::{ast, SyntaxKind}; +use syntax::{ast, SmolStr, SyntaxKind}; use crate::{ completions::flyimport::compute_fuzzy_completion_order_key, @@ -30,7 +30,6 @@ pub(super) fn complete_derive( } let name = name.to_smol_str(); - let label; let (label, lookup) = match core.zip(mac.module(ctx.db).map(|it| it.krate())) { // show derive dependencies for `core`/`std` derives Some((core, mac_krate)) if core == mac_krate => { @@ -48,13 +47,13 @@ pub(super) fn complete_derive( }, )); let lookup = components.join(", "); - label = components.iter().rev().join(", "); - (label.as_str(), Some(lookup)) + let label = Itertools::intersperse(components.into_iter().rev(), ", "); + (SmolStr::from_iter(label), Some(lookup)) } else { - (&*name, None) + (name, None) } } - _ => (&*name, None), + _ => (name, None), }; let mut item = @@ -68,7 +67,7 @@ pub(super) fn complete_derive( item.add_to(acc); } - flyimport_attribute(ctx, acc); + flyimport_attribute(acc, ctx); } fn get_derives_in_scope(ctx: &CompletionContext) -> Vec<(hir::Name, MacroDef)> { @@ -83,7 +82,7 @@ fn get_derives_in_scope(ctx: &CompletionContext) -> Vec<(hir::Name, MacroDef)> { result } -fn flyimport_attribute(ctx: &CompletionContext, acc: &mut Completions) -> Option<()> { +fn flyimport_attribute(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { if ctx.token.kind() != SyntaxKind::IDENT { return None; }; @@ -115,7 +114,7 @@ fn flyimport_attribute(ctx: &CompletionContext, acc: &mut Completions) -> Option let mut item = CompletionItem::new( CompletionItemKind::Attribute, ctx.source_range(), - mac.name(ctx.db)?.to_string(), + mac.name(ctx.db)?.to_smol_str(), ); item.add_import(ImportEdit { import, scope: import_scope.clone() }); if let Some(docs) = mac.docs(ctx.db) { diff --git a/crates/ide_completion/src/completions/fn_param.rs b/crates/ide_completion/src/completions/fn_param.rs index e910c1daaad..5acda464982 100644 --- a/crates/ide_completion/src/completions/fn_param.rs +++ b/crates/ide_completion/src/completions/fn_param.rs @@ -30,6 +30,7 @@ pub(crate) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext) } func.param_list().into_iter().flat_map(|it| it.params()).for_each(|param| { if let Some(pat) = param.pat() { + // FIXME: We should be able to turn these into SmolStr without having to allocate a String let text = param.syntax().text().to_string(); let lookup = pat.syntax().text().to_string(); params.entry(text).or_insert(lookup); @@ -59,7 +60,7 @@ pub(crate) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext) let self_completion_items = ["self", "&self", "mut self", "&mut self"]; if ctx.impl_def.is_some() && me?.param_list()?.params().next().is_none() { - self_completion_items.iter().for_each(|self_item| { + self_completion_items.into_iter().for_each(|self_item| { add_new_item_to_acc(ctx, acc, self_item.to_string(), self_item.to_string()) }); } diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs index afb8df29116..36d25d5d029 100644 --- a/crates/ide_completion/src/completions/keyword.rs +++ b/crates/ide_completion/src/completions/keyword.rs @@ -27,7 +27,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte return; } - let mut add_keyword = |kw, snippet| add_keyword(ctx, acc, kw, snippet); + let mut add_keyword = |kw, snippet| add_keyword(acc, ctx, kw, snippet); let expects_assoc_item = ctx.expects_assoc_item(); let has_block_expr_parent = ctx.has_block_expr_parent(); @@ -157,7 +157,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte ) } -fn add_keyword(ctx: &CompletionContext, acc: &mut Completions, kw: &str, snippet: &str) { +fn add_keyword(acc: &mut Completions, ctx: &CompletionContext, kw: &str, snippet: &str) { let mut item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), kw); match ctx.config.snippet_cap { diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs index e9d39edc43a..385bf59cde4 100644 --- a/crates/ide_completion/src/completions/qualified_path.rs +++ b/crates/ide_completion/src/completions/qualified_path.rs @@ -93,7 +93,7 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon if ctx.in_use_tree() { if let hir::ScopeDef::Unknown = def { if let Some(ast::NameLike::NameRef(name_ref)) = ctx.name_syntax.as_ref() { - if name_ref.syntax().text() == name.to_string().as_str() { + if name_ref.syntax().text() == name.to_smol_str().as_str() { // for `use self::foo$0`, don't suggest `foo` as a completion cov_mark::hit!(dont_complete_current_use); continue; diff --git a/crates/ide_completion/src/completions/trait_impl.rs b/crates/ide_completion/src/completions/trait_impl.rs index fc6ef5839c8..46da7cfa372 100644 --- a/crates/ide_completion/src/completions/trait_impl.rs +++ b/crates/ide_completion/src/completions/trait_impl.rs @@ -133,7 +133,7 @@ fn add_function_impl( func: hir::Function, impl_def: hir::Impl, ) { - let fn_name = func.name(ctx.db).to_string(); + let fn_name = func.name(ctx.db).to_smol_str(); let label = if func.assoc_fn_params(ctx.db).is_empty() { format!("fn {}()", fn_name) @@ -205,12 +205,12 @@ fn add_type_alias_impl( ctx: &CompletionContext, type_alias: hir::TypeAlias, ) { - let alias_name = type_alias.name(ctx.db).to_string(); + let alias_name = type_alias.name(ctx.db).to_smol_str(); let snippet = format!("type {} = ", alias_name); let range = replacement_range(ctx, type_def_node); - let mut item = CompletionItem::new(SymbolKind::TypeAlias, ctx.source_range(), snippet.clone()); + let mut item = CompletionItem::new(SymbolKind::TypeAlias, ctx.source_range(), &snippet); item.text_edit(TextEdit::replace(range, snippet)) .lookup_by(alias_name) .set_documentation(type_alias.docs(ctx.db)); @@ -224,7 +224,7 @@ fn add_const_impl( const_: hir::Const, impl_def: hir::Impl, ) { - let const_name = const_.name(ctx.db).map(|n| n.to_string()); + let const_name = const_.name(ctx.db).map(|n| n.to_smol_str()); if let Some(const_name) = const_name { if let Some(source) = const_.source(ctx.db) { @@ -238,8 +238,7 @@ fn add_const_impl( let snippet = make_const_compl_syntax(&transformed_const); let range = replacement_range(ctx, const_def_node); - let mut item = - CompletionItem::new(SymbolKind::Const, ctx.source_range(), snippet.clone()); + let mut item = CompletionItem::new(SymbolKind::Const, ctx.source_range(), &snippet); item.text_edit(TextEdit::replace(range, snippet)) .lookup_by(const_name) .set_documentation(const_.docs(ctx.db)); diff --git a/crates/ide_completion/src/item.rs b/crates/ide_completion/src/item.rs index 3f0accfbe17..ebe227d260a 100644 --- a/crates/ide_completion/src/item.rs +++ b/crates/ide_completion/src/item.rs @@ -12,8 +12,8 @@ use ide_db::{ SymbolKind, }; use smallvec::SmallVec; -use stdx::{format_to, impl_from, never}; -use syntax::{algo, TextRange}; +use stdx::{impl_from, never}; +use syntax::{algo, SmolStr, TextRange}; use text_edit::TextEdit; /// `CompletionItem` describes a single completion variant in the editor pop-up. @@ -22,7 +22,7 @@ use text_edit::TextEdit; #[derive(Clone)] pub struct CompletionItem { /// Label in the completion pop up which identifies completion. - label: String, + label: SmolStr, /// Range of identifier that is being completed. /// /// It should be used primarily for UI, but we also use this to convert @@ -46,7 +46,7 @@ pub struct CompletionItem { /// /// That is, in `foo.bar$0` lookup of `abracadabra` will be accepted (it /// contains `bar` sub sequence), and `quux` will rejected. - lookup: Option, + lookup: Option, /// Additional info to show in the UI pop up. detail: Option, @@ -268,7 +268,7 @@ impl CompletionItem { pub(crate) fn new( kind: impl Into, source_range: TextRange, - label: impl Into, + label: impl Into, ) -> Builder { let label = label.into(); Builder { @@ -379,13 +379,13 @@ impl ImportEdit { pub(crate) struct Builder { source_range: TextRange, imports_to_add: SmallVec<[ImportEdit; 1]>, - trait_name: Option, - label: String, + trait_name: Option, + label: SmolStr, insert_text: Option, is_snippet: bool, detail: Option, documentation: Option, - lookup: Option, + lookup: Option, kind: CompletionItemKind, text_edit: Option, deprecated: bool, @@ -400,25 +400,21 @@ impl Builder { let mut label = self.label; let mut lookup = self.lookup; - let mut insert_text = self.insert_text; + let insert_text = self.insert_text.unwrap_or_else(|| label.to_string()); if let [import_edit] = &*self.imports_to_add { // snippets can have multiple imports, but normal completions only have up to one if let Some(original_path) = import_edit.import.original_path.as_ref() { lookup = lookup.or_else(|| Some(label.clone())); - insert_text = insert_text.or_else(|| Some(label.clone())); - format_to!(label, " (use {})", original_path) + label = SmolStr::from(format!("{} (use {})", label, original_path)); } } else if let Some(trait_name) = self.trait_name { - insert_text = insert_text.or_else(|| Some(label.clone())); - format_to!(label, " (as {})", trait_name) + label = SmolStr::from(format!("{} (as {})", label, trait_name)); } let text_edit = match self.text_edit { Some(it) => it, - None => { - TextEdit::replace(self.source_range, insert_text.unwrap_or_else(|| label.clone())) - } + None => TextEdit::replace(self.source_range, insert_text), }; CompletionItem { @@ -437,16 +433,16 @@ impl Builder { import_to_add: self.imports_to_add, } } - pub(crate) fn lookup_by(&mut self, lookup: impl Into) -> &mut Builder { + pub(crate) fn lookup_by(&mut self, lookup: impl Into) -> &mut Builder { self.lookup = Some(lookup.into()); self } - pub(crate) fn label(&mut self, label: impl Into) -> &mut Builder { + pub(crate) fn label(&mut self, label: impl Into) -> &mut Builder { self.label = label.into(); self } - pub(crate) fn trait_name(&mut self, trait_name: impl Into) -> &mut Builder { - self.trait_name = Some(trait_name.into()); + pub(crate) fn trait_name(&mut self, trait_name: SmolStr) -> &mut Builder { + self.trait_name = Some(trait_name); self } pub(crate) fn insert_text(&mut self, insert_text: impl Into) -> &mut Builder { diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs index 4180d704a30..5ae52f3cc91 100644 --- a/crates/ide_completion/src/render.rs +++ b/crates/ide_completion/src/render.rs @@ -83,11 +83,11 @@ pub(crate) fn render_field( ty: &hir::Type, ) -> CompletionItem { let is_deprecated = ctx.is_deprecated(field); - let name = field.name(ctx.db()).to_string(); + let name = field.name(ctx.db()).to_smol_str(); let mut item = CompletionItem::new( SymbolKind::Field, ctx.source_range(), - receiver.map_or_else(|| name.clone(), |receiver| format!("{}.{}", receiver, name)), + receiver.map_or_else(|| name.clone(), |receiver| format!("{}.{}", receiver, name).into()), ); item.set_relevance(CompletionRelevance { type_match: compute_type_match(ctx.completion, ty), @@ -97,7 +97,7 @@ pub(crate) fn render_field( item.detail(ty.display(ctx.db()).to_string()) .set_documentation(field.docs(ctx.db())) .set_deprecated(is_deprecated) - .lookup_by(name.as_str()); + .lookup_by(name.clone()); let is_keyword = SyntaxKind::from_keyword(name.as_str()).is_some(); if is_keyword && !matches!(name.as_str(), "self" | "crate" | "super" | "Self") { item.insert_text(format!("r#{}", name)); @@ -199,7 +199,7 @@ fn render_resolution_( let mut item = CompletionItem::new( CompletionItemKind::UnresolvedReference, ctx.source_range(), - local_name.to_string(), + local_name.to_smol_str(), ); if let Some(import_to_add) = import_to_add { item.add_import(import_to_add); @@ -208,7 +208,7 @@ fn render_resolution_( } }; - let local_name = local_name.to_string(); + let local_name = local_name.to_smol_str(); let mut item = CompletionItem::new(kind, ctx.source_range(), local_name.clone()); if let hir::ScopeDef::Local(local) = resolution { let ty = local.ty(ctx.db()); diff --git a/crates/ide_completion/src/render/const_.rs b/crates/ide_completion/src/render/const_.rs index 241e0043c9c..707b6533b54 100644 --- a/crates/ide_completion/src/render/const_.rs +++ b/crates/ide_completion/src/render/const_.rs @@ -2,10 +2,7 @@ use hir::{AsAssocItem, HasSource}; use ide_db::SymbolKind; -use syntax::{ - ast::{Const, HasName}, - display::const_label, -}; +use syntax::{ast::Const, display::const_label}; use crate::{item::CompletionItem, render::RenderContext}; @@ -27,7 +24,7 @@ impl<'a> ConstRender<'a> { } fn render(self) -> Option { - let name = self.name()?; + let name = self.const_.name(self.ctx.db())?.to_smol_str(); let detail = self.detail(); let mut item = @@ -42,7 +39,7 @@ impl<'a> ConstRender<'a> { let db = self.ctx.db(); if let Some(actm) = self.const_.as_assoc_item(db) { if let Some(trt) = actm.containing_trait_or_trait_impl(db) { - item.trait_name(trt.name(db).to_string()); + item.trait_name(trt.name(db).to_smol_str()); item.insert_text(name); } } @@ -50,10 +47,6 @@ impl<'a> ConstRender<'a> { Some(item.build()) } - fn name(&self) -> Option { - self.ast_node.name().map(|name| name.text().to_string()) - } - fn detail(&self) -> String { const_label(&self.ast_node) } diff --git a/crates/ide_completion/src/render/function.rs b/crates/ide_completion/src/render/function.rs index 7515bb6d47d..f598b414a73 100644 --- a/crates/ide_completion/src/render/function.rs +++ b/crates/ide_completion/src/render/function.rs @@ -38,7 +38,7 @@ pub(crate) fn render_method( #[derive(Debug)] struct FunctionRender<'a> { ctx: RenderContext<'a>, - name: String, + name: hir::Name, receiver: Option, func: hir::Function, /// NB: having `ast::Fn` here might or might not be a good idea. The problem @@ -67,7 +67,7 @@ impl<'a> FunctionRender<'a> { fn_: hir::Function, is_method: bool, ) -> Option> { - let name = local_name.unwrap_or_else(|| fn_.name(ctx.db())).to_string(); + let name = local_name.unwrap_or_else(|| fn_.name(ctx.db())); let ast_node = fn_.source(ctx.db())?.value; Some(FunctionRender { ctx, name, receiver, func: fn_, ast_node, is_method }) @@ -77,7 +77,7 @@ impl<'a> FunctionRender<'a> { let params = self.params(); let call = match &self.receiver { Some(receiver) => format!("{}.{}", receiver, &self.name), - None => self.name.clone(), + None => self.name.to_string(), }; let mut item = CompletionItem::new(self.kind(), self.ctx.source_range(), call.clone()); item.set_documentation(self.ctx.docs(self.func)) @@ -91,7 +91,7 @@ impl<'a> FunctionRender<'a> { let db = self.ctx.db(); if let Some(actm) = self.func.as_assoc_item(db) { if let Some(trt) = actm.containing_trait_or_trait_impl(db) { - item.trait_name(trt.name(db).to_string()); + item.trait_name(trt.name(db).to_smol_str()); } } } @@ -99,7 +99,7 @@ impl<'a> FunctionRender<'a> { if let Some(import_to_add) = import_to_add { item.add_import(import_to_add); } - item.lookup_by(self.name); + item.lookup_by(self.name.to_smol_str()); let ret_type = self.func.ret_type(self.ctx.db()); item.set_relevance(CompletionRelevance { diff --git a/crates/ide_completion/src/render/macro_.rs b/crates/ide_completion/src/render/macro_.rs index b1ddfab0cbb..1f76583adbb 100644 --- a/crates/ide_completion/src/render/macro_.rs +++ b/crates/ide_completion/src/render/macro_.rs @@ -2,7 +2,7 @@ use hir::HasSource; use ide_db::SymbolKind; -use syntax::display::macro_label; +use syntax::{display::macro_label, SmolStr}; use crate::{ context::CallKind, @@ -23,7 +23,7 @@ pub(crate) fn render_macro( #[derive(Debug)] struct MacroRender<'a> { ctx: RenderContext<'a>, - name: String, + name: SmolStr, macro_: hir::MacroDef, docs: Option, bra: &'static str, @@ -32,7 +32,7 @@ struct MacroRender<'a> { impl<'a> MacroRender<'a> { fn new(ctx: RenderContext<'a>, name: hir::Name, macro_: hir::MacroDef) -> MacroRender<'a> { - let name = name.to_string(); + let name = name.to_smol_str(); let docs = ctx.docs(macro_); let docs_str = docs.as_ref().map_or("", |s| s.as_str()); let (bra, ket) = guess_macro_braces(&name, docs_str); @@ -47,7 +47,7 @@ impl<'a> MacroRender<'a> { } else { Some(self.ctx.source_range()) }?; - let mut item = CompletionItem::new(SymbolKind::Macro, source_range, &self.label()); + let mut item = CompletionItem::new(SymbolKind::Macro, source_range, self.label()); item.set_documentation(self.docs.clone()) .set_deprecated(self.ctx.is_deprecated(self.macro_)) .set_detail(self.detail()); @@ -72,7 +72,7 @@ impl<'a> MacroRender<'a> { } _ => { cov_mark::hit!(dont_insert_macro_call_parens_unncessary); - item.insert_text(&self.name); + item.insert_text(&*self.name); } }; @@ -84,18 +84,18 @@ impl<'a> MacroRender<'a> { && !matches!(self.ctx.completion.path_call_kind(), Some(CallKind::Mac)) } - fn label(&self) -> String { + fn label(&self) -> SmolStr { if self.needs_bang() && self.ctx.snippet_cap().is_some() { - format!("{}!{}…{}", self.name, self.bra, self.ket) + SmolStr::from_iter([&*self.name, "!", self.bra, "…", self.ket]) } else if self.macro_.kind() == hir::MacroKind::Derive { - self.name.to_string() + self.name.clone() } else { self.banged_name() } } - fn banged_name(&self) -> String { - format!("{}!", self.name) + fn banged_name(&self) -> SmolStr { + SmolStr::from_iter([&*self.name, "!"]) } fn detail(&self) -> Option { diff --git a/crates/ide_completion/src/render/pattern.rs b/crates/ide_completion/src/render/pattern.rs index b7032806204..e553ec8f860 100644 --- a/crates/ide_completion/src/render/pattern.rs +++ b/crates/ide_completion/src/render/pattern.rs @@ -3,6 +3,7 @@ use hir::{db::HirDatabase, HasAttrs, HasVisibility, Name, StructKind}; use ide_db::helpers::SnippetCap; use itertools::Itertools; +use syntax::SmolStr; use crate::{ context::{ParamKind, PatternContext}, @@ -25,7 +26,7 @@ pub(crate) fn render_struct_pat( return None; } - let name = local_name.unwrap_or_else(|| strukt.name(ctx.db())).to_string(); + let name = local_name.unwrap_or_else(|| strukt.name(ctx.db())).to_smol_str(); let pat = render_pat(&ctx, &name, strukt.kind(ctx.db()), &visible_fields, fields_omitted)?; Some(build_completion(ctx, name, pat, strukt)) @@ -43,8 +44,8 @@ pub(crate) fn render_variant_pat( let (visible_fields, fields_omitted) = visible_fields(&ctx, &fields, variant)?; let name = match &path { - Some(path) => path.to_string(), - None => local_name.unwrap_or_else(|| variant.name(ctx.db())).to_string(), + Some(path) => path.to_string().into(), + None => local_name.unwrap_or_else(|| variant.name(ctx.db())).to_smol_str(), }; let pat = render_pat(&ctx, &name, variant.kind(ctx.db()), &visible_fields, fields_omitted)?; @@ -53,7 +54,7 @@ pub(crate) fn render_variant_pat( fn build_completion( ctx: RenderContext<'_>, - name: String, + name: SmolStr, pat: String, def: impl HasAttrs + Copy, ) -> CompletionItem { diff --git a/crates/ide_completion/src/render/struct_literal.rs b/crates/ide_completion/src/render/struct_literal.rs index 4eb4f6b9f12..a70015dcaf6 100644 --- a/crates/ide_completion/src/render/struct_literal.rs +++ b/crates/ide_completion/src/render/struct_literal.rs @@ -3,6 +3,7 @@ use hir::{db::HirDatabase, HasAttrs, HasVisibility, Name, StructKind}; use ide_db::helpers::SnippetCap; use itertools::Itertools; +use syntax::SmolStr; use crate::{render::RenderContext, CompletionItem, CompletionItemKind}; @@ -21,7 +22,7 @@ pub(crate) fn render_struct_literal( return None; } - let name = local_name.unwrap_or_else(|| strukt.name(ctx.db())).to_string(); + let name = local_name.unwrap_or_else(|| strukt.name(ctx.db())).to_smol_str(); let literal = render_literal(&ctx, &name, strukt.kind(ctx.db()), &visible_fields)?; Some(build_completion(ctx, name, literal, strukt)) @@ -29,12 +30,15 @@ pub(crate) fn render_struct_literal( fn build_completion( ctx: RenderContext<'_>, - name: String, + name: SmolStr, literal: String, def: impl HasAttrs + Copy, ) -> CompletionItem { - let mut item = - CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), name + " {…}"); + let mut item = CompletionItem::new( + CompletionItemKind::Snippet, + ctx.source_range(), + SmolStr::from_iter([&name, " {…}"]), + ); item.set_documentation(ctx.docs(def)).set_deprecated(ctx.is_deprecated(def)).detail(&literal); match ctx.snippet_cap() { Some(snippet_cap) => item.insert_snippet(snippet_cap, literal), diff --git a/crates/ide_completion/src/render/type_alias.rs b/crates/ide_completion/src/render/type_alias.rs index 7b6d2fa5c3a..6e6c1204b2b 100644 --- a/crates/ide_completion/src/render/type_alias.rs +++ b/crates/ide_completion/src/render/type_alias.rs @@ -58,7 +58,7 @@ impl<'a> TypeAliasRender<'a> { let db = self.ctx.db(); if let Some(actm) = self.type_alias.as_assoc_item(db) { if let Some(trt) = actm.containing_trait_or_trait_impl(db) { - item.trait_name(trt.name(db).to_string()); + item.trait_name(trt.name(db).to_smol_str()); item.insert_text(name); } } diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml index 080697b96ff..c3d08acb271 100644 --- a/crates/syntax/Cargo.toml +++ b/crates/syntax/Cargo.toml @@ -18,7 +18,7 @@ rustc_lexer = { version = "725.0.0", package = "rustc-ap-rustc_lexer" } rustc-hash = "1.1.0" once_cell = "1.3.1" indexmap = "1.4.0" -smol_str = "0.1.15" +smol_str = "0.1.21" stdx = { path = "../stdx", version = "0.0.0" } text_edit = { path = "../text_edit", version = "0.0.0" }