aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/infer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/infer.rs')
-rw-r--r--crates/ra_hir_ty/src/infer.rs27
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::{
32use hir_expand::{diagnostics::DiagnosticSink, name::name}; 32use hir_expand::{diagnostics::DiagnosticSink, name::name};
33use ra_arena::map::ArenaMap; 33use ra_arena::map::ArenaMap;
34use ra_prof::profile; 34use ra_prof::profile;
35use test_utils::tested_by;
35 36
36use super::{ 37use 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) {