mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-31 20:09:01 +00:00
Merge pull request #19569 from snprajwal/fixmes
fix(ast): return correct types for `make::expr_*` methods
This commit is contained in:
commit
dc70a78b03
15 changed files with 79 additions and 75 deletions
|
|
@ -60,13 +60,13 @@ pub(crate) fn convert_for_loop_to_while_let(
|
||||||
{
|
{
|
||||||
(expr, Some(make.name_ref(method.as_str())))
|
(expr, Some(make.name_ref(method.as_str())))
|
||||||
} else if let ast::Expr::RefExpr(_) = iterable {
|
} else if let ast::Expr::RefExpr(_) = iterable {
|
||||||
(make::expr_paren(iterable), Some(make.name_ref("into_iter")))
|
(make::expr_paren(iterable).into(), Some(make.name_ref("into_iter")))
|
||||||
} else {
|
} else {
|
||||||
(iterable, Some(make.name_ref("into_iter")))
|
(iterable, Some(make.name_ref("into_iter")))
|
||||||
};
|
};
|
||||||
|
|
||||||
let iterable = if let Some(method) = method {
|
let iterable = if let Some(method) = method {
|
||||||
make::expr_method_call(iterable, method, make::arg_list([]))
|
make::expr_method_call(iterable, method, make::arg_list([])).into()
|
||||||
} else {
|
} else {
|
||||||
iterable
|
iterable
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,7 @@ fn wrap_ok(expr: ast::Expr) -> ast::Expr {
|
||||||
make::expr_path(make::ext::ident_path("Ok")),
|
make::expr_path(make::ext::ident_path("Ok")),
|
||||||
make::arg_list(std::iter::once(expr)),
|
make::arg_list(std::iter::once(expr)),
|
||||||
)
|
)
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
||||||
|
|
@ -1426,10 +1426,10 @@ fn make_call(ctx: &AssistContext<'_>, fun: &Function, indent: IndentLevel) -> Sy
|
||||||
let name = fun.name.clone();
|
let name = fun.name.clone();
|
||||||
let mut call_expr = if fun.self_param.is_some() {
|
let mut call_expr = if fun.self_param.is_some() {
|
||||||
let self_arg = make::expr_path(make::ext::ident_path("self"));
|
let self_arg = make::expr_path(make::ext::ident_path("self"));
|
||||||
make::expr_method_call(self_arg, name, args)
|
make::expr_method_call(self_arg, name, args).into()
|
||||||
} else {
|
} else {
|
||||||
let func = make::expr_path(make::path_unqualified(make::path_segment(name)));
|
let func = make::expr_path(make::path_unqualified(make::path_segment(name)));
|
||||||
make::expr_call(func, args)
|
make::expr_call(func, args).into()
|
||||||
};
|
};
|
||||||
|
|
||||||
let handler = FlowHandler::from_ret_ty(fun, &ret_ty);
|
let handler = FlowHandler::from_ret_ty(fun, &ret_ty);
|
||||||
|
|
@ -1911,14 +1911,15 @@ fn make_body(ctx: &AssistContext<'_>, old_indent: IndentLevel, fun: &Function) -
|
||||||
};
|
};
|
||||||
let func = make::expr_path(make::ext::ident_path(constructor));
|
let func = make::expr_path(make::ext::ident_path(constructor));
|
||||||
let args = make::arg_list(iter::once(tail_expr));
|
let args = make::arg_list(iter::once(tail_expr));
|
||||||
make::expr_call(func, args)
|
make::expr_call(func, args).into()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
FlowHandler::If { .. } => {
|
FlowHandler::If { .. } => {
|
||||||
let controlflow_continue = make::expr_call(
|
let controlflow_continue = make::expr_call(
|
||||||
make::expr_path(make::path_from_text("ControlFlow::Continue")),
|
make::expr_path(make::path_from_text("ControlFlow::Continue")),
|
||||||
make::arg_list([make::ext::expr_unit()]),
|
make::arg_list([make::ext::expr_unit()]),
|
||||||
);
|
)
|
||||||
|
.into();
|
||||||
with_tail_expr(block, controlflow_continue)
|
with_tail_expr(block, controlflow_continue)
|
||||||
}
|
}
|
||||||
FlowHandler::IfOption { .. } => {
|
FlowHandler::IfOption { .. } => {
|
||||||
|
|
@ -1928,12 +1929,12 @@ fn make_body(ctx: &AssistContext<'_>, old_indent: IndentLevel, fun: &Function) -
|
||||||
FlowHandler::MatchOption { .. } => map_tail_expr(block, |tail_expr| {
|
FlowHandler::MatchOption { .. } => map_tail_expr(block, |tail_expr| {
|
||||||
let some = make::expr_path(make::ext::ident_path("Some"));
|
let some = make::expr_path(make::ext::ident_path("Some"));
|
||||||
let args = make::arg_list(iter::once(tail_expr));
|
let args = make::arg_list(iter::once(tail_expr));
|
||||||
make::expr_call(some, args)
|
make::expr_call(some, args).into()
|
||||||
}),
|
}),
|
||||||
FlowHandler::MatchResult { .. } => map_tail_expr(block, |tail_expr| {
|
FlowHandler::MatchResult { .. } => map_tail_expr(block, |tail_expr| {
|
||||||
let ok = make::expr_path(make::ext::ident_path("Ok"));
|
let ok = make::expr_path(make::ext::ident_path("Ok"));
|
||||||
let args = make::arg_list(iter::once(tail_expr));
|
let args = make::arg_list(iter::once(tail_expr));
|
||||||
make::expr_call(ok, args)
|
make::expr_call(ok, args).into()
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2121,17 +2122,18 @@ fn make_rewritten_flow(handler: &FlowHandler, arg_expr: Option<ast::Expr>) -> Op
|
||||||
FlowHandler::If { .. } => make::expr_call(
|
FlowHandler::If { .. } => make::expr_call(
|
||||||
make::expr_path(make::path_from_text("ControlFlow::Break")),
|
make::expr_path(make::path_from_text("ControlFlow::Break")),
|
||||||
make::arg_list([make::ext::expr_unit()]),
|
make::arg_list([make::ext::expr_unit()]),
|
||||||
),
|
)
|
||||||
|
.into(),
|
||||||
FlowHandler::IfOption { .. } => {
|
FlowHandler::IfOption { .. } => {
|
||||||
let expr = arg_expr.unwrap_or_else(make::ext::expr_unit);
|
let expr = arg_expr.unwrap_or_else(make::ext::expr_unit);
|
||||||
let args = make::arg_list([expr]);
|
let args = make::arg_list([expr]);
|
||||||
make::expr_call(make::expr_path(make::ext::ident_path("Some")), args)
|
make::expr_call(make::expr_path(make::ext::ident_path("Some")), args).into()
|
||||||
}
|
}
|
||||||
FlowHandler::MatchOption { .. } => make::expr_path(make::ext::ident_path("None")),
|
FlowHandler::MatchOption { .. } => make::expr_path(make::ext::ident_path("None")),
|
||||||
FlowHandler::MatchResult { .. } => {
|
FlowHandler::MatchResult { .. } => {
|
||||||
let expr = arg_expr.unwrap_or_else(make::ext::expr_unit);
|
let expr = arg_expr.unwrap_or_else(make::ext::expr_unit);
|
||||||
let args = make::arg_list([expr]);
|
let args = make::arg_list([expr]);
|
||||||
make::expr_call(make::expr_path(make::ext::ident_path("Err")), args)
|
make::expr_call(make::expr_path(make::ext::ident_path("Err")), args).into()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Some(make::expr_return(Some(value)).clone_for_update())
|
Some(make::expr_return(Some(value)).clone_for_update())
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,8 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<'
|
||||||
.map(convert_param_list_to_arg_list)
|
.map(convert_param_list_to_arg_list)
|
||||||
.unwrap_or_else(|| make::arg_list([]));
|
.unwrap_or_else(|| make::arg_list([]));
|
||||||
|
|
||||||
let tail_expr = make::expr_method_call(field, make::name_ref(&name), arg_list);
|
let tail_expr =
|
||||||
|
make::expr_method_call(field, make::name_ref(&name), arg_list).into();
|
||||||
let tail_expr_finished =
|
let tail_expr_finished =
|
||||||
if is_async { make::expr_await(tail_expr) } else { tail_expr };
|
if is_async { make::expr_await(tail_expr) } else { tail_expr };
|
||||||
let body = make::block_expr([], Some(tail_expr_finished));
|
let body = make::block_expr([], Some(tail_expr_finished));
|
||||||
|
|
|
||||||
|
|
@ -751,7 +751,7 @@ fn func_assoc_item(
|
||||||
}
|
}
|
||||||
.clone_for_update();
|
.clone_for_update();
|
||||||
|
|
||||||
let body = make::block_expr(vec![], Some(call)).clone_for_update();
|
let body = make::block_expr(vec![], Some(call.into())).clone_for_update();
|
||||||
let func = make::fn_(
|
let func = make::fn_(
|
||||||
item.visibility(),
|
item.visibility(),
|
||||||
item.name()?,
|
item.name()?,
|
||||||
|
|
|
||||||
|
|
@ -475,7 +475,7 @@ fn make_fn_body_as_new_function(
|
||||||
.map(|_| placeholder_expr.clone())
|
.map(|_| placeholder_expr.clone())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
make::expr_call(make::expr_path(path_self), make::arg_list(args))
|
make::expr_call(make::expr_path(path_self), make::arg_list(args)).into()
|
||||||
}
|
}
|
||||||
StructKind::Unit => make::expr_path(path_self),
|
StructKind::Unit => make::expr_path(path_self),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -512,7 +512,7 @@ fn inline(
|
||||||
&& usage.syntax().parent().and_then(ast::Expr::cast).is_some() =>
|
&& usage.syntax().parent().and_then(ast::Expr::cast).is_some() =>
|
||||||
{
|
{
|
||||||
cov_mark::hit!(inline_call_inline_closure);
|
cov_mark::hit!(inline_call_inline_closure);
|
||||||
let expr = make::expr_paren(expr.clone());
|
let expr = make::expr_paren(expr.clone()).into();
|
||||||
inline_direct(usage, &expr);
|
inline_direct(usage, &expr);
|
||||||
}
|
}
|
||||||
// inline single use literals
|
// inline single use literals
|
||||||
|
|
@ -567,7 +567,7 @@ fn inline(
|
||||||
let no_stmts = body.statements().next().is_none();
|
let no_stmts = body.statements().next().is_none();
|
||||||
match body.tail_expr() {
|
match body.tail_expr() {
|
||||||
Some(expr) if matches!(expr, ast::Expr::ClosureExpr(_)) && no_stmts => {
|
Some(expr) if matches!(expr, ast::Expr::ClosureExpr(_)) && no_stmts => {
|
||||||
make::expr_paren(expr).clone_for_update()
|
make::expr_paren(expr).clone_for_update().into()
|
||||||
}
|
}
|
||||||
Some(expr) if !is_async_fn && no_stmts => expr,
|
Some(expr) if !is_async_fn && no_stmts => expr,
|
||||||
_ => match node
|
_ => match node
|
||||||
|
|
@ -577,7 +577,7 @@ fn inline(
|
||||||
.and_then(|bin_expr| bin_expr.lhs())
|
.and_then(|bin_expr| bin_expr.lhs())
|
||||||
{
|
{
|
||||||
Some(lhs) if lhs.syntax() == node.syntax() => {
|
Some(lhs) if lhs.syntax() == node.syntax() => {
|
||||||
make::expr_paren(ast::Expr::BlockExpr(body)).clone_for_update()
|
make::expr_paren(ast::Expr::BlockExpr(body)).clone_for_update().into()
|
||||||
}
|
}
|
||||||
_ => ast::Expr::BlockExpr(body),
|
_ => ast::Expr::BlockExpr(body),
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ fn compute_dbg_replacement(macro_expr: ast::MacroExpr) -> Option<(TextRange, Opt
|
||||||
None => false,
|
None => false,
|
||||||
};
|
};
|
||||||
let expr = replace_nested_dbgs(expr.clone());
|
let expr = replace_nested_dbgs(expr.clone());
|
||||||
let expr = if wrap { make::expr_paren(expr) } else { expr.clone_subtree() };
|
let expr = if wrap { make::expr_paren(expr).into() } else { expr.clone_subtree() };
|
||||||
(macro_call.syntax().text_range(), Some(expr))
|
(macro_call.syntax().text_range(), Some(expr))
|
||||||
}
|
}
|
||||||
// dbg!(expr0, expr1, ...)
|
// dbg!(expr0, expr1, ...)
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ fn into_closure(param: &Expr) -> Expr {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
.unwrap_or_else(|| make::expr_closure(None, param.clone()))
|
.unwrap_or_else(|| make::expr_closure(None, param.clone()).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assist: replace_with_eager_method
|
// Assist: replace_with_eager_method
|
||||||
|
|
@ -155,7 +155,7 @@ fn into_call(param: &Expr) -> Expr {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
.unwrap_or_else(|| make::expr_call(param.clone(), make::arg_list(Vec::new())))
|
.unwrap_or_else(|| make::expr_call(param.clone(), make::arg_list(Vec::new())).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
||||||
|
|
@ -61,10 +61,13 @@ pub(crate) fn replace_try_expr_with_match(
|
||||||
TryEnum::Option => {
|
TryEnum::Option => {
|
||||||
make::expr_return(Some(make::expr_path(make::ext::ident_path("None"))))
|
make::expr_return(Some(make::expr_path(make::ext::ident_path("None"))))
|
||||||
}
|
}
|
||||||
TryEnum::Result => make::expr_return(Some(make::expr_call(
|
TryEnum::Result => make::expr_return(Some(
|
||||||
|
make::expr_call(
|
||||||
make::expr_path(make::ext::ident_path("Err")),
|
make::expr_path(make::ext::ident_path("Err")),
|
||||||
make::arg_list(iter::once(make::expr_path(make::ext::ident_path("err")))),
|
make::arg_list(iter::once(make::expr_path(make::ext::ident_path("err")))),
|
||||||
))),
|
)
|
||||||
|
.into(),
|
||||||
|
)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let happy_arm = make::match_arm(
|
let happy_arm = make::match_arm(
|
||||||
|
|
|
||||||
|
|
@ -330,7 +330,11 @@ fn invert_special_case_legacy(expr: &ast::Expr) -> Option<ast::Expr> {
|
||||||
T![>] => T![<=],
|
T![>] => T![<=],
|
||||||
T![>=] => T![<],
|
T![>=] => T![<],
|
||||||
// Parenthesize other expressions before prefixing `!`
|
// Parenthesize other expressions before prefixing `!`
|
||||||
_ => return Some(make::expr_prefix(T![!], make::expr_paren(expr.clone())).into()),
|
_ => {
|
||||||
|
return Some(
|
||||||
|
make::expr_prefix(T![!], make::expr_paren(expr.clone()).into()).into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
ted::replace(op_token, make::token(rev_token));
|
ted::replace(op_token, make::token(rev_token));
|
||||||
Some(bin.into())
|
Some(bin.into())
|
||||||
|
|
@ -347,7 +351,7 @@ fn invert_special_case_legacy(expr: &ast::Expr) -> Option<ast::Expr> {
|
||||||
"is_err" => "is_ok",
|
"is_err" => "is_ok",
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
Some(make::expr_method_call(receiver, make::name_ref(method), arg_list))
|
Some(make::expr_method_call(receiver, make::name_ref(method), arg_list).into())
|
||||||
}
|
}
|
||||||
ast::Expr::PrefixExpr(pe) if pe.op_kind()? == ast::UnaryOp::Not => match pe.expr()? {
|
ast::Expr::PrefixExpr(pe) if pe.op_kind()? == ast::UnaryOp::Not => match pe.expr()? {
|
||||||
ast::Expr::ParenExpr(parexpr) => parexpr.expr(),
|
ast::Expr::ParenExpr(parexpr) => parexpr.expr(),
|
||||||
|
|
@ -852,6 +856,7 @@ impl ReferenceConversion {
|
||||||
make::expr_ref(expr, false)
|
make::expr_ref(expr, false)
|
||||||
} else {
|
} else {
|
||||||
make::expr_method_call(expr, make::name_ref("as_ref"), make::arg_list([]))
|
make::expr_method_call(expr, make::name_ref("as_ref"), make::arg_list([]))
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ fn gen_clone_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
||||||
stdx::always!(func.name().is_some_and(|name| name.text() == "clone"));
|
stdx::always!(func.name().is_some_and(|name| name.text() == "clone"));
|
||||||
fn gen_clone_call(target: ast::Expr) -> ast::Expr {
|
fn gen_clone_call(target: ast::Expr) -> ast::Expr {
|
||||||
let method = make::name_ref("clone");
|
let method = make::name_ref("clone");
|
||||||
make::expr_method_call(target, method, make::arg_list(None))
|
make::expr_method_call(target, method, make::arg_list(None)).into()
|
||||||
}
|
}
|
||||||
let expr = match adt {
|
let expr = match adt {
|
||||||
// `Clone` cannot be derived for unions, so no default impl can be provided.
|
// `Clone` cannot be derived for unions, so no default impl can be provided.
|
||||||
|
|
@ -83,7 +83,8 @@ fn gen_clone_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
||||||
}
|
}
|
||||||
let pat = make::tuple_struct_pat(variant_name.clone(), pats.into_iter());
|
let pat = make::tuple_struct_pat(variant_name.clone(), pats.into_iter());
|
||||||
let struct_name = make::expr_path(variant_name);
|
let struct_name = make::expr_path(variant_name);
|
||||||
let tuple_expr = make::expr_call(struct_name, make::arg_list(fields));
|
let tuple_expr =
|
||||||
|
make::expr_call(struct_name, make::arg_list(fields)).into();
|
||||||
arms.push(make::match_arm(pat.into(), None, tuple_expr));
|
arms.push(make::match_arm(pat.into(), None, tuple_expr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,7 +127,7 @@ fn gen_clone_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
||||||
fields.push(gen_clone_call(target));
|
fields.push(gen_clone_call(target));
|
||||||
}
|
}
|
||||||
let struct_name = make::expr_path(make::ext::ident_path("Self"));
|
let struct_name = make::expr_path(make::ext::ident_path("Self"));
|
||||||
make::expr_call(struct_name, make::arg_list(fields))
|
make::expr_call(struct_name, make::arg_list(fields)).into()
|
||||||
}
|
}
|
||||||
// => Self { }
|
// => Self { }
|
||||||
None => {
|
None => {
|
||||||
|
|
@ -165,7 +166,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
||||||
let method = make::name_ref("debug_struct");
|
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 args = make::arg_list(Some(make::expr_literal(&struct_name).into()));
|
||||||
let mut expr = make::expr_method_call(target, method, args);
|
let mut expr = make::expr_method_call(target, method, args).into();
|
||||||
|
|
||||||
let mut pats = vec![];
|
let mut pats = vec![];
|
||||||
for field in list.fields() {
|
for field in list.fields() {
|
||||||
|
|
@ -181,12 +182,13 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
||||||
let path = &format!("{field_name}");
|
let path = &format!("{field_name}");
|
||||||
let path = make::expr_path(make::ext::ident_path(path));
|
let path = make::expr_path(make::ext::ident_path(path));
|
||||||
let args = make::arg_list(vec![name, path]);
|
let args = make::arg_list(vec![name, path]);
|
||||||
expr = make::expr_method_call(expr, method_name, args);
|
expr = make::expr_method_call(expr, method_name, args).into();
|
||||||
}
|
}
|
||||||
|
|
||||||
// => <expr>.finish()
|
// => <expr>.finish()
|
||||||
let method = make::name_ref("finish");
|
let method = make::name_ref("finish");
|
||||||
let expr = make::expr_method_call(expr, method, make::arg_list(None));
|
let expr =
|
||||||
|
make::expr_method_call(expr, method, make::arg_list(None)).into();
|
||||||
|
|
||||||
// => MyStruct { fields.. } => f.debug_struct("MyStruct")...finish(),
|
// => MyStruct { fields.. } => f.debug_struct("MyStruct")...finish(),
|
||||||
let pat = make::record_pat(variant_name.clone(), pats.into_iter());
|
let pat = make::record_pat(variant_name.clone(), pats.into_iter());
|
||||||
|
|
@ -198,7 +200,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
||||||
let method = make::name_ref("debug_tuple");
|
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 args = make::arg_list(Some(make::expr_literal(&struct_name).into()));
|
||||||
let mut expr = make::expr_method_call(target, method, args);
|
let mut expr = make::expr_method_call(target, method, args).into();
|
||||||
|
|
||||||
let mut pats = vec![];
|
let mut pats = vec![];
|
||||||
for (i, _) in list.fields().enumerate() {
|
for (i, _) in list.fields().enumerate() {
|
||||||
|
|
@ -214,12 +216,13 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
||||||
let field_path = &name.to_string();
|
let field_path = &name.to_string();
|
||||||
let field_path = make::expr_path(make::ext::ident_path(field_path));
|
let field_path = make::expr_path(make::ext::ident_path(field_path));
|
||||||
let args = make::arg_list(vec![field_path]);
|
let args = make::arg_list(vec![field_path]);
|
||||||
expr = make::expr_method_call(expr, method_name, args);
|
expr = make::expr_method_call(expr, method_name, args).into();
|
||||||
}
|
}
|
||||||
|
|
||||||
// => <expr>.finish()
|
// => <expr>.finish()
|
||||||
let method = make::name_ref("finish");
|
let method = make::name_ref("finish");
|
||||||
let expr = make::expr_method_call(expr, method, make::arg_list(None));
|
let expr =
|
||||||
|
make::expr_method_call(expr, method, make::arg_list(None)).into();
|
||||||
|
|
||||||
// => MyStruct (fields..) => f.debug_tuple("MyStruct")...finish(),
|
// => MyStruct (fields..) => f.debug_tuple("MyStruct")...finish(),
|
||||||
let pat = make::tuple_struct_pat(variant_name.clone(), pats.into_iter());
|
let pat = make::tuple_struct_pat(variant_name.clone(), pats.into_iter());
|
||||||
|
|
@ -254,12 +257,12 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
||||||
|
|
||||||
let expr = match strukt.field_list() {
|
let expr = match strukt.field_list() {
|
||||||
// => f.debug_struct("Name").finish()
|
// => f.debug_struct("Name").finish()
|
||||||
None => make::expr_method_call(target, make::name_ref("debug_struct"), args),
|
None => make::expr_method_call(target, make::name_ref("debug_struct"), args).into(),
|
||||||
|
|
||||||
// => f.debug_struct("Name").field("foo", &self.foo).finish()
|
// => f.debug_struct("Name").field("foo", &self.foo).finish()
|
||||||
Some(ast::FieldList::RecordFieldList(field_list)) => {
|
Some(ast::FieldList::RecordFieldList(field_list)) => {
|
||||||
let method = make::name_ref("debug_struct");
|
let method = make::name_ref("debug_struct");
|
||||||
let mut expr = make::expr_method_call(target, method, args);
|
let mut expr = make::expr_method_call(target, method, args).into();
|
||||||
for field in field_list.fields() {
|
for field in field_list.fields() {
|
||||||
let name = field.name()?;
|
let name = field.name()?;
|
||||||
let f_name = make::expr_literal(&(format!("\"{name}\""))).into();
|
let f_name = make::expr_literal(&(format!("\"{name}\""))).into();
|
||||||
|
|
@ -267,7 +270,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
||||||
let f_path = make::expr_ref(f_path, false);
|
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]);
|
let args = make::arg_list([f_name, f_path]);
|
||||||
expr = make::expr_method_call(expr, make::name_ref("field"), args);
|
expr = make::expr_method_call(expr, make::name_ref("field"), args).into();
|
||||||
}
|
}
|
||||||
expr
|
expr
|
||||||
}
|
}
|
||||||
|
|
@ -275,20 +278,21 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
||||||
// => f.debug_tuple("Name").field(self.0).finish()
|
// => f.debug_tuple("Name").field(self.0).finish()
|
||||||
Some(ast::FieldList::TupleFieldList(field_list)) => {
|
Some(ast::FieldList::TupleFieldList(field_list)) => {
|
||||||
let method = make::name_ref("debug_tuple");
|
let method = make::name_ref("debug_tuple");
|
||||||
let mut expr = make::expr_method_call(target, method, args);
|
let mut expr = make::expr_method_call(target, method, args).into();
|
||||||
for (i, _) in field_list.fields().enumerate() {
|
for (i, _) in field_list.fields().enumerate() {
|
||||||
let f_path = make::expr_path(make::ext::ident_path("self"));
|
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_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");
|
let method = make::name_ref("field");
|
||||||
expr = make::expr_method_call(expr, method, make::arg_list(Some(f_path)));
|
expr = make::expr_method_call(expr, method, make::arg_list(Some(f_path)))
|
||||||
|
.into();
|
||||||
}
|
}
|
||||||
expr
|
expr
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let method = make::name_ref("finish");
|
let method = make::name_ref("finish");
|
||||||
let expr = make::expr_method_call(expr, method, make::arg_list(None));
|
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 body = make::block_expr(None, Some(expr)).indent(ast::edit::IndentLevel(1));
|
||||||
ted::replace(func.body()?.syntax(), body.clone_for_update().syntax());
|
ted::replace(func.body()?.syntax(), body.clone_for_update().syntax());
|
||||||
Some(())
|
Some(())
|
||||||
|
|
@ -300,7 +304,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
||||||
fn gen_default_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
fn gen_default_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
||||||
fn gen_default_call() -> Option<ast::Expr> {
|
fn gen_default_call() -> Option<ast::Expr> {
|
||||||
let fn_name = make::ext::path_from_idents(["Default", "default"])?;
|
let fn_name = make::ext::path_from_idents(["Default", "default"])?;
|
||||||
Some(make::expr_call(make::expr_path(fn_name), make::arg_list(None)))
|
Some(make::expr_call(make::expr_path(fn_name), make::arg_list(None)).into())
|
||||||
}
|
}
|
||||||
match adt {
|
match adt {
|
||||||
// `Debug` cannot be derived for unions, so no default impl can be provided.
|
// `Debug` cannot be derived for unions, so no default impl can be provided.
|
||||||
|
|
@ -327,7 +331,7 @@ fn gen_default_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
||||||
.fields()
|
.fields()
|
||||||
.map(|_| gen_default_call())
|
.map(|_| gen_default_call())
|
||||||
.collect::<Option<Vec<ast::Expr>>>()?;
|
.collect::<Option<Vec<ast::Expr>>>()?;
|
||||||
make::expr_call(struct_name, make::arg_list(fields))
|
make::expr_call(struct_name, make::arg_list(fields)).into()
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let struct_name = make::ext::ident_path("Self");
|
let struct_name = make::ext::ident_path("Self");
|
||||||
|
|
@ -348,7 +352,7 @@ fn gen_hash_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
||||||
fn gen_hash_call(target: ast::Expr) -> ast::Stmt {
|
fn gen_hash_call(target: ast::Expr) -> ast::Stmt {
|
||||||
let method = make::name_ref("hash");
|
let method = make::name_ref("hash");
|
||||||
let arg = make::expr_path(make::ext::ident_path("state"));
|
let arg = make::expr_path(make::ext::ident_path("state"));
|
||||||
let expr = make::expr_method_call(target, method, make::arg_list(Some(arg)));
|
let expr = make::expr_method_call(target, method, make::arg_list(Some(arg))).into();
|
||||||
make::expr_stmt(expr).into()
|
make::expr_stmt(expr).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -361,7 +365,7 @@ fn gen_hash_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> {
|
||||||
let fn_name = make_discriminant()?;
|
let fn_name = make_discriminant()?;
|
||||||
|
|
||||||
let arg = make::expr_path(make::ext::ident_path("self"));
|
let arg = make::expr_path(make::ext::ident_path("self"));
|
||||||
let fn_call = make::expr_call(fn_name, make::arg_list(Some(arg)));
|
let fn_call = make::expr_call(fn_name, make::arg_list(Some(arg))).into();
|
||||||
let stmt = gen_hash_call(fn_call);
|
let stmt = gen_hash_call(fn_call);
|
||||||
|
|
||||||
make::block_expr(Some(stmt), None).indent(ast::edit::IndentLevel(1))
|
make::block_expr(Some(stmt), None).indent(ast::edit::IndentLevel(1))
|
||||||
|
|
@ -444,9 +448,11 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn, trait_ref: Option<TraitRef>) -
|
||||||
ast::Adt::Enum(enum_) => {
|
ast::Adt::Enum(enum_) => {
|
||||||
// => std::mem::discriminant(self) == std::mem::discriminant(other)
|
// => std::mem::discriminant(self) == std::mem::discriminant(other)
|
||||||
let lhs_name = make::expr_path(make::ext::ident_path("self"));
|
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())));
|
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_name = make::expr_path(make::ext::ident_path("other"));
|
||||||
let rhs = make::expr_call(make_discriminant()?, make::arg_list(Some(rhs_name.clone())));
|
let rhs = make::expr_call(make_discriminant()?, make::arg_list(Some(rhs_name.clone())))
|
||||||
|
.into();
|
||||||
let eq_check =
|
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);
|
||||||
|
|
||||||
|
|
@ -613,7 +619,7 @@ fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn, trait_ref: Option<TraitRef>)
|
||||||
fn gen_partial_cmp_call(lhs: ast::Expr, rhs: ast::Expr) -> ast::Expr {
|
fn gen_partial_cmp_call(lhs: ast::Expr, rhs: ast::Expr) -> ast::Expr {
|
||||||
let rhs = make::expr_ref(rhs, false);
|
let rhs = make::expr_ref(rhs, false);
|
||||||
let method = make::name_ref("partial_cmp");
|
let method = make::name_ref("partial_cmp");
|
||||||
make::expr_method_call(lhs, method, make::arg_list(Some(rhs)))
|
make::expr_method_call(lhs, method, make::arg_list(Some(rhs))).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that self type and rhs type match. We don't know how to implement the method
|
// Check that self type and rhs type match. We don't know how to implement the method
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ impl RefData {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.needs_parentheses {
|
if self.needs_parentheses {
|
||||||
expr = make::expr_paren(expr);
|
expr = make::expr_paren(expr).into();
|
||||||
}
|
}
|
||||||
|
|
||||||
expr
|
expr
|
||||||
|
|
|
||||||
|
|
@ -633,14 +633,14 @@ pub fn expr_prefix(op: SyntaxKind, expr: ast::Expr) -> ast::PrefixExpr {
|
||||||
let token = token(op);
|
let token = token(op);
|
||||||
expr_from_text(&format!("{token}{expr}"))
|
expr_from_text(&format!("{token}{expr}"))
|
||||||
}
|
}
|
||||||
pub fn expr_call(f: ast::Expr, arg_list: ast::ArgList) -> ast::Expr {
|
pub fn expr_call(f: ast::Expr, arg_list: ast::ArgList) -> ast::CallExpr {
|
||||||
expr_from_text(&format!("{f}{arg_list}"))
|
expr_from_text(&format!("{f}{arg_list}"))
|
||||||
}
|
}
|
||||||
pub fn expr_method_call(
|
pub fn expr_method_call(
|
||||||
receiver: ast::Expr,
|
receiver: ast::Expr,
|
||||||
method: ast::NameRef,
|
method: ast::NameRef,
|
||||||
arg_list: ast::ArgList,
|
arg_list: ast::ArgList,
|
||||||
) -> ast::Expr {
|
) -> ast::MethodCallExpr {
|
||||||
expr_from_text(&format!("{receiver}.{method}{arg_list}"))
|
expr_from_text(&format!("{receiver}.{method}{arg_list}"))
|
||||||
}
|
}
|
||||||
pub fn expr_macro_call(f: ast::Expr, arg_list: ast::ArgList) -> ast::Expr {
|
pub fn expr_macro_call(f: ast::Expr, arg_list: ast::ArgList) -> ast::Expr {
|
||||||
|
|
@ -652,14 +652,17 @@ pub fn expr_ref(expr: ast::Expr, exclusive: bool) -> ast::Expr {
|
||||||
pub fn expr_reborrow(expr: ast::Expr) -> ast::Expr {
|
pub fn expr_reborrow(expr: ast::Expr) -> ast::Expr {
|
||||||
expr_from_text(&format!("&mut *{expr}"))
|
expr_from_text(&format!("&mut *{expr}"))
|
||||||
}
|
}
|
||||||
pub fn expr_closure(pats: impl IntoIterator<Item = ast::Param>, expr: ast::Expr) -> ast::Expr {
|
pub fn expr_closure(
|
||||||
|
pats: impl IntoIterator<Item = ast::Param>,
|
||||||
|
expr: ast::Expr,
|
||||||
|
) -> ast::ClosureExpr {
|
||||||
let params = pats.into_iter().join(", ");
|
let params = pats.into_iter().join(", ");
|
||||||
expr_from_text(&format!("|{params}| {expr}"))
|
expr_from_text(&format!("|{params}| {expr}"))
|
||||||
}
|
}
|
||||||
pub fn expr_field(receiver: ast::Expr, field: &str) -> ast::Expr {
|
pub fn expr_field(receiver: ast::Expr, field: &str) -> ast::Expr {
|
||||||
expr_from_text(&format!("{receiver}.{field}"))
|
expr_from_text(&format!("{receiver}.{field}"))
|
||||||
}
|
}
|
||||||
pub fn expr_paren(expr: ast::Expr) -> ast::Expr {
|
pub fn expr_paren(expr: ast::Expr) -> ast::ParenExpr {
|
||||||
expr_from_text(&format!("({expr})"))
|
expr_from_text(&format!("({expr})"))
|
||||||
}
|
}
|
||||||
pub fn expr_tuple(elements: impl IntoIterator<Item = ast::Expr>) -> ast::TupleExpr {
|
pub fn expr_tuple(elements: impl IntoIterator<Item = ast::Expr>) -> ast::TupleExpr {
|
||||||
|
|
|
||||||
|
|
@ -328,10 +328,7 @@ impl SyntaxFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expr_paren(&self, expr: ast::Expr) -> ast::ParenExpr {
|
pub fn expr_paren(&self, expr: ast::Expr) -> ast::ParenExpr {
|
||||||
// FIXME: `make::expr_paren` should return a `ParenExpr`, not just an `Expr`
|
let ast = make::expr_paren(expr.clone()).clone_for_update();
|
||||||
let ast::Expr::ParenExpr(ast) = make::expr_paren(expr.clone()).clone_for_update() else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(mut mapping) = self.mappings() {
|
if let Some(mut mapping) = self.mappings() {
|
||||||
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
|
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
|
||||||
|
|
@ -403,12 +400,7 @@ impl SyntaxFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expr_call(&self, expr: ast::Expr, arg_list: ast::ArgList) -> ast::CallExpr {
|
pub fn expr_call(&self, expr: ast::Expr, arg_list: ast::ArgList) -> ast::CallExpr {
|
||||||
// FIXME: `make::expr_call`` should return a `CallExpr`, not just an `Expr`
|
let ast = make::expr_call(expr.clone(), arg_list.clone()).clone_for_update();
|
||||||
let ast::Expr::CallExpr(ast) =
|
|
||||||
make::expr_call(expr.clone(), arg_list.clone()).clone_for_update()
|
|
||||||
else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(mut mapping) = self.mappings() {
|
if let Some(mut mapping) = self.mappings() {
|
||||||
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
|
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
|
||||||
|
|
@ -426,13 +418,8 @@ impl SyntaxFactory {
|
||||||
method: ast::NameRef,
|
method: ast::NameRef,
|
||||||
arg_list: ast::ArgList,
|
arg_list: ast::ArgList,
|
||||||
) -> ast::MethodCallExpr {
|
) -> ast::MethodCallExpr {
|
||||||
// FIXME: `make::expr_method_call` should return a `MethodCallExpr`, not just an `Expr`
|
let ast = make::expr_method_call(receiver.clone(), method.clone(), arg_list.clone())
|
||||||
let ast::Expr::MethodCallExpr(ast) =
|
.clone_for_update();
|
||||||
make::expr_method_call(receiver.clone(), method.clone(), arg_list.clone())
|
|
||||||
.clone_for_update()
|
|
||||||
else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(mut mapping) = self.mappings() {
|
if let Some(mut mapping) = self.mappings() {
|
||||||
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
|
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
|
||||||
|
|
@ -479,11 +466,7 @@ impl SyntaxFactory {
|
||||||
expr: ast::Expr,
|
expr: ast::Expr,
|
||||||
) -> ast::ClosureExpr {
|
) -> ast::ClosureExpr {
|
||||||
let (args, input) = iterator_input(pats);
|
let (args, input) = iterator_input(pats);
|
||||||
// FIXME: `make::expr_paren` should return a `ClosureExpr`, not just an `Expr`
|
let ast = make::expr_closure(args, expr.clone()).clone_for_update();
|
||||||
let ast::Expr::ClosureExpr(ast) = make::expr_closure(args, expr.clone()).clone_for_update()
|
|
||||||
else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(mut mapping) = self.mappings() {
|
if let Some(mut mapping) = self.mappings() {
|
||||||
let mut builder = SyntaxMappingBuilder::new(ast.syntax.clone());
|
let mut builder = SyntaxMappingBuilder::new(ast.syntax.clone());
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue