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.rs66
1 files changed, 28 insertions, 38 deletions
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index e2eda3134..a9d958c8b 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -34,7 +34,6 @@ use hir_expand::{diagnostics::DiagnosticSink, name::name};
34use ra_arena::map::ArenaMap; 34use ra_arena::map::ArenaMap;
35use ra_prof::profile; 35use ra_prof::profile;
36use ra_syntax::SmolStr; 36use ra_syntax::SmolStr;
37use test_utils::tested_by;
38 37
39use super::{ 38use super::{
40 primitive::{FloatTy, IntTy}, 39 primitive::{FloatTy, IntTy},
@@ -42,7 +41,9 @@ use super::{
42 ApplicationTy, GenericPredicate, InEnvironment, ProjectionTy, Substs, TraitEnvironment, 41 ApplicationTy, GenericPredicate, InEnvironment, ProjectionTy, Substs, TraitEnvironment,
43 TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, 42 TraitRef, Ty, TypeCtor, TypeWalk, Uncertain,
44}; 43};
45use crate::{db::HirDatabase, infer::diagnostics::InferenceDiagnostic}; 44use crate::{
45 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
46};
46 47
47pub(crate) use unify::unify; 48pub(crate) use unify::unify;
48 49
@@ -271,38 +272,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
271 self.result.diagnostics.push(diagnostic); 272 self.result.diagnostics.push(diagnostic);
272 } 273 }
273 274
274 fn make_ty(&mut self, type_ref: &TypeRef) -> Ty { 275 fn make_ty_with_mode(
275 let ty = Ty::from_hir( 276 &mut self,
276 self.db, 277 type_ref: &TypeRef,
277 // FIXME use right resolver for block 278 impl_trait_mode: ImplTraitLoweringMode,
278 &self.resolver, 279 ) -> Ty {
279 type_ref, 280 // FIXME use right resolver for block
280 ); 281 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
282 .with_impl_trait_mode(impl_trait_mode);
283 let ty = Ty::from_hir(&ctx, type_ref);
281 let ty = self.insert_type_vars(ty); 284 let ty = self.insert_type_vars(ty);
282 self.normalize_associated_types_in(ty) 285 self.normalize_associated_types_in(ty)
283 } 286 }
284 287
285 /// Replaces `impl Trait` in `ty` by type variables and obligations for 288 fn make_ty(&mut self, type_ref: &TypeRef) -> Ty {
286 /// those variables. This is done for function arguments when calling a 289 self.make_ty_with_mode(type_ref, ImplTraitLoweringMode::Disallowed)
287 /// function, and for return types when inside the function body, i.e. in
288 /// the cases where the `impl Trait` is 'transparent'. In other cases, `impl
289 /// Trait` is represented by `Ty::Opaque`.
290 fn insert_vars_for_impl_trait(&mut self, ty: Ty) -> Ty {
291 ty.fold(&mut |ty| match ty {
292 Ty::Opaque(preds) => {
293 tested_by!(insert_vars_for_impl_trait);
294 let var = self.table.new_type_var();
295 let var_subst = Substs::builder(1).push(var.clone()).build();
296 self.obligations.extend(
297 preds
298 .iter()
299 .map(|pred| pred.clone().subst_bound_vars(&var_subst))
300 .filter_map(Obligation::from_predicate),
301 );
302 var
303 }
304 _ => ty,
305 })
306 } 290 }
307 291
308 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. 292 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it.
@@ -446,19 +430,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
446 None => return (Ty::Unknown, None), 430 None => return (Ty::Unknown, None),
447 }; 431 };
448 let resolver = &self.resolver; 432 let resolver = &self.resolver;
433 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
449 // FIXME: this should resolve assoc items as well, see this example: 434 // FIXME: this should resolve assoc items as well, see this example:
450 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 435 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521
451 match resolver.resolve_path_in_type_ns_fully(self.db, path.mod_path()) { 436 match resolver.resolve_path_in_type_ns_fully(self.db, path.mod_path()) {
452 Some(TypeNs::AdtId(AdtId::StructId(strukt))) => { 437 Some(TypeNs::AdtId(AdtId::StructId(strukt))) => {
453 let substs = Ty::substs_from_path(self.db, resolver, path, strukt.into()); 438 let substs = Ty::substs_from_path(&ctx, path, strukt.into());
454 let ty = self.db.ty(strukt.into()); 439 let ty = self.db.ty(strukt.into());
455 let ty = self.insert_type_vars(ty.apply_substs(substs)); 440 let ty = self.insert_type_vars(ty.subst(&substs));
456 (ty, Some(strukt.into())) 441 (ty, Some(strukt.into()))
457 } 442 }
458 Some(TypeNs::EnumVariantId(var)) => { 443 Some(TypeNs::EnumVariantId(var)) => {
459 let substs = Ty::substs_from_path(self.db, resolver, path, var.into()); 444 let substs = Ty::substs_from_path(&ctx, path, var.into());
460 let ty = self.db.ty(var.parent.into()); 445 let ty = self.db.ty(var.parent.into());
461 let ty = self.insert_type_vars(ty.apply_substs(substs)); 446 let ty = self.insert_type_vars(ty.subst(&substs));
462 (ty, Some(var.into())) 447 (ty, Some(var.into()))
463 } 448 }
464 Some(_) | None => (Ty::Unknown, None), 449 Some(_) | None => (Ty::Unknown, None),
@@ -471,13 +456,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
471 456
472 fn collect_fn(&mut self, data: &FunctionData) { 457 fn collect_fn(&mut self, data: &FunctionData) {
473 let body = Arc::clone(&self.body); // avoid borrow checker problem 458 let body = Arc::clone(&self.body); // avoid borrow checker problem
474 for (type_ref, pat) in data.params.iter().zip(body.params.iter()) { 459 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
475 let ty = self.make_ty(type_ref); 460 .with_impl_trait_mode(ImplTraitLoweringMode::Param);
461 let param_tys =
462 data.params.iter().map(|type_ref| Ty::from_hir(&ctx, type_ref)).collect::<Vec<_>>();
463 for (ty, pat) in param_tys.into_iter().zip(body.params.iter()) {
464 let ty = self.insert_type_vars(ty);
465 let ty = self.normalize_associated_types_in(ty);
476 466
477 self.infer_pat(*pat, &ty, BindingMode::default()); 467 self.infer_pat(*pat, &ty, BindingMode::default());
478 } 468 }
479 let return_ty = self.make_ty(&data.ret_type); 469 let return_ty = self.make_ty_with_mode(&data.ret_type, ImplTraitLoweringMode::Disallowed); // FIXME implement RPIT
480 self.return_ty = self.insert_vars_for_impl_trait(return_ty); 470 self.return_ty = return_ty;
481 } 471 }
482 472
483 fn infer_body(&mut self) { 473 fn infer_body(&mut self) {