mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-10 15:14:32 +00:00
Auto merge of #17763 - ShoyuVanilla:wrap-unit, r=Veykril
fix: Insert a tail `Ok(())` for expr block instead of wrapping with `Ok` Fixes #17728 When type mismatch is `Result<(), E>, ()` or `Option<()>, ()` and target expr is a block expression, it is more reasonable to insert a wrapped unit - `Ok(())` or `Some(())` - as the tail expression of that block than wrapping the entire block with `Ok` or `Some`
This commit is contained in:
commit
f149dc5029
1 changed files with 68 additions and 2 deletions
|
@ -2,8 +2,12 @@ use either::Either;
|
|||
use hir::{db::ExpandDatabase, ClosureStyle, HirDisplay, HirFileIdExt, InFile, Type};
|
||||
use ide_db::{famous_defs::FamousDefs, source_change::SourceChange};
|
||||
use syntax::{
|
||||
ast::{self, BlockExpr, ExprStmt},
|
||||
AstNode, AstPtr,
|
||||
ast::{
|
||||
self,
|
||||
edit::{AstNodeEdit, IndentLevel},
|
||||
BlockExpr, Expr, ExprStmt,
|
||||
},
|
||||
AstNode, AstPtr, TextSize,
|
||||
};
|
||||
use text_edit::TextEdit;
|
||||
|
||||
|
@ -119,6 +123,38 @@ fn add_missing_ok_or_some(
|
|||
return None;
|
||||
}
|
||||
|
||||
if d.actual.is_unit() {
|
||||
if let Expr::BlockExpr(block) = &expr {
|
||||
if block.tail_expr().is_none() {
|
||||
let mut builder = TextEdit::builder();
|
||||
let block_indent = block.indent_level();
|
||||
|
||||
if block.statements().count() == 0 {
|
||||
// Empty block
|
||||
let indent = block_indent + 1;
|
||||
builder.insert(
|
||||
block.syntax().text_range().start() + TextSize::from(1),
|
||||
format!("\n{indent}{variant_name}(())\n{block_indent}"),
|
||||
);
|
||||
} else {
|
||||
let indent = IndentLevel::from(1);
|
||||
builder.insert(
|
||||
block.syntax().text_range().end() - TextSize::from(1),
|
||||
format!("{indent}{variant_name}(())\n{block_indent}"),
|
||||
);
|
||||
}
|
||||
|
||||
let source_change = SourceChange::from_text_edit(
|
||||
expr_ptr.file_id.original_file(ctx.sema.db),
|
||||
builder.finish(),
|
||||
);
|
||||
let name = format!("Insert {variant_name}(()) as the tail of this block");
|
||||
acc.push(fix("insert_wrapped_unit", &name, source_change, expr_range));
|
||||
}
|
||||
return Some(());
|
||||
}
|
||||
}
|
||||
|
||||
let mut builder = TextEdit::builder();
|
||||
builder.insert(expr.syntax().text_range().start(), format!("{variant_name}("));
|
||||
builder.insert(expr.syntax().text_range().end(), ")".to_owned());
|
||||
|
@ -533,6 +569,36 @@ fn div(x: i32, y: i32) -> MyResult<i32> {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrapped_unit_as_block_tail_expr() {
|
||||
check_fix(
|
||||
r#"
|
||||
//- minicore: result
|
||||
fn foo() -> Result<(), ()> {
|
||||
foo();
|
||||
}$0
|
||||
"#,
|
||||
r#"
|
||||
fn foo() -> Result<(), ()> {
|
||||
foo();
|
||||
Ok(())
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
||||
check_fix(
|
||||
r#"
|
||||
//- minicore: result
|
||||
fn foo() -> Result<(), ()> {}$0
|
||||
"#,
|
||||
r#"
|
||||
fn foo() -> Result<(), ()> {
|
||||
Ok(())
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_in_const_and_static() {
|
||||
check_fix(
|
||||
|
|
Loading…
Reference in a new issue