Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21886 from Shourya742/2026-03-26-migrate-gen-trait-fn-body
Replace make constructor with syntaxFactory in utils/gen trait fn body
A4-Tacks 8 weeks ago
parent 9be14d6 · parent b70d09d · commit dab40c3
-rw-r--r--crates/ide-assists/src/handlers/add_missing_impl_members.rs24
-rw-r--r--crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs21
-rw-r--r--crates/ide-assists/src/utils.rs10
-rw-r--r--crates/ide-assists/src/utils/gen_trait_fn_body.rs500
-rw-r--r--crates/syntax/src/ast/syntax_factory/constructors.rs11
5 files changed, 300 insertions, 266 deletions
diff --git a/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/crates/ide-assists/src/handlers/add_missing_impl_members.rs
index afdced4215..3689dc24b3 100644
--- a/crates/ide-assists/src/handlers/add_missing_impl_members.rs
+++ b/crates/ide-assists/src/handlers/add_missing_impl_members.rs
@@ -1,7 +1,7 @@
use hir::HasSource;
use syntax::{
Edition,
- ast::{self, AstNode, make},
+ ast::{self, AstNode, syntax_factory::SyntaxFactory},
syntax_editor::{Position, SyntaxEditor},
};
@@ -9,8 +9,8 @@ use crate::{
AssistId,
assist_context::{AssistContext, Assists},
utils::{
- DefaultMethods, IgnoreAssocItems, add_trait_assoc_items_to_impl, filter_assoc_items,
- gen_trait_fn_body,
+ DefaultMethods, IgnoreAssocItems, add_trait_assoc_items_to_impl_with_factory,
+ filter_assoc_items, gen_trait_fn_body,
},
};
@@ -148,7 +148,9 @@ fn add_missing_impl_members_inner(
let target = impl_def.syntax().text_range();
acc.add(AssistId::quick_fix(assist_id), label, target, |edit| {
- let new_item = add_trait_assoc_items_to_impl(
+ let make = SyntaxFactory::with_mappings();
+ let new_item = add_trait_assoc_items_to_impl_with_factory(
+ &make,
&ctx.sema,
ctx.config,
&missing_items,
@@ -164,6 +166,7 @@ fn add_missing_impl_members_inner(
let mut first_new_item = if let DefaultMethods::No = mode
&& let ast::AssocItem::Fn(func) = &first_new_item
&& let Some(body) = try_gen_trait_body(
+ &make,
ctx,
func,
trait_ref,
@@ -189,10 +192,10 @@ fn add_missing_impl_members_inner(
if let Some(assoc_item_list) = impl_def.assoc_item_list() {
assoc_item_list.add_items(&mut editor, new_assoc_items);
} else {
- let assoc_item_list = make::assoc_item_list(Some(new_assoc_items)).clone_for_update();
+ let assoc_item_list = make.assoc_item_list(new_assoc_items);
editor.insert_all(
Position::after(impl_def.syntax()),
- vec![make::tokens::whitespace(" ").into(), assoc_item_list.syntax().clone().into()],
+ vec![make.whitespace(" ").into(), assoc_item_list.syntax().clone().into()],
);
first_new_item = assoc_item_list.assoc_items().next();
}
@@ -215,23 +218,24 @@ fn add_missing_impl_members_inner(
editor.add_annotation(first_new_item.syntax(), tabstop);
};
};
+ editor.add_mappings(make.finish_with_mappings());
edit.add_file_edits(ctx.vfs_file_id(), editor);
})
}
fn try_gen_trait_body(
+ make: &SyntaxFactory,
ctx: &AssistContext<'_>,
func: &ast::Fn,
trait_ref: hir::TraitRef<'_>,
impl_def: &ast::Impl,
edition: Edition,
) -> Option<ast::BlockExpr> {
- let trait_path = make::ext::ident_path(
- &trait_ref.trait_().name(ctx.db()).display(ctx.db(), edition).to_string(),
- );
+ let trait_path =
+ make.ident_path(&trait_ref.trait_().name(ctx.db()).display(ctx.db(), edition).to_string());
let hir_ty = ctx.sema.resolve_type(&impl_def.self_ty()?)?;
let adt = hir_ty.as_adt()?.source(ctx.db())?;
- gen_trait_fn_body(func, &trait_path, &adt.value, Some(trait_ref))
+ gen_trait_fn_body(make, func, &trait_path, &adt.value, Some(trait_ref))
}
#[cfg(test)]
diff --git a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
index f54f7a02d2..f281fdf513 100644
--- a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -13,7 +13,7 @@ use crate::{
assist_context::{AssistContext, Assists},
utils::{
DefaultMethods, IgnoreAssocItems, add_trait_assoc_items_to_impl_with_factory,
- filter_assoc_items, gen_trait_fn_body, generate_trait_impl,
+ filter_assoc_items, gen_trait_fn_body, generate_trait_impl, generate_trait_impl_with_item,
},
};
@@ -127,7 +127,7 @@ fn add_assist(
let label = format!("Convert to manual `impl {replace_trait_path} for {annotated_name}`");
acc.add(AssistId::refactor("replace_derive_with_manual_impl"), label, target, |builder| {
- let make = SyntaxFactory::without_mappings();
+ let make = SyntaxFactory::with_mappings();
let insert_after = Position::after(adt.syntax());
let impl_is_unsafe = trait_.map(|s| s.is_unsafe(ctx.db())).unwrap_or(false);
let impl_def = impl_def_from_trait(
@@ -141,7 +141,7 @@ fn add_assist(
);
let mut editor = builder.make_editor(attr.syntax());
- update_attribute(&mut editor, old_derives, old_tree, old_trait_path, attr);
+ update_attribute(&make, &mut editor, old_derives, old_tree, old_trait_path, attr);
let trait_path = make.ty_path(replace_trait_path.clone()).into();
@@ -177,6 +177,7 @@ fn add_assist(
insert_after,
vec![make.whitespace("\n\n").into(), impl_def.syntax().clone().into()],
);
+ editor.add_mappings(make.finish_with_mappings());
builder.add_file_edits(ctx.vfs_file_id(), editor);
})
}
@@ -207,8 +208,8 @@ fn impl_def_from_trait(
return None;
}
let make = SyntaxFactory::without_mappings();
- let trait_ty = make.ty_path(trait_path.clone()).into();
- let impl_def = generate_trait_impl(&make, impl_is_unsafe, adt, trait_ty);
+ let trait_ty: ast::Type = make.ty_path(trait_path.clone()).into();
+ let impl_def = generate_trait_impl(&make, impl_is_unsafe, adt, trait_ty.clone());
let assoc_items = add_trait_assoc_items_to_impl_with_factory(
&make,
@@ -223,7 +224,7 @@ fn impl_def_from_trait(
assoc_items.split_first().map(|(first, other)| (first.clone_subtree(), other))
{
let first_item = if let ast::AssocItem::Fn(ref func) = first
- && let Some(body) = gen_trait_fn_body(func, trait_path, adt, None)
+ && let Some(body) = gen_trait_fn_body(&make, func, trait_path, adt, None)
&& let Some(func_body) = func.body()
{
let mut editor = SyntaxEditor::new(first.syntax().clone());
@@ -239,21 +240,17 @@ fn impl_def_from_trait(
make.assoc_item_list_empty()
};
- let impl_def = impl_def.clone_subtree();
- let mut editor = SyntaxEditor::new(impl_def.syntax().clone());
- editor.replace(impl_def.assoc_item_list()?.syntax(), assoc_item_list.syntax());
- let impl_def = ast::Impl::cast(editor.finish().new_root().clone())?;
- Some(impl_def)
+ Some(generate_trait_impl_with_item(&make, impl_is_unsafe, adt, trait_ty, assoc_item_list))
}
fn update_attribute(
+ make: &SyntaxFactory,
editor: &mut SyntaxEditor,
old_derives: &[ast::Path],
old_tree: &ast::TokenTree,
old_trait_path: &ast::Path,
attr: &ast::Attr,
) {
- let make = SyntaxFactory::without_mappings();
let new_derives = old_derives
.iter()
.filter(|t| t.to_string() != old_trait_path.to_string())
diff --git a/crates/ide-assists/src/utils.rs b/crates/ide-assists/src/utils.rs
index 10057f8681..fee5014232 100644
--- a/crates/ide-assists/src/utils.rs
+++ b/crates/ide-assists/src/utils.rs
@@ -758,6 +758,16 @@ pub(crate) fn generate_trait_impl_intransitive_with_item(
generate_impl_inner_with_factory(make, false, adt, Some(trait_), false, Some(body))
}
+pub(crate) fn generate_trait_impl_with_item(
+ make: &SyntaxFactory,
+ is_unsafe: bool,
+ adt: &ast::Adt,
+ trait_: ast::Type,
+ body: ast::AssocItemList,
+) -> ast::Impl {
+ generate_impl_inner_with_factory(make, is_unsafe, adt, Some(trait_), true, Some(body))
+}
+
fn generate_impl_inner(
is_unsafe: bool,
adt: &ast::Adt,
diff --git a/crates/ide-assists/src/utils/gen_trait_fn_body.rs b/crates/ide-assists/src/utils/gen_trait_fn_body.rs
index 87e90e8519..b0d88737fe 100644
--- a/crates/ide-assists/src/utils/gen_trait_fn_body.rs
+++ b/crates/ide-assists/src/utils/gen_trait_fn_body.rs
@@ -1,7 +1,10 @@
//! This module contains functions to generate default trait impl function bodies where possible.
use hir::TraitRef;
-use syntax::ast::{self, AstNode, BinaryOp, CmpOp, HasName, LogicOp, edit::AstNodeEdit, make};
+use syntax::ast::{
+ self, AstNode, BinaryOp, CmpOp, HasName, LogicOp, edit::AstNodeEdit,
+ syntax_factory::SyntaxFactory,
+};
/// Generate custom trait bodies without default implementation where possible.
///
@@ -11,6 +14,7 @@ use syntax::ast::{self, AstNode, BinaryOp, CmpOp, HasName, LogicOp, edit::AstNod
/// `None` means that generating a custom trait body failed, and the body will remain
/// as `todo!` instead.
pub(crate) fn gen_trait_fn_body(
+ make: &SyntaxFactory,
func: &ast::Fn,
trait_path: &ast::Path,
adt: &ast::Adt,
@@ -20,32 +24,32 @@ pub(crate) fn gen_trait_fn_body(
match trait_path.segment()?.name_ref()?.text().as_str() {
"Clone" => {
stdx::always!(func.name().is_some_and(|name| name.text() == "clone"));
- gen_clone_impl(adt)
+ gen_clone_impl(make, adt)
}
- "Debug" => gen_debug_impl(adt),
- "Default" => gen_default_impl(adt),
+ "Debug" => gen_debug_impl(make, adt),
+ "Default" => gen_default_impl(make, adt),
"Hash" => {
stdx::always!(func.name().is_some_and(|name| name.text() == "hash"));
- gen_hash_impl(adt)
+ gen_hash_impl(make, adt)
}
"PartialEq" => {
stdx::always!(func.name().is_some_and(|name| name.text() == "eq"));
- gen_partial_eq(adt, trait_ref)
+ gen_partial_eq(make, adt, trait_ref)
}
"PartialOrd" => {
stdx::always!(func.name().is_some_and(|name| name.text() == "partial_cmp"));
- gen_partial_ord(adt, trait_ref)
+ gen_partial_ord(make, adt, trait_ref)
}
_ => None,
}
}
/// Generate a `Clone` impl based on the fields and members of the target type.
-fn gen_clone_impl(adt: &ast::Adt) -> Option<ast::BlockExpr> {
- fn gen_clone_call(target: ast::Expr) -> ast::Expr {
- let method = make::name_ref("clone");
- make::expr_method_call(target, method, make::arg_list(None)).into()
- }
+fn gen_clone_impl(make: &SyntaxFactory, adt: &ast::Adt) -> Option<ast::BlockExpr> {
+ let gen_clone_call = |target: ast::Expr| -> ast::Expr {
+ let method = make.name_ref("clone");
+ make.expr_method_call(target, method, make.arg_list([])).into()
+ };
let expr = match adt {
// `Clone` cannot be derived for unions, so no default impl can be provided.
ast::Adt::Union(_) => return None,
@@ -54,7 +58,7 @@ fn gen_clone_impl(adt: &ast::Adt) -> Option<ast::BlockExpr> {
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.path_from_idents(["Self", &format!("{name}")])?;
match variant.field_list() {
// => match self { Self::Name { x } => Self::Name { x: x.clone() } }
@@ -63,19 +67,20 @@ fn gen_clone_impl(adt: &ast::Adt) -> Option<ast::BlockExpr> {
let mut fields = vec![];
for field in list.fields() {
let field_name = field.name()?;
- let pat = make::ident_pat(false, false, field_name.clone());
- pats.push(pat.into());
+ let pat = make.ident_pat(false, false, field_name.clone());
+ pats.push(make.record_pat_field_shorthand(pat.into()));
- let path = make::ext::ident_path(&field_name.to_string());
- let method_call = gen_clone_call(make::expr_path(path));
- let name_ref = make::name_ref(&field_name.to_string());
- let field = make::record_expr_field(name_ref, Some(method_call));
+ let path = make.ident_path(&field_name.to_string());
+ let method_call = gen_clone_call(make.expr_path(path));
+ let name_ref = make.name_ref(&field_name.to_string());
+ let field = make.record_expr_field(name_ref, Some(method_call));
fields.push(field);
}
- let pat = make::record_pat(variant_name.clone(), pats.into_iter());
- let fields = make::record_expr_field_list(fields);
- let record_expr = make::record_expr(variant_name, fields).into();
- arms.push(make::match_arm(pat.into(), None, record_expr));
+ let pat_field_list = make.record_pat_field_list(pats, None);
+ let pat = make.record_pat_with_fields(variant_name.clone(), pat_field_list);
+ let fields = make.record_expr_field_list(fields);
+ let record_expr = make.record_expr(variant_name, fields).into();
+ arms.push(make.match_arm(pat.into(), None, record_expr));
}
// => match self { Self::Name(arg1) => Self::Name(arg1.clone()) }
@@ -84,31 +89,30 @@ fn gen_clone_impl(adt: &ast::Adt) -> Option<ast::BlockExpr> {
let mut fields = vec![];
for (i, _) in list.fields().enumerate() {
let field_name = format!("arg{i}");
- let pat = make::ident_pat(false, false, make::name(&field_name));
+ let pat = make.ident_pat(false, false, make.name(&field_name));
pats.push(pat.into());
- let f_path = make::expr_path(make::ext::ident_path(&field_name));
+ let f_path = make.expr_path(make.ident_path(&field_name));
fields.push(gen_clone_call(f_path));
}
- let pat = make::tuple_struct_pat(variant_name.clone(), pats.into_iter());
- let struct_name = make::expr_path(variant_name);
- let tuple_expr =
- make::expr_call(struct_name, make::arg_list(fields)).into();
- arms.push(make::match_arm(pat.into(), None, tuple_expr));
+ let pat = make.tuple_struct_pat(variant_name.clone(), pats.into_iter());
+ let struct_name = make.expr_path(variant_name);
+ let tuple_expr = make.expr_call(struct_name, make.arg_list(fields)).into();
+ arms.push(make.match_arm(pat.into(), None, tuple_expr));
}
// => match self { Self::Name => Self::Name }
None => {
- let pattern = make::path_pat(variant_name.clone());
- let variant_expr = make::expr_path(variant_name);
- arms.push(make::match_arm(pattern, None, variant_expr));
+ let pattern = make.path_pat(variant_name.clone());
+ let variant_expr = make.expr_path(variant_name);
+ arms.push(make.match_arm(pattern, None, variant_expr));
}
}
}
- let match_target = make::expr_path(make::ext::ident_path("self"));
- let list = make::match_arm_list(arms).indent(ast::edit::IndentLevel(1));
- make::expr_match(match_target, list).into()
+ let match_target = make.expr_path(make.ident_path("self"));
+ let list = make.match_arm_list(arms).indent(ast::edit::IndentLevel(1));
+ make.expr_match(match_target, list).into()
}
ast::Adt::Struct(strukt) => {
match strukt.field_list() {
@@ -116,43 +120,43 @@ fn gen_clone_impl(adt: &ast::Adt) -> Option<ast::BlockExpr> {
Some(ast::FieldList::RecordFieldList(field_list)) => {
let mut fields = vec![];
for field in field_list.fields() {
- let base = make::expr_path(make::ext::ident_path("self"));
- let target = make::expr_field(base, &field.name()?.to_string());
+ let base = make.expr_path(make.ident_path("self"));
+ let target = make.expr_field(base, &field.name()?.to_string()).into();
let method_call = gen_clone_call(target);
- let name_ref = make::name_ref(&field.name()?.to_string());
- let field = make::record_expr_field(name_ref, Some(method_call));
+ let name_ref = make.name_ref(&field.name()?.to_string());
+ let field = make.record_expr_field(name_ref, Some(method_call));
fields.push(field);
}
- let struct_name = make::ext::ident_path("Self");
- let fields = make::record_expr_field_list(fields);
- make::record_expr(struct_name, fields).into()
+ let struct_name = make.ident_path("Self");
+ let fields = make.record_expr_field_list(fields);
+ make.record_expr(struct_name, fields).into()
}
// => Self(self.0.clone(), self.1.clone())
Some(ast::FieldList::TupleFieldList(field_list)) => {
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 f_path = make.expr_path(make.ident_path("self"));
+ let target = make.expr_field(f_path, &format!("{i}")).into();
fields.push(gen_clone_call(target));
}
- let struct_name = make::expr_path(make::ext::ident_path("Self"));
- make::expr_call(struct_name, make::arg_list(fields)).into()
+ let struct_name = make.expr_path(make.ident_path("Self"));
+ make.expr_call(struct_name, make.arg_list(fields)).into()
}
// => Self { }
None => {
- let struct_name = make::ext::ident_path("Self");
- let fields = make::record_expr_field_list(None);
- make::record_expr(struct_name, fields).into()
+ let struct_name = make.ident_path("Self");
+ let fields = make.record_expr_field_list([]);
+ make.record_expr(struct_name, fields).into()
}
}
}
};
- let body = make::block_expr(None, Some(expr)).indent(ast::edit::IndentLevel(1));
+ let body = make.block_expr(None, Some(expr)).indent(ast::edit::IndentLevel(1));
Some(body)
}
/// Generate a `Debug` impl based on the fields and members of the target type.
-fn gen_debug_impl(adt: &ast::Adt) -> Option<ast::BlockExpr> {
+fn gen_debug_impl(make: &SyntaxFactory, adt: &ast::Adt) -> Option<ast::BlockExpr> {
let annotated_name = adt.name()?;
match adt {
// `Debug` cannot be derived for unions, so no default impl can be provided.
@@ -164,156 +168,154 @@ fn gen_debug_impl(adt: &ast::Adt) -> Option<ast::BlockExpr> {
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 target = make::expr_path(make::ext::ident_path("f"));
+ let variant_name = make.path_from_idents(["Self", &format!("{name}")])?;
+ let target = make.expr_path(make.ident_path("f"));
match variant.field_list() {
Some(ast::FieldList::RecordFieldList(list)) => {
// => f.debug_struct(name)
- let target = make::expr_path(make::ext::ident_path("f"));
- let method = make::name_ref("debug_struct");
+ let target = make.expr_path(make.ident_path("f"));
+ let method = make.name_ref("debug_struct");
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).into();
+ let args = make.arg_list([make.expr_literal(&struct_name).into()]);
+ let mut expr = make.expr_method_call(target, method, args).into();
let mut pats = vec![];
for field in list.fields() {
let field_name = field.name()?;
// create a field pattern for use in `MyStruct { fields.. }`
- let pat = make::ident_pat(false, false, field_name.clone());
- pats.push(pat.into());
+ let pat = make.ident_pat(false, false, field_name.clone());
+ pats.push(make.record_pat_field_shorthand(pat.into()));
// => <expr>.field("field_name", field)
- let method_name = make::name_ref("field");
- let name = make::expr_literal(&(format!("\"{field_name}\""))).into();
+ let method_name = make.name_ref("field");
+ 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).into();
+ let path = make.expr_path(make.ident_path(path));
+ let args = make.arg_list([name, path]);
+ expr = make.expr_method_call(expr, method_name, args).into();
}
// => <expr>.finish()
- let method = make::name_ref("finish");
- let expr =
- make::expr_method_call(expr, method, make::arg_list(None)).into();
+ let method = make.name_ref("finish");
+ let expr = make.expr_method_call(expr, method, make.arg_list([])).into();
// => MyStruct { fields.. } => f.debug_struct("MyStruct")...finish(),
- let pat = make::record_pat(variant_name.clone(), pats.into_iter());
- arms.push(make::match_arm(pat.into(), None, expr));
+ let pat_field_list = make.record_pat_field_list(pats, None);
+ let pat = make.record_pat_with_fields(variant_name.clone(), pat_field_list);
+ arms.push(make.match_arm(pat.into(), None, expr));
}
Some(ast::FieldList::TupleFieldList(list)) => {
// => f.debug_tuple(name)
- let target = make::expr_path(make::ext::ident_path("f"));
- let method = make::name_ref("debug_tuple");
+ let target = make.expr_path(make.ident_path("f"));
+ let method = make.name_ref("debug_tuple");
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).into();
+ let args = make.arg_list([make.expr_literal(&struct_name).into()]);
+ let mut expr = make.expr_method_call(target, method, args).into();
let mut pats = vec![];
for (i, _) in list.fields().enumerate() {
let name = format!("arg{i}");
// create a field pattern for use in `MyStruct(fields..)`
- let field_name = make::name(&name);
- let pat = make::ident_pat(false, false, field_name.clone());
+ let field_name = make.name(&name);
+ let pat = make.ident_pat(false, false, field_name.clone());
pats.push(pat.into());
// => <expr>.field(field)
- let method_name = make::name_ref("field");
+ let method_name = make.name_ref("field");
let field_path = &name.to_string();
- let field_path = make::expr_path(make::ext::ident_path(field_path));
- let args = make::arg_list(vec![field_path]);
- expr = make::expr_method_call(expr, method_name, args).into();
+ let field_path = make.expr_path(make.ident_path(field_path));
+ let args = make.arg_list([field_path]);
+ expr = make.expr_method_call(expr, method_name, args).into();
}
// => <expr>.finish()
- let method = make::name_ref("finish");
- let expr =
- make::expr_method_call(expr, method, make::arg_list(None)).into();
+ let method = make.name_ref("finish");
+ let expr = make.expr_method_call(expr, method, make.arg_list([])).into();
// => MyStruct (fields..) => f.debug_tuple("MyStruct")...finish(),
- let pat = make::tuple_struct_pat(variant_name.clone(), pats.into_iter());
- arms.push(make::match_arm(pat.into(), None, expr));
+ let pat = make.tuple_struct_pat(variant_name.clone(), pats.into_iter());
+ arms.push(make.match_arm(pat.into(), None, expr));
}
None => {
- let fmt_string = make::expr_literal(&(format!("\"{name}\""))).into();
- let args = make::ext::token_tree_from_node(
- make::arg_list([target, fmt_string]).syntax(),
- );
- let macro_name = make::ext::ident_path("write");
- let macro_call = make::expr_macro(macro_name, args);
-
- let variant_name = make::path_pat(variant_name);
- arms.push(make::match_arm(variant_name, None, macro_call.into()));
+ let fmt_string = make.expr_literal(&(format!("\"{name}\""))).into();
+ let args =
+ make.token_tree_from_node(make.arg_list([target, fmt_string]).syntax());
+ let macro_name = make.ident_path("write");
+ let macro_call = make.expr_macro(macro_name, args);
+
+ let variant_name = make.path_pat(variant_name);
+ arms.push(make.match_arm(variant_name, None, macro_call.into()));
}
}
}
- let match_target = make::expr_path(make::ext::ident_path("self"));
- let list = make::match_arm_list(arms).indent(ast::edit::IndentLevel(1));
- let match_expr = make::expr_match(match_target, list);
+ let match_target = make.expr_path(make.ident_path("self"));
+ let list = make.match_arm_list(arms).indent(ast::edit::IndentLevel(1));
+ let match_expr = make.expr_match(match_target, list);
- let body = make::block_expr(None, Some(match_expr.into()));
+ let body = make.block_expr(None::<ast::Stmt>, Some(match_expr.into()));
let body = body.indent(ast::edit::IndentLevel(1));
Some(body)
}
ast::Adt::Struct(strukt) => {
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"));
+ let args = make.arg_list([make.expr_literal(&name).into()]);
+ let target = make.expr_path(make.ident_path("f"));
let expr = match strukt.field_list() {
// => f.debug_struct("Name").finish()
- None => make::expr_method_call(target, make::name_ref("debug_struct"), args).into(),
+ None => make.expr_method_call(target, make.name_ref("debug_struct"), args).into(),
// => f.debug_struct("Name").field("foo", &self.foo).finish()
Some(ast::FieldList::RecordFieldList(field_list)) => {
- let method = make::name_ref("debug_struct");
- let mut expr = make::expr_method_call(target, method, args).into();
+ let method = make.name_ref("debug_struct");
+ let mut expr = make.expr_method_call(target, method, args).into();
for field in field_list.fields() {
let name = field.name()?;
- 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 args = make::arg_list([f_name, f_path]);
- expr = make::expr_method_call(expr, make::name_ref("field"), args).into();
+ let f_name = make.expr_literal(&(format!("\"{name}\""))).into();
+ let f_path = make.expr_path(make.ident_path("self"));
+ let f_path = make.expr_field(f_path, &format!("{name}")).into();
+ let f_path = make.expr_ref(f_path, false);
+ let args = make.arg_list([f_name, f_path]);
+ expr = make.expr_method_call(expr, make.name_ref("field"), args).into();
}
expr
}
- // => f.debug_tuple("Name").field(self.0).finish()
+ // => f.debug_tuple("Name").field(&self.0).finish()
Some(ast::FieldList::TupleFieldList(field_list)) => {
- let method = make::name_ref("debug_tuple");
- let mut expr = make::expr_method_call(target, method, args).into();
+ let method = make.name_ref("debug_tuple");
+ let mut expr = make.expr_method_call(target, method, args).into();
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 method = make::name_ref("field");
- expr = make::expr_method_call(expr, method, make::arg_list(Some(f_path)))
- .into();
+ let f_path = make.expr_path(make.ident_path("self"));
+ let f_path = make.expr_field(f_path, &format!("{i}")).into();
+ let f_path = make.expr_ref(f_path, false);
+ let method = make.name_ref("field");
+ expr = make.expr_method_call(expr, method, make.arg_list([f_path])).into();
}
expr
}
};
- let method = make::name_ref("finish");
- let expr = make::expr_method_call(expr, method, make::arg_list(None)).into();
- let body = make::block_expr(None, Some(expr)).indent(ast::edit::IndentLevel(1));
+ let method = make.name_ref("finish");
+ let expr = make.expr_method_call(expr, method, make.arg_list([])).into();
+ let body =
+ make.block_expr(None::<ast::Stmt>, Some(expr)).indent(ast::edit::IndentLevel(1));
Some(body)
}
}
}
-/// Generate a `Debug` impl based on the fields and members of the target type.
-fn gen_default_impl(adt: &ast::Adt) -> Option<ast::BlockExpr> {
- fn gen_default_call() -> Option<ast::Expr> {
- let fn_name = make::ext::path_from_idents(["Default", "default"])?;
- Some(make::expr_call(make::expr_path(fn_name), make::arg_list(None)).into())
- }
+/// Generate a `Default` impl based on the fields and members of the target type.
+fn gen_default_impl(make: &SyntaxFactory, adt: &ast::Adt) -> Option<ast::BlockExpr> {
+ let gen_default_call = || -> Option<ast::Expr> {
+ let fn_name = make.path_from_idents(["Default", "default"])?;
+ Some(make.expr_call(make.expr_path(fn_name), make.arg_list([])).into())
+ };
match adt {
// `Debug` cannot be derived for unions, so no default impl can be provided.
ast::Adt::Union(_) => None,
@@ -325,42 +327,43 @@ fn gen_default_impl(adt: &ast::Adt) -> Option<ast::BlockExpr> {
let mut fields = vec![];
for field in field_list.fields() {
let method_call = gen_default_call()?;
- let name_ref = make::name_ref(&field.name()?.to_string());
- let field = make::record_expr_field(name_ref, Some(method_call));
+ let name_ref = make.name_ref(&field.name()?.to_string());
+ let field = make.record_expr_field(name_ref, Some(method_call));
fields.push(field);
}
- let struct_name = make::ext::ident_path("Self");
- let fields = make::record_expr_field_list(fields);
- make::record_expr(struct_name, fields).into()
+ let struct_name = make.ident_path("Self");
+ let fields = make.record_expr_field_list(fields);
+ make.record_expr(struct_name, fields).into()
}
Some(ast::FieldList::TupleFieldList(field_list)) => {
- let struct_name = make::expr_path(make::ext::ident_path("Self"));
+ let struct_name = make.expr_path(make.ident_path("Self"));
let fields = field_list
.fields()
.map(|_| gen_default_call())
.collect::<Option<Vec<ast::Expr>>>()?;
- make::expr_call(struct_name, make::arg_list(fields)).into()
+ make.expr_call(struct_name, make.arg_list(fields)).into()
}
None => {
- let struct_name = make::ext::ident_path("Self");
- let fields = make::record_expr_field_list(None);
- make::record_expr(struct_name, fields).into()
+ let struct_name = make.ident_path("Self");
+ let fields = make.record_expr_field_list([]);
+ make.record_expr(struct_name, fields).into()
}
};
- let body = make::block_expr(None, Some(expr)).indent(ast::edit::IndentLevel(1));
+ let body =
+ make.block_expr(None::<ast::Stmt>, Some(expr)).indent(ast::edit::IndentLevel(1));
Some(body)
}
}
}
/// Generate a `Hash` impl based on the fields and members of the target type.
-fn gen_hash_impl(adt: &ast::Adt) -> Option<ast::BlockExpr> {
- fn gen_hash_call(target: ast::Expr) -> ast::Stmt {
- let method = make::name_ref("hash");
- let arg = make::expr_path(make::ext::ident_path("state"));
- let expr = make::expr_method_call(target, method, make::arg_list(Some(arg))).into();
- make::expr_stmt(expr).into()
- }
+fn gen_hash_impl(make: &SyntaxFactory, adt: &ast::Adt) -> Option<ast::BlockExpr> {
+ let gen_hash_call = |target: ast::Expr| -> ast::Stmt {
+ let method = make.name_ref("hash");
+ let arg = make.expr_path(make.ident_path("state"));
+ let expr = make.expr_method_call(target, method, make.arg_list([arg])).into();
+ make.expr_stmt(expr).into()
+ };
let body = match adt {
// `Hash` cannot be derived for unions, so no default impl can be provided.
@@ -368,35 +371,35 @@ fn gen_hash_impl(adt: &ast::Adt) -> Option<ast::BlockExpr> {
// => std::mem::discriminant(self).hash(state);
ast::Adt::Enum(_) => {
- let fn_name = make_discriminant()?;
+ let fn_name = make_discriminant(make)?;
- let arg = make::expr_path(make::ext::ident_path("self"));
- let fn_call = make::expr_call(fn_name, make::arg_list(Some(arg))).into();
+ let arg = make.expr_path(make.ident_path("self"));
+ let fn_call: ast::Expr = make.expr_call(fn_name, make.arg_list([arg])).into();
let stmt = gen_hash_call(fn_call);
- make::block_expr(Some(stmt), None).indent(ast::edit::IndentLevel(1))
+ make.block_expr([stmt], None).indent(ast::edit::IndentLevel(1))
}
ast::Adt::Struct(strukt) => match strukt.field_list() {
// => self.<field>.hash(state);
Some(ast::FieldList::RecordFieldList(field_list)) => {
let mut stmts = vec![];
for field in field_list.fields() {
- let base = make::expr_path(make::ext::ident_path("self"));
- let target = make::expr_field(base, &field.name()?.to_string());
+ let base = make.expr_path(make.ident_path("self"));
+ let target = make.expr_field(base, &field.name()?.to_string()).into();
stmts.push(gen_hash_call(target));
}
- make::block_expr(stmts, None).indent(ast::edit::IndentLevel(1))
+ make.block_expr(stmts, None).indent(ast::edit::IndentLevel(1))
}
// => self.<field_index>.hash(state);
Some(ast::FieldList::TupleFieldList(field_list)) => {
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 base = make.expr_path(make.ident_path("self"));
+ let target = make.expr_field(base, &format!("{i}")).into();
stmts.push(gen_hash_call(target));
}
- make::block_expr(stmts, None).indent(ast::edit::IndentLevel(1))
+ make.block_expr(stmts, None).indent(ast::edit::IndentLevel(1))
}
// No fields in the body means there's nothing to hash.
@@ -408,32 +411,37 @@ fn gen_hash_impl(adt: &ast::Adt) -> Option<ast::BlockExpr> {
}
/// Generate a `PartialEq` impl based on the fields and members of the target type.
-fn gen_partial_eq(adt: &ast::Adt, trait_ref: Option<TraitRef<'_>>) -> Option<ast::BlockExpr> {
- fn gen_eq_chain(expr: Option<ast::Expr>, cmp: ast::Expr) -> Option<ast::Expr> {
+fn gen_partial_eq(
+ make: &SyntaxFactory,
+ adt: &ast::Adt,
+ trait_ref: Option<TraitRef<'_>>,
+) -> Option<ast::BlockExpr> {
+ let gen_eq_chain = |expr: Option<ast::Expr>, cmp: ast::Expr| -> Option<ast::Expr> {
match expr {
- Some(expr) => Some(make::expr_bin_op(expr, BinaryOp::LogicOp(LogicOp::And), cmp)),
+ Some(expr) => Some(make.expr_bin_op(expr, BinaryOp::LogicOp(LogicOp::And), cmp)),
None => Some(cmp),
}
- }
+ };
- fn gen_record_pat_field(field_name: &str, pat_name: &str) -> ast::RecordPatField {
- let pat = make::ext::simple_ident_pat(make::name(pat_name));
- let name_ref = make::name_ref(field_name);
- make::record_pat_field(name_ref, pat.into())
- }
+ let gen_record_pat_field = |field_name: &str, pat_name: &str| -> ast::RecordPatField {
+ let pat = make.ident_pat(false, false, make.name(pat_name));
+ let name_ref = make.name_ref(field_name);
+ make.record_pat_field(name_ref, pat.into())
+ };
- fn gen_record_pat(record_name: ast::Path, fields: Vec<ast::RecordPatField>) -> ast::RecordPat {
- let list = make::record_pat_field_list(fields, None);
- make::record_pat_with_fields(record_name, list)
- }
+ let gen_record_pat =
+ |record_name: ast::Path, fields: Vec<ast::RecordPatField>| -> ast::RecordPat {
+ let list = make.record_pat_field_list(fields, None);
+ make.record_pat_with_fields(record_name, list)
+ };
- fn gen_variant_path(variant: &ast::Variant) -> Option<ast::Path> {
- make::ext::path_from_idents(["Self", &variant.name()?.to_string()])
- }
+ let gen_variant_path = |variant: &ast::Variant| -> Option<ast::Path> {
+ make.path_from_idents(["Self", &variant.name()?.to_string()])
+ };
- fn gen_tuple_field(field_name: &str) -> ast::Pat {
- ast::Pat::IdentPat(make::ident_pat(false, false, make::name(field_name)))
- }
+ let gen_tuple_field = |field_name: &str| -> ast::Pat {
+ ast::Pat::IdentPat(make.ident_pat(false, false, make.name(field_name)))
+ };
// Check that self type and rhs type match. We don't know how to implement the method
// automatically otherwise.
@@ -451,14 +459,14 @@ fn gen_partial_eq(adt: &ast::Adt, trait_ref: Option<TraitRef<'_>>) -> Option<ast
ast::Adt::Enum(enum_) => {
// => std::mem::discriminant(self) == std::mem::discriminant(other)
- let lhs_name = make::expr_path(make::ext::ident_path("self"));
- let lhs = make::expr_call(make_discriminant()?, make::arg_list(Some(lhs_name.clone())))
- .into();
- let rhs_name = make::expr_path(make::ext::ident_path("other"));
- let rhs = make::expr_call(make_discriminant()?, make::arg_list(Some(rhs_name.clone())))
- .into();
+ let lhs_name = make.expr_path(make.ident_path("self"));
+ let lhs =
+ make.expr_call(make_discriminant(make)?, make.arg_list([lhs_name.clone()])).into();
+ let rhs_name = make.expr_path(make.ident_path("other"));
+ let rhs =
+ make.expr_call(make_discriminant(make)?, make.arg_list([rhs_name.clone()])).into();
let eq_check =
- make::expr_bin_op(lhs, BinaryOp::CmpOp(CmpOp::Eq { negated: false }), rhs);
+ make.expr_bin_op(lhs, BinaryOp::CmpOp(CmpOp::Eq { negated: false }), rhs);
let mut n_cases = 0;
let mut arms = vec![];
@@ -480,9 +488,9 @@ fn gen_partial_eq(adt: &ast::Adt, trait_ref: Option<TraitRef<'_>>) -> Option<ast
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));
- let rhs = make::expr_path(make::ext::ident_path(r_name));
- let cmp = make::expr_bin_op(
+ let lhs = make.expr_path(make.ident_path(l_name));
+ let rhs = make.expr_path(make.ident_path(r_name));
+ let cmp = make.expr_bin_op(
lhs,
BinaryOp::CmpOp(CmpOp::Eq { negated: false }),
rhs,
@@ -492,10 +500,10 @@ fn gen_partial_eq(adt: &ast::Adt, trait_ref: Option<TraitRef<'_>>) -> Option<ast
let left = gen_record_pat(gen_variant_path(&variant)?, l_fields);
let right = gen_record_pat(gen_variant_path(&variant)?, r_fields);
- let tuple = make::tuple_pat(vec![left.into(), right.into()]);
+ let tuple = make.tuple_pat(vec![left.into(), right.into()]);
if let Some(expr) = expr {
- arms.push(make::match_arm(tuple.into(), None, expr));
+ arms.push(make.match_arm(tuple.into(), None, expr));
}
}
@@ -513,9 +521,9 @@ fn gen_partial_eq(adt: &ast::Adt, trait_ref: Option<TraitRef<'_>>) -> Option<ast
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));
- let rhs = make::expr_path(make::ext::ident_path(&r_name));
- let cmp = make::expr_bin_op(
+ let lhs = make.expr_path(make.ident_path(&l_name));
+ let rhs = make.expr_path(make.ident_path(&r_name));
+ let cmp = make.expr_bin_op(
lhs,
BinaryOp::CmpOp(CmpOp::Eq { negated: false }),
rhs,
@@ -523,12 +531,12 @@ fn gen_partial_eq(adt: &ast::Adt, trait_ref: Option<TraitRef<'_>>) -> Option<ast
expr = gen_eq_chain(expr, cmp);
}
- let left = make::tuple_struct_pat(gen_variant_path(&variant)?, l_fields);
- let right = make::tuple_struct_pat(gen_variant_path(&variant)?, r_fields);
- let tuple = make::tuple_pat(vec![left.into(), right.into()]);
+ let left = make.tuple_struct_pat(gen_variant_path(&variant)?, l_fields);
+ let right = make.tuple_struct_pat(gen_variant_path(&variant)?, r_fields);
+ let tuple = make.tuple_pat(vec![left.into(), right.into()]);
if let Some(expr) = expr {
- arms.push(make::match_arm(tuple.into(), None, expr));
+ arms.push(make.match_arm(tuple.into(), None, expr));
}
}
None => continue,
@@ -542,57 +550,57 @@ fn gen_partial_eq(adt: &ast::Adt, trait_ref: Option<TraitRef<'_>>) -> Option<ast
// The fallback arm will be `_ => false,` if we've already gone through every case where the variants of self and other match,
// and `_ => std::mem::discriminant(self) == std::mem::discriminant(other),` otherwise.
if n_cases > 1 {
- let lhs = make::wildcard_pat().into();
+ let lhs = make.wildcard_pat().into();
let rhs = if arms_len == n_cases {
- make::expr_literal("false").into()
+ make.expr_literal("false").into()
} else {
eq_check
};
- arms.push(make::match_arm(lhs, None, rhs));
+ arms.push(make.match_arm(lhs, None, rhs));
}
- let match_target = make::expr_tuple([lhs_name, rhs_name]).into();
- let list = make::match_arm_list(arms).indent(ast::edit::IndentLevel(1));
- make::expr_match(match_target, list).into()
+ let match_target = make.expr_tuple([lhs_name, rhs_name]).into();
+ let list = make.match_arm_list(arms).indent(ast::edit::IndentLevel(1));
+ make.expr_match(match_target, list).into()
}
};
- make::block_expr(None, Some(expr)).indent(ast::edit::IndentLevel(1))
+ make.block_expr(None::<ast::Stmt>, Some(expr)).indent(ast::edit::IndentLevel(1))
}
ast::Adt::Struct(strukt) => match strukt.field_list() {
Some(ast::FieldList::RecordFieldList(field_list)) => {
let mut expr = None;
for field in field_list.fields() {
- let lhs = make::expr_path(make::ext::ident_path("self"));
- let lhs = make::expr_field(lhs, &field.name()?.to_string());
- let rhs = make::expr_path(make::ext::ident_path("other"));
- let rhs = make::expr_field(rhs, &field.name()?.to_string());
+ let lhs = make.expr_path(make.ident_path("self"));
+ let lhs = make.expr_field(lhs, &field.name()?.to_string()).into();
+ let rhs = make.expr_path(make.ident_path("other"));
+ let rhs = make.expr_field(rhs, &field.name()?.to_string()).into();
let cmp =
- make::expr_bin_op(lhs, BinaryOp::CmpOp(CmpOp::Eq { negated: false }), rhs);
+ make.expr_bin_op(lhs, BinaryOp::CmpOp(CmpOp::Eq { negated: false }), rhs);
expr = gen_eq_chain(expr, cmp);
}
- make::block_expr(None, expr).indent(ast::edit::IndentLevel(1))
+ make.block_expr(None, expr).indent(ast::edit::IndentLevel(1))
}
Some(ast::FieldList::TupleFieldList(field_list)) => {
let mut expr = None;
for (i, _) in field_list.fields().enumerate() {
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"));
- let rhs = make::expr_field(rhs, &idx);
+ let lhs = make.expr_path(make.ident_path("self"));
+ let lhs = make.expr_field(lhs, &idx).into();
+ let rhs = make.expr_path(make.ident_path("other"));
+ let rhs = make.expr_field(rhs, &idx).into();
let cmp =
- make::expr_bin_op(lhs, BinaryOp::CmpOp(CmpOp::Eq { negated: false }), rhs);
+ make.expr_bin_op(lhs, BinaryOp::CmpOp(CmpOp::Eq { negated: false }), rhs);
expr = gen_eq_chain(expr, cmp);
}
- make::block_expr(None, expr).indent(ast::edit::IndentLevel(1))
+ make.block_expr(None::<ast::Stmt>, expr).indent(ast::edit::IndentLevel(1))
}
// No fields in the body means there's nothing to compare.
None => {
- let expr = make::expr_literal("true").into();
- make::block_expr(None, Some(expr)).indent(ast::edit::IndentLevel(1))
+ let expr = make.expr_literal("true").into();
+ make.block_expr(None, Some(expr)).indent(ast::edit::IndentLevel(1))
}
},
};
@@ -600,29 +608,33 @@ fn gen_partial_eq(adt: &ast::Adt, trait_ref: Option<TraitRef<'_>>) -> Option<ast
Some(body)
}
-fn gen_partial_ord(adt: &ast::Adt, trait_ref: Option<TraitRef<'_>>) -> Option<ast::BlockExpr> {
- fn gen_partial_eq_match(match_target: ast::Expr) -> Option<ast::Stmt> {
+fn gen_partial_ord(
+ make: &SyntaxFactory,
+ adt: &ast::Adt,
+ trait_ref: Option<TraitRef<'_>>,
+) -> Option<ast::BlockExpr> {
+ let gen_partial_eq_match = |match_target: ast::Expr| -> Option<ast::Stmt> {
let mut arms = vec![];
let variant_name =
- make::path_pat(make::ext::path_from_idents(["core", "cmp", "Ordering", "Equal"])?);
- let lhs = make::tuple_struct_pat(make::ext::path_from_idents(["Some"])?, [variant_name]);
- arms.push(make::match_arm(lhs.into(), None, make::expr_empty_block().into()));
+ make.path_pat(make.path_from_idents(["core", "cmp", "Ordering", "Equal"])?);
+ let lhs = make.tuple_struct_pat(make.path_from_idents(["Some"])?, [variant_name]);
+ arms.push(make.match_arm(lhs.into(), None, make.expr_empty_block().into()));
- arms.push(make::match_arm(
- make::ident_pat(false, false, make::name("ord")).into(),
+ arms.push(make.match_arm(
+ make.ident_pat(false, false, make.name("ord")).into(),
None,
- make::expr_return(Some(make::expr_path(make::ext::ident_path("ord")))),
+ make.expr_return(Some(make.expr_path(make.ident_path("ord")))).into(),
));
- let list = make::match_arm_list(arms).indent(ast::edit::IndentLevel(1));
- Some(make::expr_stmt(make::expr_match(match_target, list).into()).into())
- }
+ let list = make.match_arm_list(arms).indent(ast::edit::IndentLevel(1));
+ Some(make.expr_stmt(make.expr_match(match_target, list).into()).into())
+ };
- fn gen_partial_cmp_call(lhs: ast::Expr, rhs: ast::Expr) -> ast::Expr {
- let rhs = make::expr_ref(rhs, false);
- let method = make::name_ref("partial_cmp");
- make::expr_method_call(lhs, method, make::arg_list(Some(rhs))).into()
- }
+ let gen_partial_cmp_call = |lhs: ast::Expr, rhs: ast::Expr| -> ast::Expr {
+ let rhs = make.expr_ref(rhs, false);
+ let method = make.name_ref("partial_cmp");
+ make.expr_method_call(lhs, method, make.arg_list([rhs])).into()
+ };
// Check that self type and rhs type match. We don't know how to implement the method
// automatically otherwise.
@@ -643,10 +655,10 @@ fn gen_partial_ord(adt: &ast::Adt, trait_ref: Option<TraitRef<'_>>) -> Option<as
Some(ast::FieldList::RecordFieldList(field_list)) => {
let mut exprs = vec![];
for field in field_list.fields() {
- let lhs = make::expr_path(make::ext::ident_path("self"));
- let lhs = make::expr_field(lhs, &field.name()?.to_string());
- let rhs = make::expr_path(make::ext::ident_path("other"));
- let rhs = make::expr_field(rhs, &field.name()?.to_string());
+ let lhs = make.expr_path(make.ident_path("self"));
+ let lhs = make.expr_field(lhs, &field.name()?.to_string()).into();
+ let rhs = make.expr_path(make.ident_path("other"));
+ let rhs = make.expr_field(rhs, &field.name()?.to_string()).into();
let ord = gen_partial_cmp_call(lhs, rhs);
exprs.push(ord);
}
@@ -656,17 +668,17 @@ fn gen_partial_ord(adt: &ast::Adt, trait_ref: Option<TraitRef<'_>>) -> Option<as
.into_iter()
.map(gen_partial_eq_match)
.collect::<Option<Vec<ast::Stmt>>>()?;
- make::block_expr(stmts, tail).indent(ast::edit::IndentLevel(1))
+ make.block_expr(stmts, tail).indent(ast::edit::IndentLevel(1))
}
Some(ast::FieldList::TupleFieldList(field_list)) => {
let mut exprs = vec![];
for (i, _) in field_list.fields().enumerate() {
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"));
- let rhs = make::expr_field(rhs, &idx);
+ let lhs = make.expr_path(make.ident_path("self"));
+ let lhs = make.expr_field(lhs, &idx).into();
+ let rhs = make.expr_path(make.ident_path("other"));
+ let rhs = make.expr_field(rhs, &idx).into();
let ord = gen_partial_cmp_call(lhs, rhs);
exprs.push(ord);
}
@@ -675,13 +687,13 @@ fn gen_partial_ord(adt: &ast::Adt, trait_ref: Option<TraitRef<'_>>) -> Option<as
.into_iter()
.map(gen_partial_eq_match)
.collect::<Option<Vec<ast::Stmt>>>()?;
- make::block_expr(stmts, tail).indent(ast::edit::IndentLevel(1))
+ make.block_expr(stmts, tail).indent(ast::edit::IndentLevel(1))
}
// No fields in the body means there's nothing to compare.
None => {
- let expr = make::expr_literal("true").into();
- make::block_expr(None, Some(expr)).indent(ast::edit::IndentLevel(1))
+ let expr = make.expr_literal("true").into();
+ make.block_expr(None, Some(expr)).indent(ast::edit::IndentLevel(1))
}
},
};
@@ -689,6 +701,6 @@ fn gen_partial_ord(adt: &ast::Adt, trait_ref: Option<TraitRef<'_>>) -> Option<as
Some(body)
}
-fn make_discriminant() -> Option<ast::Expr> {
- Some(make::expr_path(make::ext::path_from_idents(["core", "mem", "discriminant"])?))
+fn make_discriminant(make: &SyntaxFactory) -> Option<ast::Expr> {
+ Some(make.expr_path(make.path_from_idents(["core", "mem", "discriminant"])?))
}
diff --git a/crates/syntax/src/ast/syntax_factory/constructors.rs b/crates/syntax/src/ast/syntax_factory/constructors.rs
index 44114a7802..44ab64d4f6 100644
--- a/crates/syntax/src/ast/syntax_factory/constructors.rs
+++ b/crates/syntax/src/ast/syntax_factory/constructors.rs
@@ -2053,6 +2053,17 @@ impl SyntaxFactory {
self.path_unqualified(self.path_segment(self.name_ref(ident)))
}
+ pub fn path_from_idents<'a>(
+ &self,
+ parts: impl IntoIterator<Item = &'a str>,
+ ) -> Option<ast::Path> {
+ make::ext::path_from_idents(parts).map(|path| path.clone_for_update())
+ }
+
+ pub fn token_tree_from_node(&self, node: &SyntaxNode) -> ast::TokenTree {
+ make::ext::token_tree_from_node(node).clone_for_update()
+ }
+
pub fn expr_unit(&self) -> ast::Expr {
self.expr_tuple([]).into()
}