Auto merge of #13379 - DropDemBits:ide-assists-format-args-capture, r=Veykril

internal: Migrate `ide_assists::utils` and `ide_assists::handlers` to use format arg captures (part 1)

This not only serves as making future migration to mutable syntax trees easier, it also finds out what needs to be migrated in the first place.

~~Aside from the first commit, subsequent commits are structured to only deal with one file/handler at a time.~~

This is the first of 3 PRs, migrating:

Utils:

- `gen_trait_fn_body`
- `render_snippet`
- `ReferenceConversion`
  - `convert_type`
  - `getter`

Handlers:

- `add_explicit_type`
- `add_return_type`
- `add_turbo_fish`
- `apply_demorgan`
- `auto_import`
- `convert_comment_block`
- `convert_integer_literal`
- `convert_into_to_from`
- `convert_iter_for_each_to_for`
- `convert_let_else_to_match`
- `convert_tuple_struct_to_named_struct`
- `convert_two_arm_bool_match_to_matches_macro`
- `destructure_tuple_binding`
- `extract_function`
- `extract_module`
- `extract_struct_from_enum_variant`
- `extract_type_alias`
- `extract_variable`
- `fix_visibility`
This commit is contained in:
bors 2022-11-05 12:29:06 +00:00
commit afe8f6b922
21 changed files with 158 additions and 165 deletions

View file

@ -69,14 +69,14 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
let inferred_type = ty.display_source_code(ctx.db(), module.into()).ok()?;
acc.add(
AssistId("add_explicit_type", AssistKind::RefactorRewrite),
format!("Insert explicit type `{}`", inferred_type),
format!("Insert explicit type `{inferred_type}`"),
pat_range,
|builder| match ascribed_ty {
Some(ascribed_ty) => {
builder.replace(ascribed_ty.syntax().text_range(), inferred_type);
}
None => {
builder.insert(pat_range.end(), format!(": {}", inferred_type));
builder.insert(pat_range.end(), format!(": {inferred_type}"));
}
},
)

View file

@ -35,16 +35,16 @@ pub(crate) fn add_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
match builder_edit_pos {
InsertOrReplace::Insert(insert_pos, needs_whitespace) => {
let preceeding_whitespace = if needs_whitespace { " " } else { "" };
builder.insert(insert_pos, &format!("{}-> {} ", preceeding_whitespace, ty))
builder.insert(insert_pos, &format!("{preceeding_whitespace}-> {ty} "))
}
InsertOrReplace::Replace(text_range) => {
builder.replace(text_range, &format!("-> {}", ty))
builder.replace(text_range, &format!("-> {ty}"))
}
}
if let FnType::Closure { wrap_expr: true } = fn_type {
cov_mark::hit!(wrap_closure_non_block_expr);
// `|x| x` becomes `|x| -> T x` which is invalid, so wrap it in a block
builder.replace(tail_expr.syntax().text_range(), &format!("{{{}}}", tail_expr));
builder.replace(tail_expr.syntax().text_range(), &format!("{{{tail_expr}}}"));
}
},
)

View file

@ -93,12 +93,13 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
builder.trigger_signature_help();
match ctx.config.snippet_cap {
Some(cap) => {
let snip = format!("::<{}>", get_snippet_fish_head(number_of_arguments));
let fish_head = get_snippet_fish_head(number_of_arguments);
let snip = format!("::<{fish_head}>");
builder.insert_snippet(cap, ident.text_range().end(), snip)
}
None => {
let fish_head = std::iter::repeat("_").take(number_of_arguments).format(", ");
let snip = format!("::<{}>", fish_head);
let snip = format!("::<{fish_head}>");
builder.insert(ident.text_range().end(), snip);
}
}
@ -109,7 +110,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
/// This will create a snippet string with tabstops marked
fn get_snippet_fish_head(number_of_arguments: usize) -> String {
let mut fish_head = (1..number_of_arguments)
.format_with("", |i, f| f(&format_args!("${{{}:_}}, ", i)))
.format_with("", |i, f| f(&format_args!("${{{i}:_}}, ")))
.to_string();
// tabstop 0 is a special case and always the last one

View file

@ -123,20 +123,20 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
let lhs_range = lhs.syntax().text_range();
let not_lhs = invert_boolean_expression(lhs);
edit.replace(lhs_range, format!("!({}", not_lhs.syntax().text()));
edit.replace(lhs_range, format!("!({not_lhs}"));
}
if let Some(rhs) = terms.pop_back() {
let rhs_range = rhs.syntax().text_range();
let not_rhs = invert_boolean_expression(rhs);
edit.replace(rhs_range, format!("{})", not_rhs.syntax().text()));
edit.replace(rhs_range, format!("{not_rhs})"));
}
for term in terms {
let term_range = term.syntax().text_range();
let not_term = invert_boolean_expression(term);
edit.replace(term_range, not_term.syntax().text());
edit.replace(term_range, not_term.to_string());
}
}
},

View file

@ -127,10 +127,12 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
.sort_by_key(|import| Reverse(relevance_score(ctx, import, current_module.as_ref())));
for import in proposed_imports {
let import_path = import.import_path;
acc.add_group(
&group_label,
AssistId("auto_import", AssistKind::QuickFix),
format!("Import `{}`", import.import_path),
format!("Import `{import_path}`"),
range,
|builder| {
let scope = match scope.clone() {
@ -138,7 +140,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)),
ImportScope::Block(it) => ImportScope::Block(builder.make_mut(it)),
};
insert_use(&scope, mod_path_to_ast(&import.import_path), &ctx.config.insert_use);
insert_use(&scope, mod_path_to_ast(&import_path), &ctx.config.insert_use);
},
);
}

View file

@ -54,16 +54,17 @@ fn block_to_line(acc: &mut Assists, comment: ast::Comment) -> Option<()> {
let indent_spaces = indentation.to_string();
let output = lines
.map(|l| l.trim_start_matches(&indent_spaces))
.map(|l| {
.map(|line| {
let line = line.trim_start_matches(&indent_spaces);
// Don't introduce trailing whitespace
if l.is_empty() {
if line.is_empty() {
line_prefix.to_string()
} else {
format!("{} {}", line_prefix, l.trim_start_matches(&indent_spaces))
format!("{line_prefix} {line}")
}
})
.join(&format!("\n{}", indent_spaces));
.join(&format!("\n{indent_spaces}"));
edit.replace(target, output)
},
@ -96,7 +97,7 @@ fn line_to_block(acc: &mut Assists, comment: ast::Comment) -> Option<()> {
let block_prefix =
CommentKind { shape: CommentShape::Block, ..comment.kind() }.prefix();
let output = format!("{}\n{}\n{}*/", block_prefix, block_comment_body, indentation);
let output = format!("{block_prefix}\n{block_comment_body}\n{indentation}*/");
edit.replace(target, output)
},

View file

@ -32,19 +32,19 @@ pub(crate) fn convert_integer_literal(acc: &mut Assists, ctx: &AssistContext<'_>
}
let mut converted = match target_radix {
Radix::Binary => format!("0b{:b}", value),
Radix::Octal => format!("0o{:o}", value),
Radix::Binary => format!("0b{value:b}"),
Radix::Octal => format!("0o{value:o}"),
Radix::Decimal => value.to_string(),
Radix::Hexadecimal => format!("0x{:X}", value),
Radix::Hexadecimal => format!("0x{value:X}"),
};
let label = format!("Convert {} to {}{}", literal, converted, suffix.unwrap_or_default());
// Appends the type suffix back into the new literal if it exists.
if let Some(suffix) = suffix {
converted.push_str(suffix);
}
let label = format!("Convert {literal} to {converted}");
acc.add_group(
&group_id,
AssistId("convert_integer_literal", AssistKind::RefactorInline),

View file

@ -86,9 +86,9 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext<'_>) -
impl_.syntax().text_range(),
|builder| {
builder.replace(src_type.syntax().text_range(), dest_type.to_string());
builder.replace(ast_trait.syntax().text_range(), format!("From<{}>", src_type));
builder.replace(ast_trait.syntax().text_range(), format!("From<{src_type}>"));
builder.replace(into_fn_return.syntax().text_range(), "-> Self");
builder.replace(into_fn_params.syntax().text_range(), format!("(val: {})", src_type));
builder.replace(into_fn_params.syntax().text_range(), format!("(val: {src_type})"));
builder.replace(into_fn_name.syntax().text_range(), "from");
for s in selfs {

View file

@ -119,19 +119,19 @@ pub(crate) fn convert_for_loop_with_for_each(
{
// We have either "for x in &col" and col implements a method called iter
// or "for x in &mut col" and col implements a method called iter_mut
format_to!(buf, "{}.{}()", expr_behind_ref, method);
format_to!(buf, "{expr_behind_ref}.{method}()");
} else if let ast::Expr::RangeExpr(..) = iterable {
// range expressions need to be parenthesized for the syntax to be correct
format_to!(buf, "({})", iterable);
format_to!(buf, "({iterable})");
} else if impls_core_iter(&ctx.sema, &iterable) {
format_to!(buf, "{}", iterable);
format_to!(buf, "{iterable}");
} else if let ast::Expr::RefExpr(_) = iterable {
format_to!(buf, "({}).into_iter()", iterable);
format_to!(buf, "({iterable}).into_iter()");
} else {
format_to!(buf, "{}.into_iter()", iterable);
format_to!(buf, "{iterable}.into_iter()");
}
format_to!(buf, ".for_each(|{}| {});", pat, body);
format_to!(buf, ".for_each(|{pat}| {body});");
builder.replace(for_loop.syntax().text_range(), buf)
},

View file

@ -80,7 +80,7 @@ fn binders_to_str(binders: &[(Name, bool)], addmut: bool) -> String {
.map(
|(ident, ismut)| {
if *ismut && addmut {
format!("mut {}", ident)
format!("mut {ident}")
} else {
ident.to_string()
}
@ -93,7 +93,7 @@ fn binders_to_str(binders: &[(Name, bool)], addmut: bool) -> String {
} else if binders.len() == 1 {
vars
} else {
format!("({})", vars)
format!("({vars})")
}
}
@ -153,7 +153,7 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'
let only_expr = let_else_block.statements().next().is_none();
let branch2 = match &let_else_block.tail_expr() {
Some(tail) if only_expr => format!("{},", tail.syntax().text()),
Some(tail) if only_expr => format!("{tail},"),
_ => let_else_block.syntax().text().to_string(),
};
let replace = if binders.is_empty() {

View file

@ -226,7 +226,13 @@ fn edit_field_references(
}
fn generate_names(fields: impl Iterator<Item = ast::TupleField>) -> Vec<ast::Name> {
fields.enumerate().map(|(i, _)| ast::make::name(&format!("field{}", i + 1))).collect()
fields
.enumerate()
.map(|(i, _)| {
let idx = i + 1;
ast::make::name(&format!("field{idx}"))
})
.collect()
}
#[cfg(test)]

View file

@ -58,16 +58,16 @@ pub(crate) fn convert_two_arm_bool_match_to_matches_macro(
target_range,
|builder| {
let mut arm_str = String::new();
if let Some(ref pat) = first_arm.pat() {
if let Some(pat) = &first_arm.pat() {
arm_str += &pat.to_string();
}
if let Some(ref guard) = first_arm.guard() {
arm_str += &format!(" {}", &guard.to_string());
if let Some(guard) = &first_arm.guard() {
arm_str += &format!(" {guard}");
}
if invert_matches {
builder.replace(target_range, format!("!matches!({}, {})", expr, arm_str));
builder.replace(target_range, format!("!matches!({expr}, {arm_str})"));
} else {
builder.replace(target_range, format!("matches!({}, {})", expr, arm_str));
builder.replace(target_range, format!("matches!({expr}, {arm_str})"));
}
},
)

View file

@ -133,7 +133,7 @@ fn generate_name(
_usages: &Option<UsageSearchResult>,
) -> String {
// FIXME: detect if name already used
format!("_{}", index)
format!("_{index}")
}
enum RefType {
@ -168,12 +168,12 @@ fn edit_tuple_assignment(
let add_cursor = |text: &str| {
// place cursor on first tuple item
let first_tuple = &data.field_names[0];
text.replacen(first_tuple, &format!("$0{}", first_tuple), 1)
text.replacen(first_tuple, &format!("$0{first_tuple}"), 1)
};
// with sub_pattern: keep original tuple and add subpattern: `tup @ (_0, _1)`
if in_sub_pattern {
let text = format!(" @ {}", tuple_pat);
let text = format!(" @ {tuple_pat}");
match ctx.config.snippet_cap {
Some(cap) => {
let snip = add_cursor(&text);
@ -314,9 +314,9 @@ struct RefData {
impl RefData {
fn format(&self, field_name: &str) -> String {
match (self.needs_deref, self.needs_parentheses) {
(true, true) => format!("(*{})", field_name),
(true, false) => format!("*{}", field_name),
(false, true) => format!("({})", field_name),
(true, true) => format!("(*{field_name})"),
(true, false) => format!("*{field_name}"),
(false, true) => format!("({field_name})"),
(false, false) => field_name.to_string(),
}
}

View file

@ -181,7 +181,7 @@ fn make_function_name(semantics_scope: &hir::SemanticsScope<'_>) -> ast::NameRef
let mut counter = 0;
while names_in_scope.contains(&name) {
counter += 1;
name = format!("{}{}", &default_name, counter)
name = format!("{default_name}{counter}")
}
make::name_ref(&name)
}
@ -1291,19 +1291,23 @@ fn make_call(ctx: &AssistContext<'_>, fun: &Function, indent: IndentLevel) -> St
match fun.outliving_locals.as_slice() {
[] => {}
[var] => {
format_to!(buf, "let {}{} = ", mut_modifier(var), var.local.name(ctx.db()))
let modifier = mut_modifier(var);
let name = var.local.name(ctx.db());
format_to!(buf, "let {modifier}{name} = ")
}
vars => {
buf.push_str("let (");
let bindings = vars.iter().format_with(", ", |local, f| {
f(&format_args!("{}{}", mut_modifier(local), local.local.name(ctx.db())))
let modifier = mut_modifier(local);
let name = local.local.name(ctx.db());
f(&format_args!("{modifier}{name}"))
});
format_to!(buf, "{}", bindings);
format_to!(buf, "{bindings}");
buf.push_str(") = ");
}
}
format_to!(buf, "{}", expr);
format_to!(buf, "{expr}");
let insert_comma = fun
.body
.parent()
@ -1447,6 +1451,8 @@ fn format_function(
new_indent: IndentLevel,
) -> String {
let mut fn_def = String::new();
let fun_name = &fun.name;
let params = fun.make_param_list(ctx, module);
let ret_ty = fun.make_ret_ty(ctx, module);
let body = make_body(ctx, old_indent, new_indent, fun);
@ -1454,42 +1460,28 @@ fn format_function(
let async_kw = if fun.control_flow.is_async { "async " } else { "" };
let unsafe_kw = if fun.control_flow.is_unsafe { "unsafe " } else { "" };
let (generic_params, where_clause) = make_generic_params_and_where_clause(ctx, fun);
format_to!(fn_def, "\n\n{new_indent}{const_kw}{async_kw}{unsafe_kw}");
match ctx.config.snippet_cap {
Some(_) => format_to!(
fn_def,
"\n\n{}{}{}{}fn $0{}",
new_indent,
const_kw,
async_kw,
unsafe_kw,
fun.name,
),
None => format_to!(
fn_def,
"\n\n{}{}{}{}fn {}",
new_indent,
const_kw,
async_kw,
unsafe_kw,
fun.name,
),
Some(_) => format_to!(fn_def, "fn $0{fun_name}"),
None => format_to!(fn_def, "fn {fun_name}"),
}
if let Some(generic_params) = generic_params {
format_to!(fn_def, "{}", generic_params);
format_to!(fn_def, "{generic_params}");
}
format_to!(fn_def, "{}", params);
format_to!(fn_def, "{params}");
if let Some(ret_ty) = ret_ty {
format_to!(fn_def, " {}", ret_ty);
format_to!(fn_def, " {ret_ty}");
}
if let Some(where_clause) = where_clause {
format_to!(fn_def, " {}", where_clause);
format_to!(fn_def, " {where_clause}");
}
format_to!(fn_def, " {}", body);
format_to!(fn_def, " {body}");
fn_def
}

View file

@ -127,7 +127,7 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
for item in items_to_be_processed {
let item = item.indent(IndentLevel(1));
let mut indented_item = String::new();
format_to!(indented_item, "{}{}", new_item_indent, item.to_string());
format_to!(indented_item, "{new_item_indent}{item}");
body_items.push(indented_item);
}
@ -137,30 +137,28 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
let mut impl_body_def = String::new();
if let Some(self_ty) = impl_.self_ty() {
format_to!(
impl_body_def,
"{}impl {} {{\n{}\n{}}}",
old_item_indent + 1,
self_ty.to_string(),
body,
old_item_indent + 1
);
{
let impl_indent = old_item_indent + 1;
format_to!(
impl_body_def,
"{impl_indent}impl {self_ty} {{\n{body}\n{impl_indent}}}",
);
}
body = impl_body_def;
// Add the import for enum/struct corresponding to given impl block
module.make_use_stmt_of_node_with_super(self_ty.syntax());
for item in module.use_items {
let mut indented_item = String::new();
format_to!(indented_item, "{}{}", old_item_indent + 1, item.to_string());
body = format!("{}\n\n{}", indented_item, body);
let item_indent = old_item_indent + 1;
body = format!("{item_indent}{item}\n\n{body}");
}
}
}
let mut module_def = String::new();
format_to!(module_def, "mod {} {{\n{}\n{}}}", module.name, body, old_item_indent);
let module_name = module.name;
format_to!(module_def, "mod {module_name} {{\n{body}\n{old_item_indent}}}");
let mut usages_to_be_updated_for_curr_file = vec![];
for usages_to_be_updated_for_file in usages_to_be_processed {
@ -199,7 +197,7 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
builder.delete(range);
}
builder.insert(impl_.syntax().text_range().end(), format!("\n\n{}", module_def));
builder.insert(impl_.syntax().text_range().end(), format!("\n\n{module_def}"));
} else {
builder.replace(module.text_range, module_def)
}
@ -343,9 +341,10 @@ impl Module {
&& !self.text_range.contains_range(desc.text_range())
{
if let Some(name_ref) = ast::NameRef::cast(desc) {
let mod_name = self.name;
return Some((
name_ref.syntax().text_range(),
format!("{}::{}", self.name, name_ref),
format!("{mod_name}::{name_ref}"),
));
}
}

View file

@ -296,10 +296,14 @@ fn create_struct_def(
fn update_variant(variant: &ast::Variant, generics: Option<ast::GenericParamList>) -> Option<()> {
let name = variant.name()?;
let ty = generics
let generic_args = generics
.filter(|generics| generics.generic_params().count() > 0)
.map(|generics| make::ty(&format!("{}{}", &name.text(), generics.to_generic_args())))
.unwrap_or_else(|| make::ty(&name.text()));
.map(|generics| generics.to_generic_args());
// FIXME: replace with a `ast::make` constructor
let ty = match generic_args {
Some(generic_args) => make::ty(&format!("{name}{generic_args}")),
None => make::ty(&name.text()),
};
// change from a record to a tuple field list
let tuple_field = make::tuple_field(None, ty);

View file

@ -1,8 +1,7 @@
use either::Either;
use ide_db::syntax_helpers::node_ext::walk_ty;
use itertools::Itertools;
use syntax::{
ast::{self, edit::IndentLevel, AstNode, HasGenericParams, HasName},
ast::{self, edit::IndentLevel, make, AstNode, HasGenericParams, HasName},
match_ast,
};
@ -64,41 +63,29 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) ->
known_generics.extend(it.generic_params());
}
let generics = collect_used_generics(&ty, &known_generics);
let generic_params =
generics.map(|it| make::generic_param_list(it.into_iter().cloned()));
let replacement = if !generics.is_empty() {
format!(
"Type<{}>",
generics.iter().format_with(", ", |generic, f| {
match generic {
ast::GenericParam::ConstParam(cp) => f(&cp.name().unwrap()),
ast::GenericParam::LifetimeParam(lp) => f(&lp.lifetime().unwrap()),
ast::GenericParam::TypeParam(tp) => f(&tp.name().unwrap()),
}
})
)
} else {
String::from("Type")
};
let ty_args = generic_params
.as_ref()
.map_or(String::new(), |it| it.to_generic_args().to_string());
let replacement = format!("Type{ty_args}");
builder.replace(target, replacement);
let indent = IndentLevel::from_node(node);
let generics = if !generics.is_empty() {
format!("<{}>", generics.iter().format(", "))
} else {
String::new()
};
let generic_params = generic_params.map_or(String::new(), |it| it.to_string());
match ctx.config.snippet_cap {
Some(cap) => {
builder.insert_snippet(
cap,
insert_pos,
format!("type $0Type{} = {};\n\n{}", generics, ty, indent),
format!("type $0Type{generic_params} = {ty};\n\n{indent}"),
);
}
None => {
builder.insert(
insert_pos,
format!("type Type{} = {};\n\n{}", generics, ty, indent),
format!("type Type{generic_params} = {ty};\n\n{indent}"),
);
}
}
@ -109,7 +96,7 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) ->
fn collect_used_generics<'gp>(
ty: &ast::Type,
known_generics: &'gp [ast::GenericParam],
) -> Vec<&'gp ast::GenericParam> {
) -> Option<Vec<&'gp ast::GenericParam>> {
// can't use a closure -> closure here cause lifetime inference fails for that
fn find_lifetime(text: &str) -> impl Fn(&&ast::GenericParam) -> bool + '_ {
move |gp: &&ast::GenericParam| match gp {
@ -198,7 +185,8 @@ fn collect_used_generics<'gp>(
ast::GenericParam::LifetimeParam(_) => 0,
ast::GenericParam::TypeParam(_) => 1,
});
generics
Some(generics).filter(|it| it.len() > 0)
}
#[cfg(test)]

View file

@ -91,13 +91,13 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
match anchor {
Anchor::Before(_) | Anchor::Replace(_) => {
format_to!(buf, "let {}{} = {}", var_modifier, var_name, reference_modifier)
format_to!(buf, "let {var_modifier}{var_name} = {reference_modifier}")
}
Anchor::WrapInBlock(_) => {
format_to!(buf, "{{ let {} = {}", var_name, reference_modifier)
format_to!(buf, "{{ let {var_name} = {reference_modifier}")
}
};
format_to!(buf, "{}", to_extract.syntax());
format_to!(buf, "{to_extract}");
if let Anchor::Replace(stmt) = anchor {
cov_mark::hit!(test_extract_var_expr_stmt);
@ -107,8 +107,8 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
match ctx.config.snippet_cap {
Some(cap) => {
let snip = buf.replace(
&format!("let {}{}", var_modifier, var_name),
&format!("let {}$0{}", var_modifier, var_name),
&format!("let {var_modifier}{var_name}"),
&format!("let {var_modifier}$0{var_name}"),
);
edit.replace_snippet(cap, expr_range, snip)
}
@ -135,8 +135,8 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
match ctx.config.snippet_cap {
Some(cap) => {
let snip = buf.replace(
&format!("let {}{}", var_modifier, var_name),
&format!("let {}$0{}", var_modifier, var_name),
&format!("let {var_modifier}{var_name}"),
&format!("let {var_modifier}$0{var_name}"),
);
edit.insert_snippet(cap, offset, snip)
}

View file

@ -57,8 +57,8 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>)
if current_module.krate() == target_module.krate() { "pub(crate)" } else { "pub" };
let assist_label = match target_name {
None => format!("Change visibility to {}", missing_visibility),
Some(name) => format!("Change visibility of {} to {}", name, missing_visibility),
None => format!("Change visibility to {missing_visibility}"),
Some(name) => format!("Change visibility of {name} to {missing_visibility}"),
};
acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| {
@ -68,15 +68,15 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>)
Some(current_visibility) => builder.replace_snippet(
cap,
current_visibility.syntax().text_range(),
format!("$0{}", missing_visibility),
format!("$0{missing_visibility}"),
),
None => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
None => builder.insert_snippet(cap, offset, format!("$0{missing_visibility} ")),
},
None => match current_visibility {
Some(current_visibility) => {
builder.replace(current_visibility.syntax().text_range(), missing_visibility)
}
None => builder.insert(offset, format!("{} ", missing_visibility)),
None => builder.insert(offset, format!("{missing_visibility} ")),
},
}
})
@ -114,7 +114,7 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext<'_>
let target_name = record_field_def.name(ctx.db());
let assist_label =
format!("Change visibility of {}.{} to {}", parent_name, target_name, missing_visibility);
format!("Change visibility of {parent_name}.{target_name} to {missing_visibility}");
acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| {
builder.edit_file(target_file);
@ -123,15 +123,15 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext<'_>
Some(current_visibility) => builder.replace_snippet(
cap,
current_visibility.syntax().text_range(),
format!("$0{}", missing_visibility),
format!("$0{missing_visibility}"),
),
None => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
None => builder.insert_snippet(cap, offset, format!("$0{missing_visibility} ")),
},
None => match current_visibility {
Some(current_visibility) => {
builder.replace(current_visibility.syntax().text_range(), missing_visibility)
}
None => builder.insert(offset, format!("{} ", missing_visibility)),
None => builder.insert(offset, format!("{missing_visibility} ")),
},
}
})

View file

@ -189,8 +189,8 @@ pub(crate) fn render_snippet(_cap: SnippetCap, node: &SyntaxNode, cursor: Cursor
let mut placeholder = cursor.node().to_string();
escape(&mut placeholder);
let tab_stop = match cursor {
Cursor::Replace(placeholder) => format!("${{0:{}}}", placeholder),
Cursor::Before(placeholder) => format!("$0{}", placeholder),
Cursor::Replace(placeholder) => format!("${{0:{placeholder}}}"),
Cursor::Before(placeholder) => format!("$0{placeholder}"),
};
let mut buf = node.to_string();
@ -539,17 +539,17 @@ impl ReferenceConversion {
ReferenceConversionType::AsRefSlice => {
let type_argument_name =
self.ty.type_arguments().next().unwrap().display(db).to_string();
format!("&[{}]", type_argument_name)
format!("&[{type_argument_name}]")
}
ReferenceConversionType::Dereferenced => {
let type_argument_name =
self.ty.type_arguments().next().unwrap().display(db).to_string();
format!("&{}", type_argument_name)
format!("&{type_argument_name}")
}
ReferenceConversionType::Option => {
let type_argument_name =
self.ty.type_arguments().next().unwrap().display(db).to_string();
format!("Option<&{}>", type_argument_name)
format!("Option<&{type_argument_name}>")
}
ReferenceConversionType::Result => {
let mut type_arguments = self.ty.type_arguments();
@ -557,19 +557,19 @@ impl ReferenceConversion {
type_arguments.next().unwrap().display(db).to_string();
let second_type_argument_name =
type_arguments.next().unwrap().display(db).to_string();
format!("Result<&{}, &{}>", first_type_argument_name, second_type_argument_name)
format!("Result<&{first_type_argument_name}, &{second_type_argument_name}>")
}
}
}
pub(crate) fn getter(&self, field_name: String) -> String {
match self.conversion {
ReferenceConversionType::Copy => format!("self.{}", field_name),
ReferenceConversionType::Copy => format!("self.{field_name}"),
ReferenceConversionType::AsRefStr
| ReferenceConversionType::AsRefSlice
| ReferenceConversionType::Dereferenced
| ReferenceConversionType::Option
| ReferenceConversionType::Result => format!("self.{}.as_ref()", field_name),
| ReferenceConversionType::Result => format!("self.{field_name}.as_ref()"),
}
}
}

View file

@ -41,7 +41,7 @@ fn gen_clone_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
let mut arms = vec![];
for variant in list.variants() {
let name = variant.name()?;
let variant_name = make::ext::path_from_idents(["Self", &format!("{}", name)])?;
let variant_name = make::ext::path_from_idents(["Self", &format!("{name}")])?;
match variant.field_list() {
// => match self { Self::Name { x } => Self::Name { x: x.clone() } }
@ -70,7 +70,7 @@ fn gen_clone_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
let mut pats = vec![];
let mut fields = vec![];
for (i, _) in list.fields().enumerate() {
let field_name = format!("arg{}", i);
let field_name = format!("arg{i}");
let pat = make::ident_pat(false, false, make::name(&field_name));
pats.push(pat.into());
@ -118,7 +118,7 @@ fn gen_clone_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
let mut fields = vec![];
for (i, _) in field_list.fields().enumerate() {
let f_path = make::expr_path(make::ext::ident_path("self"));
let target = make::expr_field(f_path, &format!("{}", i));
let target = make::expr_field(f_path, &format!("{i}"));
fields.push(gen_clone_call(target));
}
let struct_name = make::expr_path(make::ext::ident_path("Self"));
@ -151,7 +151,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
let mut arms = vec![];
for variant in list.variants() {
let name = variant.name()?;
let variant_name = make::ext::path_from_idents(["Self", &format!("{}", name)])?;
let variant_name = make::ext::path_from_idents(["Self", &format!("{name}")])?;
let target = make::expr_path(make::ext::ident_path("f"));
match variant.field_list() {
@ -159,7 +159,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
// => f.debug_struct(name)
let target = make::expr_path(make::ext::ident_path("f"));
let method = make::name_ref("debug_struct");
let struct_name = format!("\"{}\"", name);
let struct_name = format!("\"{name}\"");
let args = make::arg_list(Some(make::expr_literal(&struct_name).into()));
let mut expr = make::expr_method_call(target, method, args);
@ -173,8 +173,8 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
// => <expr>.field("field_name", field)
let method_name = make::name_ref("field");
let name = make::expr_literal(&(format!("\"{}\"", field_name))).into();
let path = &format!("{}", field_name);
let name = make::expr_literal(&(format!("\"{field_name}\""))).into();
let path = &format!("{field_name}");
let path = make::expr_path(make::ext::ident_path(path));
let args = make::arg_list(vec![name, path]);
expr = make::expr_method_call(expr, method_name, args);
@ -192,13 +192,13 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
// => f.debug_tuple(name)
let target = make::expr_path(make::ext::ident_path("f"));
let method = make::name_ref("debug_tuple");
let struct_name = format!("\"{}\"", name);
let struct_name = format!("\"{name}\"");
let args = make::arg_list(Some(make::expr_literal(&struct_name).into()));
let mut expr = make::expr_method_call(target, method, args);
let mut pats = vec![];
for (i, _) in list.fields().enumerate() {
let name = format!("arg{}", i);
let name = format!("arg{i}");
// create a field pattern for use in `MyStruct(fields..)`
let field_name = make::name(&name);
@ -222,7 +222,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
arms.push(make::match_arm(Some(pat.into()), None, expr));
}
None => {
let fmt_string = make::expr_literal(&(format!("\"{}\"", name))).into();
let fmt_string = make::expr_literal(&(format!("\"{name}\""))).into();
let args = make::arg_list([target, fmt_string]);
let macro_name = make::expr_path(make::ext::ident_path("write"));
let macro_call = make::expr_macro_call(macro_name, args);
@ -244,7 +244,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
}
ast::Adt::Struct(strukt) => {
let name = format!("\"{}\"", annotated_name);
let name = format!("\"{annotated_name}\"");
let args = make::arg_list(Some(make::expr_literal(&name).into()));
let target = make::expr_path(make::ext::ident_path("f"));
@ -258,10 +258,10 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
let mut expr = make::expr_method_call(target, method, args);
for field in field_list.fields() {
let name = field.name()?;
let f_name = make::expr_literal(&(format!("\"{}\"", name))).into();
let f_name = make::expr_literal(&(format!("\"{name}\""))).into();
let f_path = make::expr_path(make::ext::ident_path("self"));
let f_path = make::expr_ref(f_path, false);
let f_path = make::expr_field(f_path, &format!("{}", name));
let f_path = make::expr_field(f_path, &format!("{name}"));
let args = make::arg_list([f_name, f_path]);
expr = make::expr_method_call(expr, make::name_ref("field"), args);
}
@ -275,7 +275,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
for (i, _) in field_list.fields().enumerate() {
let f_path = make::expr_path(make::ext::ident_path("self"));
let f_path = make::expr_ref(f_path, false);
let f_path = make::expr_field(f_path, &format!("{}", i));
let f_path = make::expr_field(f_path, &format!("{i}"));
let method = make::name_ref("field");
expr = make::expr_method_call(expr, method, make::arg_list(Some(f_path)));
}
@ -379,7 +379,7 @@ fn gen_hash_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
let mut stmts = vec![];
for (i, _) in field_list.fields().enumerate() {
let base = make::expr_path(make::ext::ident_path("self"));
let target = make::expr_field(base, &format!("{}", i));
let target = make::expr_field(base, &format!("{i}"));
stmts.push(gen_hash_call(target));
}
make::block_expr(stmts, None).indent(ast::edit::IndentLevel(1))
@ -453,10 +453,10 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
for field in list.fields() {
let field_name = field.name()?.to_string();
let l_name = &format!("l_{}", field_name);
let l_name = &format!("l_{field_name}");
l_fields.push(gen_record_pat_field(&field_name, l_name));
let r_name = &format!("r_{}", field_name);
let r_name = &format!("r_{field_name}");
r_fields.push(gen_record_pat_field(&field_name, r_name));
let lhs = make::expr_path(make::ext::ident_path(l_name));
@ -484,12 +484,12 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
let mut r_fields = vec![];
for (i, _) in list.fields().enumerate() {
let field_name = format!("{}", i);
let field_name = format!("{i}");
let l_name = format!("l{}", field_name);
let l_name = format!("l{field_name}");
l_fields.push(gen_tuple_field(&l_name));
let r_name = format!("r{}", field_name);
let r_name = format!("r{field_name}");
r_fields.push(gen_tuple_field(&r_name));
let lhs = make::expr_path(make::ext::ident_path(&l_name));
@ -548,7 +548,7 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
Some(ast::FieldList::TupleFieldList(field_list)) => {
let mut expr = None;
for (i, _) in field_list.fields().enumerate() {
let idx = format!("{}", i);
let idx = format!("{i}");
let lhs = make::expr_path(make::ext::ident_path("self"));
let lhs = make::expr_field(lhs, &idx);
let rhs = make::expr_path(make::ext::ident_path("other"));
@ -628,7 +628,7 @@ fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
Some(ast::FieldList::TupleFieldList(field_list)) => {
let mut exprs = vec![];
for (i, _) in field_list.fields().enumerate() {
let idx = format!("{}", i);
let idx = format!("{i}");
let lhs = make::expr_path(make::ext::ident_path("self"));
let lhs = make::expr_field(lhs, &idx);
let rhs = make::expr_path(make::ext::ident_path("other"));