diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 92de9842c..7905d86a1 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -130,9 +130,9 @@ pub struct FnSig { | |||
130 | } | 130 | } |
131 | 131 | ||
132 | impl Ty { | 132 | impl Ty { |
133 | pub fn new(node: ast::TypeRef) -> Self { | 133 | pub fn new(_db: &impl HirDatabase, node: ast::TypeRef) -> Cancelable<Self> { |
134 | use ra_syntax::ast::TypeRef::*; | 134 | use ra_syntax::ast::TypeRef::*; |
135 | match node { | 135 | Ok(match node { |
136 | ParenType(_inner) => Ty::Unknown, // TODO | 136 | ParenType(_inner) => Ty::Unknown, // TODO |
137 | TupleType(_inner) => Ty::Unknown, // TODO | 137 | TupleType(_inner) => Ty::Unknown, // TODO |
138 | NeverType(..) => Ty::Never, | 138 | NeverType(..) => Ty::Never, |
@@ -140,7 +140,7 @@ impl Ty { | |||
140 | let path = if let Some(p) = inner.path() { | 140 | let path = if let Some(p) = inner.path() { |
141 | p | 141 | p |
142 | } else { | 142 | } else { |
143 | return Ty::Unknown; | 143 | return Ok(Ty::Unknown); |
144 | }; | 144 | }; |
145 | if path.qualifier().is_none() { | 145 | if path.qualifier().is_none() { |
146 | let name = path | 146 | let name = path |
@@ -172,7 +172,7 @@ impl Ty { | |||
172 | ForType(_inner) => Ty::Unknown, // TODO | 172 | ForType(_inner) => Ty::Unknown, // TODO |
173 | ImplTraitType(_inner) => Ty::Unknown, // TODO | 173 | ImplTraitType(_inner) => Ty::Unknown, // TODO |
174 | DynTraitType(_inner) => Ty::Unknown, // TODO | 174 | DynTraitType(_inner) => Ty::Unknown, // TODO |
175 | } | 175 | }) |
176 | } | 176 | } |
177 | 177 | ||
178 | pub fn unit() -> Self { | 178 | pub fn unit() -> Self { |
@@ -218,19 +218,28 @@ pub fn type_for_fn(db: &impl HirDatabase, f: Function) -> Cancelable<Ty> { | |||
218 | .param_list() | 218 | .param_list() |
219 | .map(|pl| { | 219 | .map(|pl| { |
220 | pl.params() | 220 | pl.params() |
221 | .map(|p| p.type_ref().map(|t| Ty::new(t)).unwrap_or(Ty::Unknown)) | 221 | .map(|p| { |
222 | p.type_ref() | ||
223 | .map(|t| Ty::new(db, t)) | ||
224 | .unwrap_or(Ok(Ty::Unknown)) | ||
225 | }) | ||
222 | .collect() | 226 | .collect() |
223 | }) | 227 | }) |
224 | .unwrap_or_else(Vec::new); | 228 | .unwrap_or_else(|| Ok(Vec::new()))?; |
225 | let output = node | 229 | let output = node |
226 | .ret_type() | 230 | .ret_type() |
227 | .and_then(|rt| rt.type_ref()) | 231 | .and_then(|rt| rt.type_ref()) |
228 | .map(|t| Ty::new(t)) | 232 | .map(|t| Ty::new(db, t)) |
229 | .unwrap_or(Ty::Unknown); | 233 | .unwrap_or(Ok(Ty::Unknown))?; |
230 | let sig = FnSig { input, output }; | 234 | let sig = FnSig { input, output }; |
231 | Ok(Ty::FnPtr(Arc::new(sig))) | 235 | Ok(Ty::FnPtr(Arc::new(sig))) |
232 | } | 236 | } |
233 | 237 | ||
238 | // TODO this should probably be per namespace (i.e. types vs. values), since for | ||
239 | // a tuple struct `struct Foo(Bar)`, Foo has function type as a value, but | ||
240 | // defines the struct type Foo when used in the type namespace. rustc has a | ||
241 | // separate DefId for the constructor, but with the current DefId approach, that | ||
242 | // seems complicated. | ||
234 | pub fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Ty> { | 243 | pub fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Ty> { |
235 | let def = def_id.resolve(db)?; | 244 | let def = def_id.resolve(db)?; |
236 | match def { | 245 | match def { |
@@ -408,9 +417,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
408 | } | 417 | } |
409 | } | 418 | } |
410 | match callee_ty { | 419 | match callee_ty { |
411 | Ty::FnPtr(sig) => { | 420 | Ty::FnPtr(sig) => sig.output.clone(), |
412 | sig.output.clone() | ||
413 | } | ||
414 | _ => { | 421 | _ => { |
415 | // not callable | 422 | // not callable |
416 | // TODO report an error? | 423 | // TODO report an error? |
@@ -499,7 +506,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
499 | } else { | 506 | } else { |
500 | Ty::Unknown | 507 | Ty::Unknown |
501 | }; | 508 | }; |
502 | let cast_ty = e.type_ref().map(Ty::new).unwrap_or(Ty::Unknown); | 509 | let cast_ty = e |
510 | .type_ref() | ||
511 | .map(|t| Ty::new(self.db, t)) | ||
512 | .unwrap_or(Ok(Ty::Unknown))?; | ||
503 | // TODO do the coercion... | 513 | // TODO do the coercion... |
504 | cast_ty | 514 | cast_ty |
505 | } | 515 | } |
@@ -532,7 +542,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
532 | match stmt { | 542 | match stmt { |
533 | ast::Stmt::LetStmt(stmt) => { | 543 | ast::Stmt::LetStmt(stmt) => { |
534 | let decl_ty = if let Some(type_ref) = stmt.type_ref() { | 544 | let decl_ty = if let Some(type_ref) = stmt.type_ref() { |
535 | Ty::new(type_ref) | 545 | Ty::new(self.db, type_ref)? |
536 | } else { | 546 | } else { |
537 | Ty::Unknown | 547 | Ty::Unknown |
538 | }; | 548 | }; |
@@ -582,7 +592,7 @@ pub fn infer(db: &impl HirDatabase, function: Function) -> Cancelable<InferenceR | |||
582 | continue; | 592 | continue; |
583 | }; | 593 | }; |
584 | if let Some(type_ref) = param.type_ref() { | 594 | if let Some(type_ref) = param.type_ref() { |
585 | let ty = Ty::new(type_ref); | 595 | let ty = Ty::new(db, type_ref)?; |
586 | ctx.type_for.insert(LocalSyntaxPtr::new(pat.syntax()), ty); | 596 | ctx.type_for.insert(LocalSyntaxPtr::new(pat.syntax()), ty); |
587 | } else { | 597 | } else { |
588 | // TODO self param | 598 | // TODO self param |