From a14df19d825152aff823fae3344f9e4c2d31937b Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 6 Nov 2020 01:47:41 +0100 Subject: Add infer_function_return_type assist --- .../src/handlers/infer_function_return_type.rs | 113 +++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 crates/assists/src/handlers/infer_function_return_type.rs (limited to 'crates/assists/src/handlers') diff --git a/crates/assists/src/handlers/infer_function_return_type.rs b/crates/assists/src/handlers/infer_function_return_type.rs new file mode 100644 index 000000000..da60ff9de --- /dev/null +++ b/crates/assists/src/handlers/infer_function_return_type.rs @@ -0,0 +1,113 @@ +use hir::HirDisplay; +use syntax::{ast, AstNode, TextSize}; +use test_utils::mark; + +use crate::{AssistContext, AssistId, AssistKind, Assists}; + +// Assist: infer_function_return_type +// +// Adds the return type to a function inferred from its tail expression if it doesn't have a return +// type specified. +// +// ``` +// fn foo() { 4<|>2i32 } +// ``` +// -> +// ``` +// fn foo() -> i32 { 42i32 } +// ``` +pub(crate) fn infer_function_return_type(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { + let expr = ctx.find_node_at_offset::()?; + let func = expr.syntax().ancestors().find_map(ast::Fn::cast)?; + + if func.ret_type().is_some() { + mark::hit!(existing_ret_type); + return None; + } + let body = func.body()?; + let tail_expr = body.expr()?; + // check whether the expr we were at is indeed the tail expression + if !tail_expr.syntax().text_range().contains_range(expr.syntax().text_range()) { + mark::hit!(not_tail_expr); + return None; + } + let module = ctx.sema.scope(func.syntax()).module()?; + let ty = ctx.sema.type_of_expr(&tail_expr)?; + let ty = ty.display_source_code(ctx.db(), module.into()).ok()?; + let rparen = func.param_list()?.r_paren_token()?; + + acc.add( + AssistId("change_return_type_to_result", AssistKind::RefactorRewrite), + "Wrap return type in Result", + tail_expr.syntax().text_range(), + |builder| { + let insert_pos = rparen.text_range().end() + TextSize::from(1); + + builder.insert(insert_pos, &format!("-> {} ", ty)); + }, + ) +} + +#[cfg(test)] +mod tests { + use crate::tests::{check_assist, check_assist_not_applicable}; + + use super::*; + + #[test] + fn infer_return_type() { + check_assist( + infer_function_return_type, + r#"fn foo() { + 45<|> + }"#, + r#"fn foo() -> i32 { + 45 + }"#, + ); + } + + #[test] + fn infer_return_type_nested() { + check_assist( + infer_function_return_type, + r#"fn foo() { + if true { + 3<|> + } else { + 5 + } + }"#, + r#"fn foo() -> i32 { + if true { + 3 + } else { + 5 + } + }"#, + ); + } + + #[test] + fn not_applicable_ret_type_specified() { + mark::check!(existing_ret_type); + check_assist_not_applicable( + infer_function_return_type, + r#"fn foo() -> i32 { + ( 45<|> + 32 ) * 123 + }"#, + ); + } + + #[test] + fn not_applicable_non_tail_expr() { + mark::check!(not_tail_expr); + check_assist_not_applicable( + infer_function_return_type, + r#"fn foo() { + let x = <|>3; + ( 45 + 32 ) * 123 + }"#, + ); + } +} -- cgit v1.2.3 From 0a7c8512ffec9b6cf695f546ac5f4f297c92fa53 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 6 Nov 2020 02:13:29 +0100 Subject: Support closures in infer_function_return_type assist --- .../src/handlers/infer_function_return_type.rs | 133 ++++++++++++++++++--- 1 file changed, 114 insertions(+), 19 deletions(-) (limited to 'crates/assists/src/handlers') diff --git a/crates/assists/src/handlers/infer_function_return_type.rs b/crates/assists/src/handlers/infer_function_return_type.rs index da60ff9de..f363a56f3 100644 --- a/crates/assists/src/handlers/infer_function_return_type.rs +++ b/crates/assists/src/handlers/infer_function_return_type.rs @@ -1,12 +1,12 @@ use hir::HirDisplay; -use syntax::{ast, AstNode, TextSize}; +use syntax::{ast, AstNode, SyntaxToken, TextSize}; use test_utils::mark; use crate::{AssistContext, AssistId, AssistKind, Assists}; // Assist: infer_function_return_type // -// Adds the return type to a function inferred from its tail expression if it doesn't have a return +// Adds the return type to a function or closure inferred from its tail expression if it doesn't have a return // type specified. // // ``` @@ -18,36 +18,52 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; // ``` pub(crate) fn infer_function_return_type(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { let expr = ctx.find_node_at_offset::()?; - let func = expr.syntax().ancestors().find_map(ast::Fn::cast)?; - - if func.ret_type().is_some() { - mark::hit!(existing_ret_type); - return None; - } - let body = func.body()?; - let tail_expr = body.expr()?; - // check whether the expr we were at is indeed the tail expression - if !tail_expr.syntax().text_range().contains_range(expr.syntax().text_range()) { - mark::hit!(not_tail_expr); - return None; - } - let module = ctx.sema.scope(func.syntax()).module()?; + let (tail_expr, insert_pos) = extract(expr)?; + let module = ctx.sema.scope(tail_expr.syntax()).module()?; let ty = ctx.sema.type_of_expr(&tail_expr)?; let ty = ty.display_source_code(ctx.db(), module.into()).ok()?; - let rparen = func.param_list()?.r_paren_token()?; acc.add( AssistId("change_return_type_to_result", AssistKind::RefactorRewrite), "Wrap return type in Result", tail_expr.syntax().text_range(), |builder| { - let insert_pos = rparen.text_range().end() + TextSize::from(1); - + let insert_pos = insert_pos.text_range().end() + TextSize::from(1); builder.insert(insert_pos, &format!("-> {} ", ty)); }, ) } +fn extract(expr: ast::Expr) -> Option<(ast::Expr, SyntaxToken)> { + let (ret_ty, tail_expr, insert_pos) = + if let Some(closure) = expr.syntax().ancestors().find_map(ast::ClosureExpr::cast) { + let tail_expr = match closure.body()? { + ast::Expr::BlockExpr(block) => block.expr()?, + body => body, + }; + let ret_ty = closure.ret_type(); + let rpipe = closure.param_list()?.syntax().last_token()?; + (ret_ty, tail_expr, rpipe) + } else { + let func = expr.syntax().ancestors().find_map(ast::Fn::cast)?; + let tail_expr = func.body()?.expr()?; + let ret_ty = func.ret_type(); + let rparen = func.param_list()?.r_paren_token()?; + (ret_ty, tail_expr, rparen) + }; + if ret_ty.is_some() { + mark::hit!(existing_ret_type); + mark::hit!(existing_ret_type_closure); + return None; + } + // check whether the expr we were at is indeed the tail expression + if !tail_expr.syntax().text_range().contains_range(expr.syntax().text_range()) { + mark::hit!(not_tail_expr); + return None; + } + Some((tail_expr, insert_pos)) +} + #[cfg(test)] mod tests { use crate::tests::{check_assist, check_assist_not_applicable}; @@ -110,4 +126,83 @@ mod tests { }"#, ); } + + #[test] + fn infer_return_type_closure_block() { + check_assist( + infer_function_return_type, + r#"fn foo() { + |x: i32| { + x<|> + }; + }"#, + r#"fn foo() { + |x: i32| -> i32 { + x + }; + }"#, + ); + } + + #[test] + fn infer_return_type_closure() { + check_assist( + infer_function_return_type, + r#"fn foo() { + |x: i32| x<|>; + }"#, + r#"fn foo() { + |x: i32| -> i32 x; + }"#, + ); + } + + #[test] + fn infer_return_type_nested_closure() { + check_assist( + infer_function_return_type, + r#"fn foo() { + || { + if true { + 3<|> + } else { + 5 + } + } + }"#, + r#"fn foo() { + || -> i32 { + if true { + 3 + } else { + 5 + } + } + }"#, + ); + } + + #[test] + fn not_applicable_ret_type_specified_closure() { + mark::check!(existing_ret_type_closure); + check_assist_not_applicable( + infer_function_return_type, + r#"fn foo() { + || -> i32 { 3<|> } + }"#, + ); + } + + #[test] + fn not_applicable_non_tail_expr_closure() { + check_assist_not_applicable( + infer_function_return_type, + r#"fn foo() { + || -> i32 { + let x = 3<|>; + 6 + } + }"#, + ); + } } -- cgit v1.2.3 From 2e6e5d8f7330c7970aa41e452a9fd9e3b3de4d84 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 6 Nov 2020 02:17:34 +0100 Subject: Ignore unit expressions in infer_function_return_type assist --- .../assists/src/handlers/infer_function_return_type.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'crates/assists/src/handlers') diff --git a/crates/assists/src/handlers/infer_function_return_type.rs b/crates/assists/src/handlers/infer_function_return_type.rs index f363a56f3..81217378a 100644 --- a/crates/assists/src/handlers/infer_function_return_type.rs +++ b/crates/assists/src/handlers/infer_function_return_type.rs @@ -18,9 +18,9 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; // ``` pub(crate) fn infer_function_return_type(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { let expr = ctx.find_node_at_offset::()?; - let (tail_expr, insert_pos) = extract(expr)?; + let (tail_expr, insert_pos) = extract_tail(expr)?; let module = ctx.sema.scope(tail_expr.syntax()).module()?; - let ty = ctx.sema.type_of_expr(&tail_expr)?; + let ty = ctx.sema.type_of_expr(&tail_expr).filter(|ty| !ty.is_unit())?; let ty = ty.display_source_code(ctx.db(), module.into()).ok()?; acc.add( @@ -34,7 +34,7 @@ pub(crate) fn infer_function_return_type(acc: &mut Assists, ctx: &AssistContext) ) } -fn extract(expr: ast::Expr) -> Option<(ast::Expr, SyntaxToken)> { +fn extract_tail(expr: ast::Expr) -> Option<(ast::Expr, SyntaxToken)> { let (ret_ty, tail_expr, insert_pos) = if let Some(closure) = expr.syntax().ancestors().find_map(ast::ClosureExpr::cast) { let tail_expr = match closure.body()? { @@ -127,6 +127,16 @@ mod tests { ); } + #[test] + fn not_applicable_unit_return_type() { + check_assist_not_applicable( + infer_function_return_type, + r#"fn foo() { + (<|>) + }"#, + ); + } + #[test] fn infer_return_type_closure_block() { check_assist( -- cgit v1.2.3 From c66588447440b4c1d32c75dd307dc752c83550e4 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 6 Nov 2020 03:06:08 +0100 Subject: Wrap non-block expressions in closures with a block --- .../src/handlers/infer_function_return_type.rs | 43 ++++++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) (limited to 'crates/assists/src/handlers') diff --git a/crates/assists/src/handlers/infer_function_return_type.rs b/crates/assists/src/handlers/infer_function_return_type.rs index 81217378a..b4944a6b0 100644 --- a/crates/assists/src/handlers/infer_function_return_type.rs +++ b/crates/assists/src/handlers/infer_function_return_type.rs @@ -18,38 +18,43 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; // ``` pub(crate) fn infer_function_return_type(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { let expr = ctx.find_node_at_offset::()?; - let (tail_expr, insert_pos) = extract_tail(expr)?; + let (tail_expr, insert_pos, wrap_expr) = extract_tail(expr)?; let module = ctx.sema.scope(tail_expr.syntax()).module()?; let ty = ctx.sema.type_of_expr(&tail_expr).filter(|ty| !ty.is_unit())?; let ty = ty.display_source_code(ctx.db(), module.into()).ok()?; acc.add( - AssistId("change_return_type_to_result", AssistKind::RefactorRewrite), - "Wrap return type in Result", + AssistId("infer_function_return_type", AssistKind::RefactorRewrite), + "Add this function's return type", tail_expr.syntax().text_range(), |builder| { let insert_pos = insert_pos.text_range().end() + TextSize::from(1); builder.insert(insert_pos, &format!("-> {} ", ty)); + if wrap_expr { + 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)); + } }, ) } -fn extract_tail(expr: ast::Expr) -> Option<(ast::Expr, SyntaxToken)> { - let (ret_ty, tail_expr, insert_pos) = +fn extract_tail(expr: ast::Expr) -> Option<(ast::Expr, SyntaxToken, bool)> { + let (ret_ty, tail_expr, insert_pos, wrap_expr) = if let Some(closure) = expr.syntax().ancestors().find_map(ast::ClosureExpr::cast) { - let tail_expr = match closure.body()? { - ast::Expr::BlockExpr(block) => block.expr()?, - body => body, + let (tail_expr, wrap_expr) = match closure.body()? { + ast::Expr::BlockExpr(block) => (block.expr()?, false), + body => (body, true), }; let ret_ty = closure.ret_type(); let rpipe = closure.param_list()?.syntax().last_token()?; - (ret_ty, tail_expr, rpipe) + (ret_ty, tail_expr, rpipe, wrap_expr) } else { let func = expr.syntax().ancestors().find_map(ast::Fn::cast)?; let tail_expr = func.body()?.expr()?; let ret_ty = func.ret_type(); let rparen = func.param_list()?.r_paren_token()?; - (ret_ty, tail_expr, rparen) + (ret_ty, tail_expr, rparen, false) }; if ret_ty.is_some() { mark::hit!(existing_ret_type); @@ -61,7 +66,7 @@ fn extract_tail(expr: ast::Expr) -> Option<(ast::Expr, SyntaxToken)> { mark::hit!(not_tail_expr); return None; } - Some((tail_expr, insert_pos)) + Some((tail_expr, insert_pos, wrap_expr)) } #[cfg(test)] @@ -156,13 +161,27 @@ mod tests { #[test] fn infer_return_type_closure() { + check_assist( + infer_function_return_type, + r#"fn foo() { + |x: i32| { x<|> }; + }"#, + r#"fn foo() { + |x: i32| -> i32 { x }; + }"#, + ); + } + + #[test] + fn infer_return_type_closure_wrap() { + mark::check!(wrap_closure_non_block_expr); check_assist( infer_function_return_type, r#"fn foo() { |x: i32| x<|>; }"#, r#"fn foo() { - |x: i32| -> i32 x; + |x: i32| -> i32 {x}; }"#, ); } -- cgit v1.2.3 From 4f0d02c27694f52dce637e1bfbf2a0bd28dadeac Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 6 Nov 2020 21:49:03 +0100 Subject: Enable infer_function_return_type in return-type position --- .../src/handlers/infer_function_return_type.rs | 158 +++++++++++++++++---- 1 file changed, 129 insertions(+), 29 deletions(-) (limited to 'crates/assists/src/handlers') diff --git a/crates/assists/src/handlers/infer_function_return_type.rs b/crates/assists/src/handlers/infer_function_return_type.rs index b4944a6b0..80864c530 100644 --- a/crates/assists/src/handlers/infer_function_return_type.rs +++ b/crates/assists/src/handlers/infer_function_return_type.rs @@ -1,5 +1,5 @@ use hir::HirDisplay; -use syntax::{ast, AstNode, SyntaxToken, TextSize}; +use syntax::{ast, AstNode, TextRange, TextSize}; use test_utils::mark; use crate::{AssistContext, AssistId, AssistKind, Assists}; @@ -7,7 +7,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; // Assist: infer_function_return_type // // Adds the return type to a function or closure inferred from its tail expression if it doesn't have a return -// type specified. +// type specified. This assists is useable in a functions or closures tail expression or return type position. // // ``` // fn foo() { 4<|>2i32 } @@ -17,10 +17,12 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; // fn foo() -> i32 { 42i32 } // ``` pub(crate) fn infer_function_return_type(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { - let expr = ctx.find_node_at_offset::()?; - let (tail_expr, insert_pos, wrap_expr) = extract_tail(expr)?; + let (tail_expr, builder_edit_pos, wrap_expr) = extract_tail(ctx)?; let module = ctx.sema.scope(tail_expr.syntax()).module()?; - let ty = ctx.sema.type_of_expr(&tail_expr).filter(|ty| !ty.is_unit())?; + let ty = ctx.sema.type_of_expr(&tail_expr)?; + if ty.is_unit() { + return None; + } let ty = ty.display_source_code(ctx.db(), module.into()).ok()?; acc.add( @@ -28,8 +30,14 @@ pub(crate) fn infer_function_return_type(acc: &mut Assists, ctx: &AssistContext) "Add this function's return type", tail_expr.syntax().text_range(), |builder| { - let insert_pos = insert_pos.text_range().end() + TextSize::from(1); - builder.insert(insert_pos, &format!("-> {} ", ty)); + match builder_edit_pos { + InsertOrReplace::Insert(insert_pos) => { + builder.insert(insert_pos, &format!("-> {} ", ty)) + } + InsertOrReplace::Replace(text_range) => { + builder.replace(text_range, &format!("-> {}", ty)) + } + } if wrap_expr { mark::hit!(wrap_closure_non_block_expr); // `|x| x` becomes `|x| -> T x` which is invalid, so wrap it in a block @@ -39,34 +47,69 @@ pub(crate) fn infer_function_return_type(acc: &mut Assists, ctx: &AssistContext) ) } -fn extract_tail(expr: ast::Expr) -> Option<(ast::Expr, SyntaxToken, bool)> { - let (ret_ty, tail_expr, insert_pos, wrap_expr) = - if let Some(closure) = expr.syntax().ancestors().find_map(ast::ClosureExpr::cast) { - let (tail_expr, wrap_expr) = match closure.body()? { +enum InsertOrReplace { + Insert(TextSize), + Replace(TextRange), +} + +/// Check the potentially already specified return type and reject it or turn it into a builder command +/// if allowed. +fn ret_ty_to_action(ret_ty: Option, insert_pos: TextSize) -> Option { + match ret_ty { + Some(ret_ty) => match ret_ty.ty() { + Some(ast::Type::InferType(_)) | None => { + mark::hit!(existing_infer_ret_type); + mark::hit!(existing_infer_ret_type_closure); + Some(InsertOrReplace::Replace(ret_ty.syntax().text_range())) + } + _ => { + mark::hit!(existing_ret_type); + mark::hit!(existing_ret_type_closure); + None + } + }, + None => Some(InsertOrReplace::Insert(insert_pos + TextSize::from(1))), + } +} + +fn extract_tail(ctx: &AssistContext) -> Option<(ast::Expr, InsertOrReplace, bool)> { + let (tail_expr, return_type_range, action, wrap_expr) = + if let Some(closure) = ctx.find_node_at_offset::() { + let rpipe_pos = closure.param_list()?.syntax().last_token()?.text_range().end(); + let action = ret_ty_to_action(closure.ret_type(), rpipe_pos)?; + + let body = closure.body()?; + let body_start = body.syntax().first_token()?.text_range().start(); + let (tail_expr, wrap_expr) = match body { ast::Expr::BlockExpr(block) => (block.expr()?, false), body => (body, true), }; - let ret_ty = closure.ret_type(); - let rpipe = closure.param_list()?.syntax().last_token()?; - (ret_ty, tail_expr, rpipe, wrap_expr) + + let ret_range = TextRange::new(rpipe_pos, body_start); + (tail_expr, ret_range, action, wrap_expr) } else { - let func = expr.syntax().ancestors().find_map(ast::Fn::cast)?; - let tail_expr = func.body()?.expr()?; - let ret_ty = func.ret_type(); - let rparen = func.param_list()?.r_paren_token()?; - (ret_ty, tail_expr, rparen, false) + let func = ctx.find_node_at_offset::()?; + let rparen_pos = func.param_list()?.r_paren_token()?.text_range().end(); + let action = ret_ty_to_action(func.ret_type(), rparen_pos)?; + + let body = func.body()?; + let tail_expr = body.expr()?; + + let ret_range_end = body.l_curly_token()?.text_range().start(); + let ret_range = TextRange::new(rparen_pos, ret_range_end); + (tail_expr, ret_range, action, false) }; - if ret_ty.is_some() { - mark::hit!(existing_ret_type); - mark::hit!(existing_ret_type_closure); - return None; - } - // check whether the expr we were at is indeed the tail expression - if !tail_expr.syntax().text_range().contains_range(expr.syntax().text_range()) { - mark::hit!(not_tail_expr); + let frange = ctx.frange.range; + if return_type_range.contains_range(frange) { + mark::hit!(cursor_in_ret_position); + mark::hit!(cursor_in_ret_position_closure); + } else if tail_expr.syntax().text_range().contains_range(frange) { + mark::hit!(cursor_on_tail); + mark::hit!(cursor_on_tail_closure); + } else { return None; } - Some((tail_expr, insert_pos, wrap_expr)) + Some((tail_expr, action, wrap_expr)) } #[cfg(test)] @@ -75,8 +118,65 @@ mod tests { use super::*; + #[test] + fn infer_return_type_specified_inferred() { + mark::check!(existing_infer_ret_type); + check_assist( + infer_function_return_type, + r#"fn foo() -> <|>_ { + 45 + }"#, + r#"fn foo() -> i32 { + 45 + }"#, + ); + } + + #[test] + fn infer_return_type_specified_inferred_closure() { + mark::check!(existing_infer_ret_type_closure); + check_assist( + infer_function_return_type, + r#"fn foo() { + || -> _ {<|>45}; + }"#, + r#"fn foo() { + || -> i32 {45}; + }"#, + ); + } + + #[test] + fn infer_return_type_cursor_at_return_type_pos() { + mark::check!(cursor_in_ret_position); + check_assist( + infer_function_return_type, + r#"fn foo() <|>{ + 45 + }"#, + r#"fn foo() -> i32 { + 45 + }"#, + ); + } + + #[test] + fn infer_return_type_cursor_at_return_type_pos_closure() { + mark::check!(cursor_in_ret_position_closure); + check_assist( + infer_function_return_type, + r#"fn foo() { + || <|>45 + }"#, + r#"fn foo() { + || -> i32 {45} + }"#, + ); + } + #[test] fn infer_return_type() { + mark::check!(cursor_on_tail); check_assist( infer_function_return_type, r#"fn foo() { @@ -122,7 +222,6 @@ mod tests { #[test] fn not_applicable_non_tail_expr() { - mark::check!(not_tail_expr); check_assist_not_applicable( infer_function_return_type, r#"fn foo() { @@ -144,6 +243,7 @@ mod tests { #[test] fn infer_return_type_closure_block() { + mark::check!(cursor_on_tail_closure); check_assist( infer_function_return_type, r#"fn foo() { -- cgit v1.2.3 From 186431e178c04fed8744d81b834547700af46430 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 6 Nov 2020 21:51:15 +0100 Subject: Adjust test-texts in infer_function_return_type --- .../src/handlers/infer_function_return_type.rs | 156 ++++++++++----------- 1 file changed, 78 insertions(+), 78 deletions(-) (limited to 'crates/assists/src/handlers') diff --git a/crates/assists/src/handlers/infer_function_return_type.rs b/crates/assists/src/handlers/infer_function_return_type.rs index 80864c530..520d07ae0 100644 --- a/crates/assists/src/handlers/infer_function_return_type.rs +++ b/crates/assists/src/handlers/infer_function_return_type.rs @@ -124,11 +124,11 @@ mod tests { check_assist( infer_function_return_type, r#"fn foo() -> <|>_ { - 45 - }"#, + 45 +}"#, r#"fn foo() -> i32 { - 45 - }"#, + 45 +}"#, ); } @@ -138,11 +138,11 @@ mod tests { check_assist( infer_function_return_type, r#"fn foo() { - || -> _ {<|>45}; - }"#, + || -> _ {<|>45}; +}"#, r#"fn foo() { - || -> i32 {45}; - }"#, + || -> i32 {45}; +}"#, ); } @@ -152,11 +152,11 @@ mod tests { check_assist( infer_function_return_type, r#"fn foo() <|>{ - 45 - }"#, + 45 +}"#, r#"fn foo() -> i32 { - 45 - }"#, + 45 +}"#, ); } @@ -166,11 +166,11 @@ mod tests { check_assist( infer_function_return_type, r#"fn foo() { - || <|>45 - }"#, + || <|>45 +}"#, r#"fn foo() { - || -> i32 {45} - }"#, + || -> i32 {45} +}"#, ); } @@ -180,11 +180,11 @@ mod tests { check_assist( infer_function_return_type, r#"fn foo() { - 45<|> - }"#, + 45<|> +}"#, r#"fn foo() -> i32 { - 45 - }"#, + 45 +}"#, ); } @@ -193,19 +193,19 @@ mod tests { check_assist( infer_function_return_type, r#"fn foo() { - if true { - 3<|> - } else { - 5 - } - }"#, + if true { + 3<|> + } else { + 5 + } +}"#, r#"fn foo() -> i32 { - if true { - 3 - } else { - 5 - } - }"#, + if true { + 3 + } else { + 5 + } +}"#, ); } @@ -215,8 +215,8 @@ mod tests { check_assist_not_applicable( infer_function_return_type, r#"fn foo() -> i32 { - ( 45<|> + 32 ) * 123 - }"#, + ( 45<|> + 32 ) * 123 +}"#, ); } @@ -225,9 +225,9 @@ mod tests { check_assist_not_applicable( infer_function_return_type, r#"fn foo() { - let x = <|>3; - ( 45 + 32 ) * 123 - }"#, + let x = <|>3; + ( 45 + 32 ) * 123 +}"#, ); } @@ -236,8 +236,8 @@ mod tests { check_assist_not_applicable( infer_function_return_type, r#"fn foo() { - (<|>) - }"#, + (<|>) +}"#, ); } @@ -247,15 +247,15 @@ mod tests { check_assist( infer_function_return_type, r#"fn foo() { - |x: i32| { - x<|> - }; - }"#, + |x: i32| { + x<|> + }; +}"#, r#"fn foo() { - |x: i32| -> i32 { - x - }; - }"#, + |x: i32| -> i32 { + x + }; +}"#, ); } @@ -264,11 +264,11 @@ mod tests { check_assist( infer_function_return_type, r#"fn foo() { - |x: i32| { x<|> }; - }"#, + |x: i32| { x<|> }; +}"#, r#"fn foo() { - |x: i32| -> i32 { x }; - }"#, + |x: i32| -> i32 { x }; +}"#, ); } @@ -278,11 +278,11 @@ mod tests { check_assist( infer_function_return_type, r#"fn foo() { - |x: i32| x<|>; - }"#, + |x: i32| x<|>; +}"#, r#"fn foo() { - |x: i32| -> i32 {x}; - }"#, + |x: i32| -> i32 {x}; +}"#, ); } @@ -291,23 +291,23 @@ mod tests { check_assist( infer_function_return_type, r#"fn foo() { - || { - if true { - 3<|> - } else { - 5 - } - } - }"#, + || { + if true { + 3<|> + } else { + 5 + } + } +}"#, r#"fn foo() { - || -> i32 { - if true { - 3 - } else { - 5 - } - } - }"#, + || -> i32 { + if true { + 3 + } else { + 5 + } + } +}"#, ); } @@ -317,8 +317,8 @@ mod tests { check_assist_not_applicable( infer_function_return_type, r#"fn foo() { - || -> i32 { 3<|> } - }"#, + || -> i32 { 3<|> } +}"#, ); } @@ -327,11 +327,11 @@ mod tests { check_assist_not_applicable( infer_function_return_type, r#"fn foo() { - || -> i32 { - let x = 3<|>; - 6 - } - }"#, + || -> i32 { + let x = 3<|>; + 6 + } +}"#, ); } } -- cgit v1.2.3