aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/expr
diff options
context:
space:
mode:
authorPhil Ellison <[email protected]>2019-08-11 15:00:37 +0100
committerAleksey Kladov <[email protected]>2019-08-25 10:55:56 +0100
commita40e390860987a23f9b899abc5947f1525d3709c (patch)
tree39aa52a99ce47d439ab92d0519681d4524240820 /crates/ra_hir/src/expr
parent62c2002e2b21b3a74a4e2205ccc40fa93f722b34 (diff)
Check type rather than just name in ok-wrapping diagnostic. Add test for handling generic functions (which currently fails)
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);