diff --git a/crates/ra_hir/src/expr/validation.rs b/crates/ra_hir/src/expr/validation.rs index e35990d2ea..5d9d59ff89 100644 --- a/crates/ra_hir/src/expr/validation.rs +++ b/crates/ra_hir/src/expr/validation.rs @@ -6,12 +6,11 @@ use ra_syntax::ast::{AstNode, RecordLit}; use super::{Expr, ExprId, RecordLitField}; use crate::{ adt::AdtDef, - code_model::Enum, diagnostics::{DiagnosticSink, MissingFields, MissingOkInTailExpr}, expr::AstPtr, name, path::{PathKind, PathSegment}, - ty::{InferenceResult, Ty, TypeCtor}, + ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, Function, HasSource, HirDatabase, ModuleDef, Name, Path, PerNs, Resolution, }; use ra_syntax::ast; @@ -120,28 +119,12 @@ impl<'a, 'b> ExprValidator<'a, 'b> { _ => return, }; - let std_result_type = std_result_enum.ty(db); - - fn enum_from_type(ty: &Ty) -> Option { - 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, + let std_result_ctor = TypeCtor::Adt(AdtDef::Enum(std_result_enum)); + let params = match &mismatch.expected { + Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters, _ => return, }; - let params = &ret.parameters; if params.len() == 2 && ¶ms[0] == &mismatch.actual { let source_map = self.func.body_source_map(db); let file_id = self.func.source(db).file_id; diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index 0b9bb5a66c..94424dc169 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs @@ -79,7 +79,7 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec .on::(|d| { let node = d.ast(db); 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); let fix = SourceChange::source_file_edit_from("wrap with ok", file_id, builder.finish()); res.borrow_mut().push(Diagnostic { @@ -353,7 +353,7 @@ fn div(x: i32, y: i32) -> MyResult { } #[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#" //- /main.rs use std::{string::String, result::Result::{self, Ok, Err}}; @@ -373,6 +373,32 @@ fn div(x: i32, y: i32) -> MyResult { 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 { Ok(T), Err(E) } + } + "#; + check_no_diagnostic_for_target_file("/main.rs", content); + } + #[test] fn test_fill_struct_fields_empty() { let before = r"