// fn foo() -> i32 { 42i32 }
// ```
pub(crate) fn add_return_type(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
- let (fn_type, tail_expr, builder_edit_pos, needs_whitespace) = extract_tail(ctx)?;
+ let (fn_type, tail_expr, builder_edit_pos) = extract_tail(ctx)?;
let module = ctx.sema.scope(tail_expr.syntax()).module()?;
let ty = ctx.sema.type_of_expr(&tail_expr)?.adjusted();
if ty.is_unit() {
},
tail_expr.syntax().text_range(),
|builder| {
- let preceeding_whitespace = if needs_whitespace { " " } else { "" };
-
match builder_edit_pos {
- InsertOrReplace::Insert(insert_pos) => {
+ InsertOrReplace::Insert(insert_pos, needs_whitespace) => {
+ let preceeding_whitespace = if needs_whitespace { " " } else { "" };
builder.insert(insert_pos, &format!("{}-> {} ", preceeding_whitespace, ty))
}
InsertOrReplace::Replace(text_range) => {
- builder.replace(text_range, &format!("{}-> {}", preceeding_whitespace, ty))
+ builder.replace(text_range, &format!("-> {}", ty))
}
}
if let FnType::Closure { wrap_expr: true } = fn_type {
}
enum InsertOrReplace {
- Insert(TextSize),
+ Insert(TextSize, bool),
Replace(TextRange),
}
fn ret_ty_to_action(
ret_ty: Option<ast::RetType>,
insert_after: SyntaxToken,
-) -> Option<(InsertOrReplace, bool)> {
+) -> Option<InsertOrReplace> {
match ret_ty {
Some(ret_ty) => match ret_ty.ty() {
Some(ast::Type::InferType(_)) | None => {
cov_mark::hit!(existing_infer_ret_type);
cov_mark::hit!(existing_infer_ret_type_closure);
- Some((InsertOrReplace::Replace(ret_ty.syntax().text_range()), false))
+ Some(InsertOrReplace::Replace(ret_ty.syntax().text_range()))
}
_ => {
cov_mark::hit!(existing_ret_type);
_ => (insert_after_pos, true),
};
- Some((InsertOrReplace::Insert(insert_pos), needs_whitespace))
+ Some(InsertOrReplace::Insert(insert_pos, needs_whitespace))
}
}
}
Closure { wrap_expr: bool },
}
-fn extract_tail(ctx: &AssistContext) -> Option<(FnType, ast::Expr, InsertOrReplace, bool)> {
- let (fn_type, tail_expr, return_type_range, action, needs_whitespace) =
+fn extract_tail(ctx: &AssistContext) -> Option<(FnType, ast::Expr, InsertOrReplace)> {
+ let (fn_type, tail_expr, return_type_range, action) =
if let Some(closure) = ctx.find_node_at_offset::<ast::ClosureExpr>() {
let rpipe = closure.param_list()?.syntax().last_token()?;
let rpipe_pos = rpipe.text_range().end();
- let (action, needs_whitespace) = ret_ty_to_action(closure.ret_type(), rpipe)?;
+ let action = ret_ty_to_action(closure.ret_type(), rpipe)?;
let body = closure.body()?;
let body_start = body.syntax().first_token()?.text_range().start();
};
let ret_range = TextRange::new(rpipe_pos, body_start);
- (FnType::Closure { wrap_expr }, tail_expr, ret_range, action, needs_whitespace)
+ (FnType::Closure { wrap_expr }, tail_expr, ret_range, action)
} else {
let func = ctx.find_node_at_offset::<ast::Fn>()?;
let rparen = func.param_list()?.r_paren_token()?;
let rparen_pos = rparen.text_range().end();
- let (action, needs_whitespace) = ret_ty_to_action(func.ret_type(), rparen)?;
+ let action = ret_ty_to_action(func.ret_type(), rparen)?;
let body = func.body()?;
let stmt_list = body.stmt_list()?;
let ret_range_end = stmt_list.l_curly_token()?.text_range().start();
let ret_range = TextRange::new(rparen_pos, ret_range_end);
- (FnType::Function, tail_expr, ret_range, action, needs_whitespace)
+ (FnType::Function, tail_expr, ret_range, action)
};
let range = ctx.selection_trimmed();
if return_type_range.contains_range(range) {
} else {
return None;
}
- Some((fn_type, tail_expr, action, needs_whitespace))
+ Some((fn_type, tail_expr, action))
}
#[cfg(test)]