diff options
Diffstat (limited to 'crates/ra_hir_ty/src/infer')
-rw-r--r-- | crates/ra_hir_ty/src/infer/coerce.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs | 35 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/path.rs | 8 |
3 files changed, 33 insertions, 14 deletions
diff --git a/crates/ra_hir_ty/src/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs index 0f4dac45e..83c0c2c3f 100644 --- a/crates/ra_hir_ty/src/infer/coerce.rs +++ b/crates/ra_hir_ty/src/infer/coerce.rs | |||
@@ -134,6 +134,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
134 | } | 134 | } |
135 | } | 135 | } |
136 | 136 | ||
137 | (ty_app!(TypeCtor::Closure { .. }, params), ty_app!(TypeCtor::FnPtr { .. })) => { | ||
138 | from_ty = params[0].clone(); | ||
139 | } | ||
140 | |||
137 | _ => {} | 141 | _ => {} |
138 | } | 142 | } |
139 | 143 | ||
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index 924ad3e81..3af05394c 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs | |||
@@ -8,7 +8,7 @@ use hir_def::{ | |||
8 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, | 8 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, |
9 | path::{GenericArg, GenericArgs}, | 9 | path::{GenericArg, GenericArgs}, |
10 | resolver::resolver_for_expr, | 10 | resolver::resolver_for_expr, |
11 | AdtId, ContainerId, Lookup, StructFieldId, | 11 | AdtId, AssocContainerId, Lookup, StructFieldId, |
12 | }; | 12 | }; |
13 | use hir_expand::name::{name, Name}; | 13 | use hir_expand::name::{name, Name}; |
14 | use ra_syntax::ast::RangeOp; | 14 | use ra_syntax::ast::RangeOp; |
@@ -41,7 +41,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
41 | 41 | ||
42 | /// Infer type of expression with possibly implicit coerce to the expected type. | 42 | /// Infer type of expression with possibly implicit coerce to the expected type. |
43 | /// Return the type after possible coercion. | 43 | /// Return the type after possible coercion. |
44 | fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty { | 44 | pub(super) fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty { |
45 | let ty = self.infer_expr_inner(expr, &expected); | 45 | let ty = self.infer_expr_inner(expr, &expected); |
46 | let ty = if !self.coerce(&ty, &expected.ty) { | 46 | let ty = if !self.coerce(&ty, &expected.ty) { |
47 | self.result | 47 | self.result |
@@ -102,7 +102,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
102 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 102 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
103 | Ty::unit() | 103 | Ty::unit() |
104 | } | 104 | } |
105 | Expr::Lambda { body, args, arg_types } => { | 105 | Expr::Lambda { body, args, ret_type, arg_types } => { |
106 | assert_eq!(args.len(), arg_types.len()); | 106 | assert_eq!(args.len(), arg_types.len()); |
107 | 107 | ||
108 | let mut sig_tys = Vec::new(); | 108 | let mut sig_tys = Vec::new(); |
@@ -118,7 +118,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
118 | } | 118 | } |
119 | 119 | ||
120 | // add return type | 120 | // add return type |
121 | let ret_ty = self.table.new_type_var(); | 121 | let ret_ty = match ret_type { |
122 | Some(type_ref) => self.make_ty(type_ref), | ||
123 | None => self.table.new_type_var(), | ||
124 | }; | ||
122 | sig_tys.push(ret_ty.clone()); | 125 | sig_tys.push(ret_ty.clone()); |
123 | let sig_ty = Ty::apply( | 126 | let sig_ty = Ty::apply( |
124 | TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 }, | 127 | TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 }, |
@@ -134,7 +137,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
134 | // infer the body. | 137 | // infer the body. |
135 | self.coerce(&closure_ty, &expected.ty); | 138 | self.coerce(&closure_ty, &expected.ty); |
136 | 139 | ||
137 | self.infer_expr(*body, &Expectation::has_type(ret_ty)); | 140 | let prev_ret_ty = std::mem::replace(&mut self.return_ty, ret_ty.clone()); |
141 | |||
142 | self.infer_expr_coerce(*body, &Expectation::has_type(ret_ty)); | ||
143 | |||
144 | self.return_ty = prev_ret_ty; | ||
145 | |||
138 | closure_ty | 146 | closure_ty |
139 | } | 147 | } |
140 | Expr::Call { callee, args } => { | 148 | Expr::Call { callee, args } => { |
@@ -192,6 +200,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
192 | Expr::Return { expr } => { | 200 | Expr::Return { expr } => { |
193 | if let Some(expr) = expr { | 201 | if let Some(expr) = expr { |
194 | self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone())); | 202 | self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone())); |
203 | } else { | ||
204 | let unit = Ty::unit(); | ||
205 | self.coerce(&unit, &self.return_ty.clone()); | ||
195 | } | 206 | } |
196 | Ty::simple(TypeCtor::Never) | 207 | Ty::simple(TypeCtor::Never) |
197 | } | 208 | } |
@@ -422,10 +433,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
422 | } | 433 | } |
423 | } | 434 | } |
424 | Expr::Index { base, index } => { | 435 | Expr::Index { base, index } => { |
425 | let _base_ty = self.infer_expr_inner(*base, &Expectation::none()); | 436 | let base_ty = self.infer_expr_inner(*base, &Expectation::none()); |
426 | let _index_ty = self.infer_expr(*index, &Expectation::none()); | 437 | let index_ty = self.infer_expr(*index, &Expectation::none()); |
427 | // FIXME: use `std::ops::Index::Output` to figure out the real return type | 438 | |
428 | Ty::Unknown | 439 | self.resolve_associated_type_with_params( |
440 | base_ty, | ||
441 | self.resolve_ops_index_output(), | ||
442 | &[index_ty], | ||
443 | ) | ||
429 | } | 444 | } |
430 | Expr::Tuple { exprs } => { | 445 | Expr::Tuple { exprs } => { |
431 | let mut tys = match &expected.ty { | 446 | let mut tys = match &expected.ty { |
@@ -672,7 +687,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
672 | // add obligation for trait implementation, if this is a trait method | 687 | // add obligation for trait implementation, if this is a trait method |
673 | match def { | 688 | match def { |
674 | CallableDef::FunctionId(f) => { | 689 | CallableDef::FunctionId(f) => { |
675 | if let ContainerId::TraitId(trait_) = f.lookup(self.db).container { | 690 | if let AssocContainerId::TraitId(trait_) = f.lookup(self.db).container { |
676 | // construct a TraitDef | 691 | // construct a TraitDef |
677 | let substs = | 692 | let substs = |
678 | a_ty.parameters.prefix(generics(self.db, trait_.into()).len()); | 693 | a_ty.parameters.prefix(generics(self.db, trait_.into()).len()); |
diff --git a/crates/ra_hir_ty/src/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs index 402a89386..ffd358367 100644 --- a/crates/ra_hir_ty/src/infer/path.rs +++ b/crates/ra_hir_ty/src/infer/path.rs | |||
@@ -5,7 +5,7 @@ use std::iter; | |||
5 | use hir_def::{ | 5 | use hir_def::{ |
6 | path::{Path, PathSegment}, | 6 | path::{Path, PathSegment}, |
7 | resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs}, | 7 | resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs}, |
8 | AssocItemId, ContainerId, Lookup, | 8 | AssocContainerId, AssocItemId, Lookup, |
9 | }; | 9 | }; |
10 | use hir_expand::name::Name; | 10 | use hir_expand::name::Name; |
11 | 11 | ||
@@ -209,7 +209,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
209 | AssocItemId::TypeAliasId(_) => unreachable!(), | 209 | AssocItemId::TypeAliasId(_) => unreachable!(), |
210 | }; | 210 | }; |
211 | let substs = match container { | 211 | let substs = match container { |
212 | ContainerId::ImplId(impl_id) => { | 212 | AssocContainerId::ImplId(impl_id) => { |
213 | let impl_substs = Substs::build_for_def(self.db, impl_id) | 213 | let impl_substs = Substs::build_for_def(self.db, impl_id) |
214 | .fill(iter::repeat_with(|| self.table.new_type_var())) | 214 | .fill(iter::repeat_with(|| self.table.new_type_var())) |
215 | .build(); | 215 | .build(); |
@@ -221,7 +221,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
221 | self.unify(&impl_self_ty, &ty); | 221 | self.unify(&impl_self_ty, &ty); |
222 | Some(substs) | 222 | Some(substs) |
223 | } | 223 | } |
224 | ContainerId::TraitId(trait_) => { | 224 | AssocContainerId::TraitId(trait_) => { |
225 | // we're picking this method | 225 | // we're picking this method |
226 | let trait_substs = Substs::build_for_def(self.db, trait_) | 226 | let trait_substs = Substs::build_for_def(self.db, trait_) |
227 | .push(ty.clone()) | 227 | .push(ty.clone()) |
@@ -237,7 +237,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
237 | })); | 237 | })); |
238 | Some(substs) | 238 | Some(substs) |
239 | } | 239 | } |
240 | ContainerId::ModuleId(_) => None, | 240 | AssocContainerId::ContainerId(_) => None, |
241 | }; | 241 | }; |
242 | 242 | ||
243 | self.write_assoc_resolution(id, item.into()); | 243 | self.write_assoc_resolution(id, item.into()); |