aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/ty.rs38
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
132impl Ty { 132impl 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.
234pub fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Ty> { 243pub 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