mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 13:51:31 +00:00
Simplify checking return type, add new test
This commit is contained in:
parent
6a04e9ce14
commit
6620949cae
2 changed files with 32 additions and 23 deletions
|
@ -6,12 +6,11 @@ use ra_syntax::ast::{AstNode, RecordLit};
|
||||||
use super::{Expr, ExprId, RecordLitField};
|
use super::{Expr, ExprId, RecordLitField};
|
||||||
use crate::{
|
use crate::{
|
||||||
adt::AdtDef,
|
adt::AdtDef,
|
||||||
code_model::Enum,
|
|
||||||
diagnostics::{DiagnosticSink, MissingFields, MissingOkInTailExpr},
|
diagnostics::{DiagnosticSink, MissingFields, MissingOkInTailExpr},
|
||||||
expr::AstPtr,
|
expr::AstPtr,
|
||||||
name,
|
name,
|
||||||
path::{PathKind, PathSegment},
|
path::{PathKind, PathSegment},
|
||||||
ty::{InferenceResult, Ty, TypeCtor},
|
ty::{ApplicationTy, InferenceResult, Ty, TypeCtor},
|
||||||
Function, HasSource, HirDatabase, ModuleDef, Name, Path, PerNs, Resolution,
|
Function, HasSource, HirDatabase, ModuleDef, Name, Path, PerNs, Resolution,
|
||||||
};
|
};
|
||||||
use ra_syntax::ast;
|
use ra_syntax::ast;
|
||||||
|
@ -120,28 +119,12 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
let std_result_type = std_result_enum.ty(db);
|
let std_result_ctor = TypeCtor::Adt(AdtDef::Enum(std_result_enum));
|
||||||
|
let params = match &mismatch.expected {
|
||||||
fn enum_from_type(ty: &Ty) -> Option<Enum> {
|
Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters,
|
||||||
match ty {
|
|
||||||
Ty::Apply(t) => match t.ctor {
|
|
||||||
TypeCtor::Adt(AdtDef::Enum(e)) => Some(e),
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if enum_from_type(&mismatch.expected) != enum_from_type(&std_result_type) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let ret = match &mismatch.expected {
|
|
||||||
Ty::Apply(t) => t,
|
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
let params = &ret.parameters;
|
|
||||||
if params.len() == 2 && ¶ms[0] == &mismatch.actual {
|
if params.len() == 2 && ¶ms[0] == &mismatch.actual {
|
||||||
let source_map = self.func.body_source_map(db);
|
let source_map = self.func.body_source_map(db);
|
||||||
let file_id = self.func.source(db).file_id;
|
let file_id = self.func.source(db).file_id;
|
||||||
|
|
|
@ -79,7 +79,7 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
|
||||||
.on::<hir::diagnostics::MissingOkInTailExpr, _>(|d| {
|
.on::<hir::diagnostics::MissingOkInTailExpr, _>(|d| {
|
||||||
let node = d.ast(db);
|
let node = d.ast(db);
|
||||||
let mut builder = TextEditBuilder::default();
|
let mut builder = TextEditBuilder::default();
|
||||||
let replacement = format!("Ok({})", node.syntax().text());
|
let replacement = format!("Ok({})", node.syntax());
|
||||||
builder.replace(node.syntax().text_range(), replacement);
|
builder.replace(node.syntax().text_range(), replacement);
|
||||||
let fix = SourceChange::source_file_edit_from("wrap with ok", file_id, builder.finish());
|
let fix = SourceChange::source_file_edit_from("wrap with ok", file_id, builder.finish());
|
||||||
res.borrow_mut().push(Diagnostic {
|
res.borrow_mut().push(Diagnostic {
|
||||||
|
@ -353,7 +353,7 @@ fn div(x: i32, y: i32) -> MyResult<i32> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_wrap_return_type_not_applicable() {
|
fn test_wrap_return_type_not_applicable_when_expr_type_does_not_match_ok_type() {
|
||||||
let content = r#"
|
let content = r#"
|
||||||
//- /main.rs
|
//- /main.rs
|
||||||
use std::{string::String, result::Result::{self, Ok, Err}};
|
use std::{string::String, result::Result::{self, Ok, Err}};
|
||||||
|
@ -373,6 +373,32 @@ fn div(x: i32, y: i32) -> MyResult<i32> {
|
||||||
check_no_diagnostic_for_target_file("/main.rs", content);
|
check_no_diagnostic_for_target_file("/main.rs", content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_wrap_return_type_not_applicable_when_return_type_is_not_result() {
|
||||||
|
let content = r#"
|
||||||
|
//- /main.rs
|
||||||
|
use std::{string::String, result::Result::{self, Ok, Err}};
|
||||||
|
|
||||||
|
enum SomeOtherEnum {
|
||||||
|
Ok(i32),
|
||||||
|
Err(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo() -> SomeOtherEnum {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
//- /std/lib.rs
|
||||||
|
pub mod string {
|
||||||
|
pub struct String { }
|
||||||
|
}
|
||||||
|
pub mod result {
|
||||||
|
pub enum Result<T, E> { Ok(T), Err(E) }
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
check_no_diagnostic_for_target_file("/main.rs", content);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fill_struct_fields_empty() {
|
fn test_fill_struct_fields_empty() {
|
||||||
let before = r"
|
let before = r"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue