aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/expr
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/expr')
-rw-r--r--crates/ra_hir/src/expr/validation.rs46
1 files changed, 38 insertions, 8 deletions
diff --git a/crates/ra_hir/src/expr/validation.rs b/crates/ra_hir/src/expr/validation.rs
index ca7db61bc..339a7b848 100644
--- a/crates/ra_hir/src/expr/validation.rs
+++ b/crates/ra_hir/src/expr/validation.rs
@@ -6,10 +6,13 @@ use ra_syntax::ast::{AstNode, RecordLit};
6use super::{Expr, ExprId, RecordLitField}; 6use super::{Expr, ExprId, RecordLitField};
7use crate::{ 7use crate::{
8 adt::AdtDef, 8 adt::AdtDef,
9 code_model::Enum,
9 diagnostics::{DiagnosticSink, MissingFields, MissingOkInTailExpr}, 10 diagnostics::{DiagnosticSink, MissingFields, MissingOkInTailExpr},
10 expr::AstPtr, 11 expr::AstPtr,
12 name,
13 path::{PathKind, PathSegment},
11 ty::{InferenceResult, Ty, TypeCtor}, 14 ty::{InferenceResult, Ty, TypeCtor},
12 Function, HasSource, HirDatabase, Name, Path, 15 Function, HasSource, HirDatabase, ModuleDef, Name, Path, PerNs, Resolution
13}; 16};
14use ra_syntax::ast; 17use ra_syntax::ast;
15 18
@@ -106,18 +109,45 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
106 Some(m) => m, 109 Some(m) => m,
107 None => return, 110 None => return,
108 }; 111 };
109 let ret = match &mismatch.expected { 112
110 Ty::Apply(t) => t, 113 let std_result_path = Path {
111 _ => return, 114 kind: PathKind::Abs,
115 segments: vec![
116 PathSegment { name: name::STD, args_and_bindings: None },
117 PathSegment { name: name::RESULT_MOD, args_and_bindings: None },
118 PathSegment { name: name::RESULT_TYPE, args_and_bindings: None },
119 ]
112 }; 120 };
113 let ret_enum = match ret.ctor { 121
114 TypeCtor::Adt(AdtDef::Enum(e)) => e, 122 let resolver = self.func.resolver(db);
123 let std_result_enum = match resolver.resolve_path_segments(db, &std_result_path).into_fully_resolved() {
124 PerNs { types: Some(Resolution::Def(ModuleDef::Enum(e))), .. } => e,
115 _ => return, 125 _ => return,
116 }; 126 };
117 let enum_name = ret_enum.name(db); 127
118 if enum_name.is_none() || enum_name.unwrap().to_string() != "Result" { 128 let std_result_type = std_result_enum.ty(db);
129
130 fn enum_from_type(ty: &Ty) -> Option<Enum> {
131 match ty {
132 Ty::Apply(t) => {
133 match t.ctor {
134 TypeCtor::Adt(AdtDef::Enum(e)) => Some(e),
135 _ => None,
136 }
137 }
138 _ => None
139 }
140 }
141
142 if enum_from_type(&mismatch.expected) != enum_from_type(&std_result_type) {
119 return; 143 return;
120 } 144 }
145
146 let ret = match &mismatch.expected {
147 Ty::Apply(t) => t,
148 _ => return,
149 };
150
121 let params = &ret.parameters; 151 let params = &ret.parameters;
122 if params.len() == 2 && &params[0] == &mismatch.actual { 152 if params.len() == 2 && &params[0] == &mismatch.actual {
123 let source_map = self.func.body_source_map(db); 153 let source_map = self.func.body_source_map(db);