diff options
Diffstat (limited to 'crates/ra_hir_ty/src/infer.rs')
-rw-r--r-- | crates/ra_hir_ty/src/infer.rs | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs index af42854cc..98ba05fc2 100644 --- a/crates/ra_hir_ty/src/infer.rs +++ b/crates/ra_hir_ty/src/infer.rs | |||
@@ -32,6 +32,7 @@ use hir_def::{ | |||
32 | use hir_expand::{diagnostics::DiagnosticSink, name::name}; | 32 | use hir_expand::{diagnostics::DiagnosticSink, name::name}; |
33 | use ra_arena::map::ArenaMap; | 33 | use ra_arena::map::ArenaMap; |
34 | use ra_prof::profile; | 34 | use ra_prof::profile; |
35 | use test_utils::tested_by; | ||
35 | 36 | ||
36 | use super::{ | 37 | use super::{ |
37 | primitive::{FloatTy, IntTy}, | 38 | primitive::{FloatTy, IntTy}, |
@@ -274,6 +275,29 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
274 | self.normalize_associated_types_in(ty) | 275 | self.normalize_associated_types_in(ty) |
275 | } | 276 | } |
276 | 277 | ||
278 | /// Replaces `impl Trait` in `ty` by type variables and obligations for | ||
279 | /// those variables. This is done for function arguments when calling a | ||
280 | /// function, and for return types when inside the function body, i.e. in | ||
281 | /// the cases where the `impl Trait` is 'transparent'. In other cases, `impl | ||
282 | /// Trait` is represented by `Ty::Opaque`. | ||
283 | fn insert_vars_for_impl_trait(&mut self, ty: Ty) -> Ty { | ||
284 | ty.fold(&mut |ty| match ty { | ||
285 | Ty::Opaque(preds) => { | ||
286 | tested_by!(insert_vars_for_impl_trait); | ||
287 | let var = self.table.new_type_var(); | ||
288 | let var_subst = Substs::builder(1).push(var.clone()).build(); | ||
289 | self.obligations.extend( | ||
290 | preds | ||
291 | .iter() | ||
292 | .map(|pred| pred.clone().subst_bound_vars(&var_subst)) | ||
293 | .filter_map(Obligation::from_predicate), | ||
294 | ); | ||
295 | var | ||
296 | } | ||
297 | _ => ty, | ||
298 | }) | ||
299 | } | ||
300 | |||
277 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. | 301 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. |
278 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { | 302 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { |
279 | match ty { | 303 | match ty { |
@@ -414,7 +438,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
414 | 438 | ||
415 | self.infer_pat(*pat, &ty, BindingMode::default()); | 439 | self.infer_pat(*pat, &ty, BindingMode::default()); |
416 | } | 440 | } |
417 | self.return_ty = self.make_ty(&data.ret_type); | 441 | let return_ty = self.make_ty(&data.ret_type); |
442 | self.return_ty = self.insert_vars_for_impl_trait(return_ty); | ||
418 | } | 443 | } |
419 | 444 | ||
420 | fn infer_body(&mut self) { | 445 | fn infer_body(&mut self) { |