aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-01-25 22:38:33 +0000
committerFlorian Diebold <[email protected]>2020-02-07 17:28:10 +0000
commit16c69374471a0072541c21a5551b4fd97f7e12ba (patch)
tree72564c6b99eb6f1aaf44f740d654b1725daed0c2 /crates
parent93aa166748eef9560df2435391dc3f3b53f8262d (diff)
Lower impl trait to variables, move away from using placeholders where they don't belong
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir_ty/src/db.rs12
-rw-r--r--crates/ra_hir_ty/src/infer.rs18
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs6
-rw-r--r--crates/ra_hir_ty/src/infer/path.rs55
-rw-r--r--crates/ra_hir_ty/src/lib.rs34
-rw-r--r--crates/ra_hir_ty/src/lower.rs263
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs4
-rw-r--r--crates/ra_hir_ty/src/tests/simple.rs2
-rw-r--r--crates/ra_hir_ty/src/utils.rs14
9 files changed, 220 insertions, 188 deletions
diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs
index eb521c7a0..fea122a8b 100644
--- a/crates/ra_hir_ty/src/db.rs
+++ b/crates/ra_hir_ty/src/db.rs
@@ -12,8 +12,8 @@ use ra_prof::profile;
12use crate::{ 12use crate::{
13 method_resolution::CrateImplBlocks, 13 method_resolution::CrateImplBlocks,
14 traits::{chalk, AssocTyValue, Impl}, 14 traits::{chalk, AssocTyValue, Impl},
15 CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, TraitRef, Ty, TyDefId, TypeCtor, 15 CallableDef, PolyFnSig, GenericPredicate, InferenceResult, Substs, TraitRef, Ty, TyDefId, TypeCtor,
16 ValueTyDefId, 16 ValueTyDefId, Binders,
17}; 17};
18 18
19#[salsa::query_group(HirDatabaseStorage)] 19#[salsa::query_group(HirDatabaseStorage)]
@@ -27,14 +27,14 @@ pub trait HirDatabase: DefDatabase {
27 27
28 #[salsa::invoke(crate::lower::ty_query)] 28 #[salsa::invoke(crate::lower::ty_query)]
29 #[salsa::cycle(crate::lower::ty_recover)] 29 #[salsa::cycle(crate::lower::ty_recover)]
30 fn ty(&self, def: TyDefId) -> Ty; 30 fn ty(&self, def: TyDefId) -> Binders<Ty>;
31 31
32 #[salsa::invoke(crate::lower::value_ty_query)] 32 #[salsa::invoke(crate::lower::value_ty_query)]
33 fn value_ty(&self, def: ValueTyDefId) -> Ty; 33 fn value_ty(&self, def: ValueTyDefId) -> Binders<Ty>;
34 34
35 #[salsa::invoke(crate::lower::impl_self_ty_query)] 35 #[salsa::invoke(crate::lower::impl_self_ty_query)]
36 #[salsa::cycle(crate::lower::impl_self_ty_recover)] 36 #[salsa::cycle(crate::lower::impl_self_ty_recover)]
37 fn impl_self_ty(&self, def: ImplId) -> Ty; 37 fn impl_self_ty(&self, def: ImplId) -> Binders<Ty>;
38 38
39 #[salsa::invoke(crate::lower::impl_trait_query)] 39 #[salsa::invoke(crate::lower::impl_trait_query)]
40 fn impl_trait(&self, def: ImplId) -> Option<TraitRef>; 40 fn impl_trait(&self, def: ImplId) -> Option<TraitRef>;
@@ -43,7 +43,7 @@ pub trait HirDatabase: DefDatabase {
43 fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Ty>>; 43 fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Ty>>;
44 44
45 #[salsa::invoke(crate::callable_item_sig)] 45 #[salsa::invoke(crate::callable_item_sig)]
46 fn callable_item_signature(&self, def: CallableDef) -> FnSig; 46 fn callable_item_signature(&self, def: CallableDef) -> PolyFnSig;
47 47
48 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)] 48 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)]
49 #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)] 49 #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)]
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index b4a3e1675..f7ef09f0e 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -279,11 +279,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
279 impl_trait_mode: ImplTraitLoweringMode, 279 impl_trait_mode: ImplTraitLoweringMode,
280 ) -> Ty { 280 ) -> Ty {
281 // FIXME use right resolver for block 281 // FIXME use right resolver for block
282 let ctx = crate::lower::TyLoweringContext { 282 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver).with_impl_trait_mode(impl_trait_mode);
283 db: self.db,
284 resolver: &self.resolver,
285 impl_trait_mode,
286 };
287 let ty = Ty::from_hir(&ctx, type_ref); 283 let ty = Ty::from_hir(&ctx, type_ref);
288 let ty = self.insert_type_vars(ty); 284 let ty = self.insert_type_vars(ty);
289 self.normalize_associated_types_in(ty) 285 self.normalize_associated_types_in(ty)
@@ -457,24 +453,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
457 None => return (Ty::Unknown, None), 453 None => return (Ty::Unknown, None),
458 }; 454 };
459 let resolver = &self.resolver; 455 let resolver = &self.resolver;
460 let ctx = crate::lower::TyLoweringContext { 456 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
461 db: self.db,
462 resolver: &self.resolver,
463 impl_trait_mode: ImplTraitLoweringMode::Disallowed,
464 };
465 // FIXME: this should resolve assoc items as well, see this example: 457 // FIXME: this should resolve assoc items as well, see this example:
466 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 458 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521
467 match resolver.resolve_path_in_type_ns_fully(self.db, path.mod_path()) { 459 match resolver.resolve_path_in_type_ns_fully(self.db, path.mod_path()) {
468 Some(TypeNs::AdtId(AdtId::StructId(strukt))) => { 460 Some(TypeNs::AdtId(AdtId::StructId(strukt))) => {
469 let substs = Ty::substs_from_path(&ctx, path, strukt.into()); 461 let substs = Ty::substs_from_path(&ctx, path, strukt.into());
470 let ty = self.db.ty(strukt.into()); 462 let ty = self.db.ty(strukt.into());
471 let ty = self.insert_type_vars(ty.apply_substs(substs)); 463 let ty = self.insert_type_vars(ty.subst(&substs));
472 (ty, Some(strukt.into())) 464 (ty, Some(strukt.into()))
473 } 465 }
474 Some(TypeNs::EnumVariantId(var)) => { 466 Some(TypeNs::EnumVariantId(var)) => {
475 let substs = Ty::substs_from_path(&ctx, path, var.into()); 467 let substs = Ty::substs_from_path(&ctx, path, var.into());
476 let ty = self.db.ty(var.parent.into()); 468 let ty = self.db.ty(var.parent.into());
477 let ty = self.insert_type_vars(ty.apply_substs(substs)); 469 let ty = self.insert_type_vars(ty.subst(&substs));
478 (ty, Some(var.into())) 470 (ty, Some(var.into()))
479 } 471 }
480 Some(_) | None => (Ty::Unknown, None), 472 Some(_) | None => (Ty::Unknown, None),
@@ -492,7 +484,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
492 484
493 self.infer_pat(*pat, &ty, BindingMode::default()); 485 self.infer_pat(*pat, &ty, BindingMode::default());
494 } 486 }
495 let return_ty = self.make_ty_with_mode(&data.ret_type, ImplTraitLoweringMode::Placeholder); 487 let return_ty = self.make_ty_with_mode(&data.ret_type, ImplTraitLoweringMode::Variable);
496 self.return_ty = self.insert_vars_for_impl_trait(return_ty); 488 self.return_ty = self.insert_vars_for_impl_trait(return_ty);
497 } 489 }
498 490
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index 97cb20cea..e1fdb356d 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -20,7 +20,7 @@ use crate::{
20 traits::InEnvironment, 20 traits::InEnvironment,
21 utils::{generics, variant_data, Generics}, 21 utils::{generics, variant_data, Generics},
22 ApplicationTy, CallableDef, InferTy, IntTy, Mutability, Obligation, Substs, TraitRef, Ty, 22 ApplicationTy, CallableDef, InferTy, IntTy, Mutability, Obligation, Substs, TraitRef, Ty,
23 TypeCtor, TypeWalk, Uncertain, 23 TypeCtor, TypeWalk, Uncertain, Binders,
24}; 24};
25 25
26use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; 26use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch};
@@ -588,10 +588,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
588 self.write_method_resolution(tgt_expr, func); 588 self.write_method_resolution(tgt_expr, func);
589 (ty, self.db.value_ty(func.into()), Some(generics(self.db, func.into()))) 589 (ty, self.db.value_ty(func.into()), Some(generics(self.db, func.into())))
590 } 590 }
591 None => (receiver_ty, Ty::Unknown, None), 591 None => (receiver_ty, Binders::new(0, Ty::Unknown), None),
592 }; 592 };
593 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); 593 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty);
594 let method_ty = method_ty.apply_substs(substs); 594 let method_ty = method_ty.subst(&substs);
595 let method_ty = self.insert_type_vars(method_ty); 595 let method_ty = self.insert_type_vars(method_ty);
596 self.register_obligations_for_call(&method_ty); 596 self.register_obligations_for_call(&method_ty);
597 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) { 597 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) {
diff --git a/crates/ra_hir_ty/src/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs
index 02fc99288..39aa346eb 100644
--- a/crates/ra_hir_ty/src/infer/path.rs
+++ b/crates/ra_hir_ty/src/infer/path.rs
@@ -10,8 +10,8 @@ use hir_def::{
10use hir_expand::name::Name; 10use hir_expand::name::Name;
11 11
12use crate::{ 12use crate::{
13 db::HirDatabase, lower::ImplTraitLoweringMode, method_resolution, Substs, Ty, TypeWalk, 13 db::HirDatabase, method_resolution, Substs, Ty,
14 ValueTyDefId, 14 ValueTyDefId
15}; 15};
16 16
17use super::{ExprOrPatId, InferenceContext, TraitRef}; 17use super::{ExprOrPatId, InferenceContext, TraitRef};
@@ -42,11 +42,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
42 } 42 }
43 let ty = self.make_ty(type_ref); 43 let ty = self.make_ty(type_ref);
44 let remaining_segments_for_ty = path.segments().take(path.segments().len() - 1); 44 let remaining_segments_for_ty = path.segments().take(path.segments().len() - 1);
45 let ctx = crate::lower::TyLoweringContext { 45 let ctx = crate::lower::TyLoweringContext::new(self.db, &resolver);
46 db: self.db,
47 resolver: &resolver,
48 impl_trait_mode: ImplTraitLoweringMode::Disallowed,
49 };
50 let ty = Ty::from_type_relative_path(&ctx, ty, remaining_segments_for_ty); 46 let ty = Ty::from_type_relative_path(&ctx, ty, remaining_segments_for_ty);
51 self.resolve_ty_assoc_item( 47 self.resolve_ty_assoc_item(
52 ty, 48 ty,
@@ -77,17 +73,16 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
77 ValueNs::EnumVariantId(it) => it.into(), 73 ValueNs::EnumVariantId(it) => it.into(),
78 }; 74 };
79 75
80 let mut ty = self.db.value_ty(typable); 76 let ty = self.db.value_ty(typable);
81 if let Some(self_subst) = self_subst { 77 // self_subst is just for the parent
82 ty = ty.subst(&self_subst); 78 let parent_substs = self_subst.unwrap_or_else(Substs::empty);
83 } 79 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
84 let ctx = crate::lower::TyLoweringContext {
85 db: self.db,
86 resolver: &self.resolver,
87 impl_trait_mode: ImplTraitLoweringMode::Disallowed,
88 };
89 let substs = Ty::substs_from_path(&ctx, path, typable); 80 let substs = Ty::substs_from_path(&ctx, path, typable);
90 let ty = ty.subst(&substs); 81 let full_substs = Substs::builder(substs.len())
82 .use_parent_substs(&parent_substs)
83 .fill(substs.0[parent_substs.len()..].iter().cloned())
84 .build();
85 let ty = ty.subst(&full_substs);
91 Some(ty) 86 Some(ty)
92 } 87 }
93 88
@@ -111,11 +106,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
111 (TypeNs::TraitId(trait_), true) => { 106 (TypeNs::TraitId(trait_), true) => {
112 let segment = 107 let segment =
113 remaining_segments.last().expect("there should be at least one segment here"); 108 remaining_segments.last().expect("there should be at least one segment here");
114 let ctx = crate::lower::TyLoweringContext { 109 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
115 db: self.db,
116 resolver: &self.resolver,
117 impl_trait_mode: ImplTraitLoweringMode::Disallowed,
118 };
119 let trait_ref = 110 let trait_ref =
120 TraitRef::from_resolved_path(&ctx, trait_.into(), resolved_segment, None); 111 TraitRef::from_resolved_path(&ctx, trait_.into(), resolved_segment, None);
121 self.resolve_trait_assoc_item(trait_ref, segment, id) 112 self.resolve_trait_assoc_item(trait_ref, segment, id)
@@ -127,11 +118,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
127 // as Iterator>::Item::default`) 118 // as Iterator>::Item::default`)
128 let remaining_segments_for_ty = 119 let remaining_segments_for_ty =
129 remaining_segments.take(remaining_segments.len() - 1); 120 remaining_segments.take(remaining_segments.len() - 1);
130 let ctx = crate::lower::TyLoweringContext { 121 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
131 db: self.db,
132 resolver: &self.resolver,
133 impl_trait_mode: ImplTraitLoweringMode::Disallowed,
134 };
135 let ty = Ty::from_partly_resolved_hir_path( 122 let ty = Ty::from_partly_resolved_hir_path(
136 &ctx, 123 &ctx,
137 def, 124 def,
@@ -235,12 +222,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
235 .fill(iter::repeat_with(|| self.table.new_type_var())) 222 .fill(iter::repeat_with(|| self.table.new_type_var()))
236 .build(); 223 .build();
237 let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs); 224 let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs);
238 let substs = Substs::build_for_def(self.db, item)
239 .use_parent_substs(&impl_substs)
240 .fill_with_params()
241 .build();
242 self.unify(&impl_self_ty, &ty); 225 self.unify(&impl_self_ty, &ty);
243 Some(substs) 226 Some(impl_substs)
244 } 227 }
245 AssocContainerId::TraitId(trait_) => { 228 AssocContainerId::TraitId(trait_) => {
246 // we're picking this method 229 // we're picking this method
@@ -248,15 +231,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
248 .push(ty.clone()) 231 .push(ty.clone())
249 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 232 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
250 .build(); 233 .build();
251 let substs = Substs::build_for_def(self.db, item)
252 .use_parent_substs(&trait_substs)
253 .fill_with_params()
254 .build();
255 self.obligations.push(super::Obligation::Trait(TraitRef { 234 self.obligations.push(super::Obligation::Trait(TraitRef {
256 trait_, 235 trait_,
257 substs: trait_substs, 236 substs: trait_substs.clone(),
258 })); 237 }));
259 Some(substs) 238 Some(trait_substs)
260 } 239 }
261 AssocContainerId::ContainerId(_) => None, 240 AssocContainerId::ContainerId(_) => None,
262 }; 241 };
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index cb7a60352..79084bb3e 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -453,6 +453,30 @@ impl Deref for Substs {
453 } 453 }
454} 454}
455 455
456#[derive(Copy, Clone, PartialEq, Eq, Debug)]
457pub struct Binders<T> {
458 pub num_binders: usize,
459 pub value: T,
460}
461
462impl<T> Binders<T> {
463 pub fn new(num_binders: usize, value: T) -> Self { Self { num_binders, value } }
464}
465
466impl<T: TypeWalk> Binders<T> {
467 /// Substitutes all variables.
468 pub fn subst(self, subst: &Substs) -> T {
469 assert_eq!(subst.len(), self.num_binders);
470 self.value.subst_bound_vars(subst)
471 }
472
473 /// Substitutes just a prefix of the variables (shifting the rest).
474 pub fn subst_prefix(self, subst: &Substs) -> Binders<T> {
475 assert!(subst.len() < self.num_binders);
476 Binders::new(self.num_binders - subst.len(), self.value.subst_bound_vars(subst))
477 }
478}
479
456/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. 480/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait.
457/// Name to be bikeshedded: TraitBound? TraitImplements? 481/// Name to be bikeshedded: TraitBound? TraitImplements?
458#[derive(Clone, PartialEq, Eq, Debug, Hash)] 482#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -553,6 +577,9 @@ pub struct FnSig {
553 params_and_return: Arc<[Ty]>, 577 params_and_return: Arc<[Ty]>,
554} 578}
555 579
580/// A polymorphic function signature.
581pub type PolyFnSig = Binders<FnSig>;
582
556impl FnSig { 583impl FnSig {
557 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty) -> FnSig { 584 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty) -> FnSig {
558 params.push(ret); 585 params.push(ret);
@@ -757,6 +784,9 @@ pub trait TypeWalk {
757 &mut Ty::Bound(idx) => { 784 &mut Ty::Bound(idx) => {
758 if idx as usize >= binders && (idx as usize - binders) < substs.len() { 785 if idx as usize >= binders && (idx as usize - binders) < substs.len() {
759 *ty = substs.0[idx as usize - binders].clone(); 786 *ty = substs.0[idx as usize - binders].clone();
787 } else if idx as usize >= binders + substs.len() {
788 // shift free binders
789 *ty = Ty::Bound(idx - substs.len() as u32);
760 } 790 }
761 } 791 }
762 _ => {} 792 _ => {}
@@ -903,8 +933,8 @@ impl HirDisplay for ApplicationTy {
903 write!(f, ">")?; 933 write!(f, ">")?;
904 } 934 }
905 write!(f, "(")?; 935 write!(f, "(")?;
906 f.write_joined(sig.params(), ", ")?; 936 f.write_joined(sig.value.params(), ", ")?;
907 write!(f, ") -> {}", sig.ret().display(f.db))?; 937 write!(f, ") -> {}", sig.value.ret().display(f.db))?;
908 } 938 }
909 TypeCtor::Adt(def_id) => { 939 TypeCtor::Adt(def_id) => {
910 let name = match def_id { 940 let name = match def_id {
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs
index 6f7681475..006101f2f 100644
--- a/crates/ra_hir_ty/src/lower.rs
+++ b/crates/ra_hir_ty/src/lower.rs
@@ -28,32 +28,62 @@ use crate::{
28 variant_data, 28 variant_data,
29 }, 29 },
30 FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, 30 FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef,
31 Ty, TypeCtor, TypeWalk, 31 Ty, TypeCtor, PolyFnSig, Binders,
32}; 32};
33 33
34#[derive(Clone, Debug)] 34#[derive(Debug)]
35pub struct TyLoweringContext<'a, DB: HirDatabase> { 35pub struct TyLoweringContext<'a, DB: HirDatabase> {
36 pub db: &'a DB, 36 pub db: &'a DB,
37 pub resolver: &'a Resolver, 37 pub resolver: &'a Resolver,
38 /// Note: Conceptually, it's thinkable that we could be in a location where
39 /// some type params are quantified universally (and should be represented
40 /// as placeholders), and others are quantified existentially (and should be
41 /// converted to variables). I think in practice, this isn't possible
42 /// currently, so this should be fine for now.
43 pub type_param_mode: TypeParamLoweringMode,
38 pub impl_trait_mode: ImplTraitLoweringMode, 44 pub impl_trait_mode: ImplTraitLoweringMode,
45 pub impl_trait_counter: std::cell::Cell<u16>,
39} 46}
40 47
41#[derive(Clone, Debug)] 48impl<'a, DB: HirDatabase> TyLoweringContext<'a, DB> {
49 pub fn new(db: &'a DB, resolver: &'a Resolver) -> Self {
50 let impl_trait_counter = std::cell::Cell::new(0);
51 let impl_trait_mode = ImplTraitLoweringMode::Disallowed;
52 let type_param_mode = TypeParamLoweringMode::Placeholder;
53 Self { db, resolver, impl_trait_mode, impl_trait_counter, type_param_mode }
54 }
55
56 pub fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self {
57 Self { impl_trait_mode, ..self }
58 }
59
60 pub fn with_type_param_mode(self, type_param_mode: TypeParamLoweringMode) -> Self {
61 Self { type_param_mode, ..self }
62 }
63}
64
65#[derive(Copy, Clone, Debug)]
42pub enum ImplTraitLoweringMode { 66pub enum ImplTraitLoweringMode {
43 /// `impl Trait` gets lowered into an opaque type that doesn't unify with 67 /// `impl Trait` gets lowered into an opaque type that doesn't unify with
44 /// anything except itself. This is used in places where values flow 'out', 68 /// anything except itself. This is used in places where values flow 'out',
45 /// i.e. for arguments of the function we're currently checking, and return 69 /// i.e. for arguments of the function we're currently checking, and return
46 /// types of functions we're calling. 70 /// types of functions we're calling.
47 Opaque, 71 Opaque,
48 /// `impl Trait` gets lowered into a placeholder that can unify with some 72 /// `impl Trait` gets lowered into a variable that can unify with some
49 /// type. This is used in places where values flow 'in', i.e. for arguments 73 /// type. This is used in places where values flow 'in', i.e. for arguments
50 /// of functions we're calling, and the return type of the function we're 74 /// of functions we're calling, and the return type of the function we're
51 /// currently checking. 75 /// currently checking.
52 Placeholder, 76 Variable,
53 /// `impl Trait` is disallowed and will be an error. 77 /// `impl Trait` is disallowed and will be an error.
54 Disallowed, 78 Disallowed,
55} 79}
56 80
81#[derive(Copy, Clone, Debug)]
82pub enum TypeParamLoweringMode {
83 Placeholder,
84 Variable,
85}
86
57impl Ty { 87impl Ty {
58 pub fn from_hir(ctx: &TyLoweringContext<'_, impl HirDatabase>, type_ref: &TypeRef) -> Self { 88 pub fn from_hir(ctx: &TyLoweringContext<'_, impl HirDatabase>, type_ref: &TypeRef) -> Self {
59 match type_ref { 89 match type_ref {
@@ -101,17 +131,25 @@ impl Ty {
101 let self_ty = Ty::Bound(0); 131 let self_ty = Ty::Bound(0);
102 let predicates = bounds 132 let predicates = bounds
103 .iter() 133 .iter()
104 .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone())) 134 .flat_map(|b| {
135 GenericPredicate::from_type_bound(ctx, b, self_ty.clone())
136 })
105 .collect(); 137 .collect();
106 Ty::Opaque(predicates) 138 Ty::Opaque(predicates)
107 }, 139 }
108 ImplTraitLoweringMode::Placeholder => { 140 ImplTraitLoweringMode::Variable => {
109 todo!() 141 let idx = ctx.impl_trait_counter.get();
110 }, 142 ctx.impl_trait_counter.set(idx + 1);
143 let generics =
144 generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope"));
145 let (self_params, list_params, impl_trait_params) = generics.provenance_split();
146 assert!((idx as usize) < impl_trait_params);
147 Ty::Bound(idx as u32 + self_params as u32 + list_params as u32)
148 }
111 ImplTraitLoweringMode::Disallowed => { 149 ImplTraitLoweringMode::Disallowed => {
112 // FIXME: report error 150 // FIXME: report error
113 Ty::Unknown 151 Ty::Unknown
114 }, 152 }
115 } 153 }
116 } 154 }
117 TypeRef::Error => Ty::Unknown, 155 TypeRef::Error => Ty::Unknown,
@@ -205,12 +243,31 @@ impl Ty {
205 let generics = 243 let generics =
206 generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope")); 244 generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope"));
207 let idx = generics.param_idx(param_id); 245 let idx = generics.param_idx(param_id);
208 // FIXME: maybe return name in resolution? 246 match ctx.type_param_mode {
209 let name = generics.param_name(param_id); 247 TypeParamLoweringMode::Placeholder => {
210 Ty::Param { idx, name } 248 // FIXME: maybe return name in resolution?
249 let name = generics.param_name(param_id);
250 Ty::Param { idx, name }
251 },
252 TypeParamLoweringMode::Variable => Ty::Bound(idx),
253 }
211 } 254 }
212 TypeNs::SelfType(impl_id) => ctx.db.impl_self_ty(impl_id).clone(), 255 TypeNs::SelfType(impl_id) => {
213 TypeNs::AdtSelfType(adt) => ctx.db.ty(adt.into()), 256 let generics = generics(ctx.db, impl_id.into());
257 let substs = match ctx.type_param_mode {
258 TypeParamLoweringMode::Placeholder => Substs::identity(&generics),
259 TypeParamLoweringMode::Variable => Substs::bound_vars(&generics),
260 };
261 ctx.db.impl_self_ty(impl_id).subst(&substs)
262 },
263 TypeNs::AdtSelfType(adt) => {
264 let generics = generics(ctx.db, adt.into());
265 let substs = match ctx.type_param_mode {
266 TypeParamLoweringMode::Placeholder => Substs::identity(&generics),
267 TypeParamLoweringMode::Variable => Substs::bound_vars(&generics),
268 };
269 ctx.db.ty(adt.into()).subst(&substs)
270 },
214 271
215 TypeNs::AdtId(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()), 272 TypeNs::AdtId(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()),
216 TypeNs::BuiltinType(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()), 273 TypeNs::BuiltinType(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()),
@@ -341,7 +398,7 @@ pub(super) fn substs_from_path_segment(
341 // Self type as an implicit first type parameter, but it can't be 398 // Self type as an implicit first type parameter, but it can't be
342 // actually provided in the type arguments 399 // actually provided in the type arguments
343 // (well, actually sometimes it can, in the form of type-relative paths: `<Foo as Default>::default()`) 400 // (well, actually sometimes it can, in the form of type-relative paths: `<Foo as Default>::default()`)
344 // TODO handle this using type param provenance 401 // TODO handle this using type param provenance (if there's a self param, and not one provided, add unknown)
345 substs.push(Ty::Unknown); 402 substs.push(Ty::Unknown);
346 } 403 }
347 if let Some(generic_args) = &segment.args_and_bindings { 404 if let Some(generic_args) = &segment.args_and_bindings {
@@ -493,7 +550,7 @@ fn assoc_type_bindings_from_type_bound<'a>(
493} 550}
494 551
495/// Build the signature of a callable item (function, struct or enum variant). 552/// Build the signature of a callable item (function, struct or enum variant).
496pub fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { 553pub fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> PolyFnSig {
497 match def { 554 match def {
498 CallableDef::FunctionId(f) => fn_sig_for_fn(db, f), 555 CallableDef::FunctionId(f) => fn_sig_for_fn(db, f),
499 CallableDef::StructId(s) => fn_sig_for_struct_constructor(db, s), 556 CallableDef::StructId(s) => fn_sig_for_struct_constructor(db, s),
@@ -513,11 +570,7 @@ pub(crate) fn field_types_query(
513 VariantId::EnumVariantId(it) => it.parent.resolver(db), 570 VariantId::EnumVariantId(it) => it.parent.resolver(db),
514 }; 571 };
515 let mut res = ArenaMap::default(); 572 let mut res = ArenaMap::default();
516 let ctx = TyLoweringContext { 573 let ctx = TyLoweringContext::new(db, &resolver);
517 db,
518 resolver: &resolver,
519 impl_trait_mode: ImplTraitLoweringMode::Disallowed,
520 };
521 for (field_id, field_data) in var_data.fields().iter() { 574 for (field_id, field_data) in var_data.fields().iter() {
522 res.insert(field_id, Ty::from_hir(&ctx, &field_data.type_ref)) 575 res.insert(field_id, Ty::from_hir(&ctx, &field_data.type_ref))
523 } 576 }
@@ -538,11 +591,7 @@ pub(crate) fn generic_predicates_for_param_query(
538 param_idx: u32, 591 param_idx: u32,
539) -> Arc<[GenericPredicate]> { 592) -> Arc<[GenericPredicate]> {
540 let resolver = def.resolver(db); 593 let resolver = def.resolver(db);
541 let ctx = TyLoweringContext { 594 let ctx = TyLoweringContext::new(db, &resolver);
542 db,
543 resolver: &resolver,
544 impl_trait_mode: ImplTraitLoweringMode::Disallowed,
545 };
546 resolver 595 resolver
547 .where_predicates_in_scope() 596 .where_predicates_in_scope()
548 // we have to filter out all other predicates *first*, before attempting to lower them 597 // we have to filter out all other predicates *first*, before attempting to lower them
@@ -562,8 +611,7 @@ pub(crate) fn generic_predicates_for_param_recover(
562 611
563impl TraitEnvironment { 612impl TraitEnvironment {
564 pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { 613 pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> {
565 let ctx = 614 let ctx = TyLoweringContext::new(db, &resolver);
566 TyLoweringContext { db, resolver, impl_trait_mode: ImplTraitLoweringMode::Disallowed };
567 let predicates = resolver 615 let predicates = resolver
568 .where_predicates_in_scope() 616 .where_predicates_in_scope()
569 .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) 617 .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred))
@@ -579,11 +627,7 @@ pub(crate) fn generic_predicates_query(
579 def: GenericDefId, 627 def: GenericDefId,
580) -> Arc<[GenericPredicate]> { 628) -> Arc<[GenericPredicate]> {
581 let resolver = def.resolver(db); 629 let resolver = def.resolver(db);
582 let ctx = TyLoweringContext { 630 let ctx = TyLoweringContext::new(db, &resolver);
583 db,
584 resolver: &resolver,
585 impl_trait_mode: ImplTraitLoweringMode::Disallowed,
586 };
587 resolver 631 resolver
588 .where_predicates_in_scope() 632 .where_predicates_in_scope()
589 .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) 633 .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred))
@@ -593,11 +637,7 @@ pub(crate) fn generic_predicates_query(
593/// Resolve the default type params from generics 637/// Resolve the default type params from generics
594pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs { 638pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs {
595 let resolver = def.resolver(db); 639 let resolver = def.resolver(db);
596 let ctx = TyLoweringContext { 640 let ctx = TyLoweringContext::new(db, &resolver);
597 db,
598 resolver: &resolver,
599 impl_trait_mode: ImplTraitLoweringMode::Disallowed,
600 };
601 let generic_params = generics(db, def.into()); 641 let generic_params = generics(db, def.into());
602 642
603 let defaults = generic_params 643 let defaults = generic_params
@@ -608,56 +648,46 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -
608 Substs(defaults) 648 Substs(defaults)
609} 649}
610 650
611fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig { 651fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> PolyFnSig {
612 let data = db.function_data(def); 652 let data = db.function_data(def);
613 let resolver = def.resolver(db); 653 let resolver = def.resolver(db);
614 let ctx_params = TyLoweringContext { 654 let ctx_params = TyLoweringContext::new(db, &resolver)
615 db, 655 .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
616 resolver: &resolver, 656 .with_type_param_mode(TypeParamLoweringMode::Variable);
617 impl_trait_mode: ImplTraitLoweringMode::Placeholder,
618 };
619 let params = data.params.iter().map(|tr| Ty::from_hir(&ctx_params, tr)).collect::<Vec<_>>(); 657 let params = data.params.iter().map(|tr| Ty::from_hir(&ctx_params, tr)).collect::<Vec<_>>();
620 let ctx_ret = TyLoweringContext { 658 let ctx_ret = ctx_params.with_impl_trait_mode(ImplTraitLoweringMode::Opaque);
621 db,
622 resolver: &resolver,
623 impl_trait_mode: ImplTraitLoweringMode::Opaque,
624 };
625 let ret = Ty::from_hir(&ctx_ret, &data.ret_type); 659 let ret = Ty::from_hir(&ctx_ret, &data.ret_type);
626 FnSig::from_params_and_return(params, ret) 660 let generics = generics(db, def.into());
661 let num_binders = generics.len();
662 Binders::new(num_binders, FnSig::from_params_and_return(params, ret))
627} 663}
628 664
629/// Build the declared type of a function. This should not need to look at the 665/// Build the declared type of a function. This should not need to look at the
630/// function body. 666/// function body.
631fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Ty { 667fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Binders<Ty> {
632 let generics = generics(db, def.into()); 668 let generics = generics(db, def.into());
633 let substs = Substs::identity(&generics); 669 let substs = Substs::bound_vars(&generics);
634 Ty::apply(TypeCtor::FnDef(def.into()), substs) 670 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs))
635} 671}
636 672
637/// Build the declared type of a const. 673/// Build the declared type of a const.
638fn type_for_const(db: &impl HirDatabase, def: ConstId) -> Ty { 674fn type_for_const(db: &impl HirDatabase, def: ConstId) -> Binders<Ty> {
639 let data = db.const_data(def); 675 let data = db.const_data(def);
676 let generics = generics(db, def.into());
640 let resolver = def.resolver(db); 677 let resolver = def.resolver(db);
641 let ctx = TyLoweringContext { 678 let ctx = TyLoweringContext::new(db, &resolver)
642 db, 679 .with_type_param_mode(TypeParamLoweringMode::Variable);
643 resolver: &resolver,
644 impl_trait_mode: ImplTraitLoweringMode::Disallowed,
645 };
646 680
647 Ty::from_hir(&ctx, &data.type_ref) 681 Binders::new(generics.len(), Ty::from_hir(&ctx, &data.type_ref))
648} 682}
649 683
650/// Build the declared type of a static. 684/// Build the declared type of a static.
651fn type_for_static(db: &impl HirDatabase, def: StaticId) -> Ty { 685fn type_for_static(db: &impl HirDatabase, def: StaticId) -> Binders<Ty> {
652 let data = db.static_data(def); 686 let data = db.static_data(def);
653 let resolver = def.resolver(db); 687 let resolver = def.resolver(db);
654 let ctx = TyLoweringContext { 688 let ctx = TyLoweringContext::new(db, &resolver);
655 db,
656 resolver: &resolver,
657 impl_trait_mode: ImplTraitLoweringMode::Disallowed,
658 };
659 689
660 Ty::from_hir(&ctx, &data.type_ref) 690 Binders::new(0, Ty::from_hir(&ctx, &data.type_ref))
661} 691}
662 692
663/// Build the declared type of a static. 693/// Build the declared type of a static.
@@ -671,79 +701,71 @@ fn type_for_builtin(def: BuiltinType) -> Ty {
671 }) 701 })
672} 702}
673 703
674fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig { 704fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> PolyFnSig {
675 let struct_data = db.struct_data(def.into()); 705 let struct_data = db.struct_data(def.into());
676 let fields = struct_data.variant_data.fields(); 706 let fields = struct_data.variant_data.fields();
677 let resolver = def.resolver(db); 707 let resolver = def.resolver(db);
678 let ctx = TyLoweringContext { 708 let ctx = TyLoweringContext::new(db, &resolver)
679 db, 709 .with_type_param_mode(TypeParamLoweringMode::Variable);
680 resolver: &resolver,
681 impl_trait_mode: ImplTraitLoweringMode::Disallowed,
682 };
683 let params = 710 let params =
684 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); 711 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
685 let ret = type_for_adt(db, def.into()); 712 let ret = type_for_adt(db, def.into());
686 FnSig::from_params_and_return(params, ret) 713 Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value))
687} 714}
688 715
689/// Build the type of a tuple struct constructor. 716/// Build the type of a tuple struct constructor.
690fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Ty { 717fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Binders<Ty> {
691 let struct_data = db.struct_data(def.into()); 718 let struct_data = db.struct_data(def.into());
692 if struct_data.variant_data.is_unit() { 719 if struct_data.variant_data.is_unit() {
693 return type_for_adt(db, def.into()); // Unit struct 720 return type_for_adt(db, def.into()); // Unit struct
694 } 721 }
695 let generics = generics(db, def.into()); 722 let generics = generics(db, def.into());
696 let substs = Substs::identity(&generics); 723 let substs = Substs::bound_vars(&generics);
697 Ty::apply(TypeCtor::FnDef(def.into()), substs) 724 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs))
698} 725}
699 726
700fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> FnSig { 727fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> PolyFnSig {
701 let enum_data = db.enum_data(def.parent); 728 let enum_data = db.enum_data(def.parent);
702 let var_data = &enum_data.variants[def.local_id]; 729 let var_data = &enum_data.variants[def.local_id];
703 let fields = var_data.variant_data.fields(); 730 let fields = var_data.variant_data.fields();
704 let resolver = def.parent.resolver(db); 731 let resolver = def.parent.resolver(db);
705 let ctx = TyLoweringContext { 732 let ctx = TyLoweringContext::new(db, &resolver);
706 db,
707 resolver: &resolver,
708 impl_trait_mode: ImplTraitLoweringMode::Disallowed,
709 };
710 let params = 733 let params =
711 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); 734 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
712 let generics = generics(db, def.parent.into()); 735 let generics = generics(db, def.parent.into());
713 let substs = Substs::identity(&generics); 736 let substs = Substs::bound_vars(&generics);
714 let ret = type_for_adt(db, def.parent.into()).subst(&substs); 737 let ret = type_for_adt(db, def.parent.into()).subst(&substs);
715 FnSig::from_params_and_return(params, ret) 738 let num_binders = generics.len();
739 Binders::new(num_binders, FnSig::from_params_and_return(params, ret))
716} 740}
717 741
718/// Build the type of a tuple enum variant constructor. 742/// Build the type of a tuple enum variant constructor.
719fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> Ty { 743fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> Binders<Ty> {
720 let enum_data = db.enum_data(def.parent); 744 let enum_data = db.enum_data(def.parent);
721 let var_data = &enum_data.variants[def.local_id].variant_data; 745 let var_data = &enum_data.variants[def.local_id].variant_data;
722 if var_data.is_unit() { 746 if var_data.is_unit() {
723 return type_for_adt(db, def.parent.into()); // Unit variant 747 return type_for_adt(db, def.parent.into()); // Unit variant
724 } 748 }
725 let generics = generics(db, def.parent.into()); 749 let generics = generics(db, def.parent.into());
726 let substs = Substs::identity(&generics); 750 let substs = Substs::bound_vars(&generics);
727 Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs) 751 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs))
728} 752}
729 753
730fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Ty { 754fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Binders<Ty> {
731 let generics = generics(db, adt.into()); 755 let generics = generics(db, adt.into());
732 Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) 756 let substs = Substs::bound_vars(&generics);
757 Binders::new(substs.len(), Ty::apply(TypeCtor::Adt(adt), substs))
733} 758}
734 759
735fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty { 760fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Binders<Ty> {
736 let generics = generics(db, t.into()); 761 let generics = generics(db, t.into());
737 let resolver = t.resolver(db); 762 let resolver = t.resolver(db);
738 let ctx = TyLoweringContext { 763 let ctx = TyLoweringContext::new(db, &resolver)
739 db, 764 .with_type_param_mode(TypeParamLoweringMode::Variable);
740 resolver: &resolver,
741 impl_trait_mode: ImplTraitLoweringMode::Disallowed,
742 };
743 let type_ref = &db.type_alias_data(t).type_ref; 765 let type_ref = &db.type_alias_data(t).type_ref;
744 let substs = Substs::identity(&generics); 766 let substs = Substs::bound_vars(&generics);
745 let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error)); 767 let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error));
746 inner.subst(&substs) 768 Binders::new(substs.len(), inner)
747} 769}
748 770
749#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 771#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -797,19 +819,20 @@ impl_froms!(ValueTyDefId: FunctionId, StructId, EnumVariantId, ConstId, StaticId
797/// `struct Foo(usize)`, we have two types: The type of the struct itself, and 819/// `struct Foo(usize)`, we have two types: The type of the struct itself, and
798/// the constructor function `(usize) -> Foo` which lives in the values 820/// the constructor function `(usize) -> Foo` which lives in the values
799/// namespace. 821/// namespace.
800pub(crate) fn ty_query(db: &impl HirDatabase, def: TyDefId) -> Ty { 822pub(crate) fn ty_query(db: &impl HirDatabase, def: TyDefId) -> Binders<Ty> {
801 match def { 823 match def {
802 TyDefId::BuiltinType(it) => type_for_builtin(it), 824 TyDefId::BuiltinType(it) => Binders::new(0, type_for_builtin(it)),
803 TyDefId::AdtId(it) => type_for_adt(db, it), 825 TyDefId::AdtId(it) => type_for_adt(db, it),
804 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), 826 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
805 } 827 }
806} 828}
807 829
808pub(crate) fn ty_recover(_db: &impl HirDatabase, _cycle: &[String], _def: &TyDefId) -> Ty { 830pub(crate) fn ty_recover(_db: &impl HirDatabase, _cycle: &[String], _def: &TyDefId) -> Binders<Ty> {
809 Ty::Unknown 831 // TODO still need correct number of binders here
832 Binders::new(0, Ty::Unknown)
810} 833}
811 834
812pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty { 835pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
813 match def { 836 match def {
814 ValueTyDefId::FunctionId(it) => type_for_fn(db, it), 837 ValueTyDefId::FunctionId(it) => type_for_fn(db, it),
815 ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it), 838 ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
@@ -819,34 +842,30 @@ pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty {
819 } 842 }
820} 843}
821 844
822pub(crate) fn impl_self_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> Ty { 845pub(crate) fn impl_self_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> Binders<Ty> {
823 let impl_data = db.impl_data(impl_id); 846 let impl_data = db.impl_data(impl_id);
824 let resolver = impl_id.resolver(db); 847 let resolver = impl_id.resolver(db);
825 let ctx = TyLoweringContext { 848 let generics = generics(db, impl_id.into());
826 db, 849 let ctx = TyLoweringContext::new(db, &resolver)
827 resolver: &resolver, 850 .with_type_param_mode(TypeParamLoweringMode::Variable);
828 impl_trait_mode: ImplTraitLoweringMode::Disallowed, 851 Binders::new(generics.len(), Ty::from_hir(&ctx, &impl_data.target_type))
829 };
830 Ty::from_hir(&ctx, &impl_data.target_type)
831} 852}
832 853
833pub(crate) fn impl_self_ty_recover( 854pub(crate) fn impl_self_ty_recover(
834 _db: &impl HirDatabase, 855 db: &impl HirDatabase,
835 _cycle: &[String], 856 _cycle: &[String],
836 _impl_id: &ImplId, 857 impl_id: &ImplId,
837) -> Ty { 858) -> Binders<Ty> {
838 Ty::Unknown 859 let generics = generics(db, (*impl_id).into());
860 Binders::new(generics.len(), Ty::Unknown)
839} 861}
840 862
841pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<TraitRef> { 863pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<TraitRef> {
842 let impl_data = db.impl_data(impl_id); 864 let impl_data = db.impl_data(impl_id);
843 let resolver = impl_id.resolver(db); 865 let resolver = impl_id.resolver(db);
844 let ctx = TyLoweringContext { 866 let generics = generics(db, impl_id.into());
845 db, 867 let ctx = TyLoweringContext::new(db, &resolver);
846 resolver: &resolver, 868 let self_ty = db.impl_self_ty(impl_id).subst(&Substs::identity(&generics));
847 impl_trait_mode: ImplTraitLoweringMode::Disallowed,
848 };
849 let self_ty = db.impl_self_ty(impl_id);
850 let target_trait = impl_data.target_trait.as_ref()?; 869 let target_trait = impl_data.target_trait.as_ref()?;
851 TraitRef::from_hir(&ctx, target_trait, Some(self_ty.clone())) 870 TraitRef::from_hir(&ctx, target_trait, Some(self_ty.clone()))
852} 871}
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index 5bacbbd7c..eab2149dc 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -65,7 +65,7 @@ impl CrateImplBlocks {
65 } 65 }
66 None => { 66 None => {
67 let self_ty = db.impl_self_ty(impl_id); 67 let self_ty = db.impl_self_ty(impl_id);
68 if let Some(self_ty_fp) = TyFingerprint::for_impl(&self_ty) { 68 if let Some(self_ty_fp) = TyFingerprint::for_impl(&self_ty.value) {
69 res.impls.entry(self_ty_fp).or_default().push(impl_id); 69 res.impls.entry(self_ty_fp).or_default().push(impl_id);
70 } 70 }
71 } 71 }
@@ -496,7 +496,7 @@ fn transform_receiver_ty(
496 AssocContainerId::ContainerId(_) => unreachable!(), 496 AssocContainerId::ContainerId(_) => unreachable!(),
497 }; 497 };
498 let sig = db.callable_item_signature(function_id.into()); 498 let sig = db.callable_item_signature(function_id.into());
499 Some(sig.params()[0].clone().subst(&substs)) 499 Some(sig.value.params()[0].clone().subst_bound_vars(&substs))
500} 500}
501 501
502pub fn implements_trait( 502pub fn implements_trait(
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs
index fdab9c187..f1238506b 100644
--- a/crates/ra_hir_ty/src/tests/simple.rs
+++ b/crates/ra_hir_ty/src/tests/simple.rs
@@ -1220,7 +1220,7 @@ fn test() {
1220} 1220}
1221 1221
1222#[test] 1222#[test]
1223fn infer_impl_generics() { 1223fn infer_impl_generics_basic() {
1224 assert_snapshot!( 1224 assert_snapshot!(
1225 infer(r#" 1225 infer(r#"
1226struct A<T1, T2> { 1226struct A<T1, T2> {
diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs
index 314a3241f..f116b95e7 100644
--- a/crates/ra_hir_ty/src/utils.rs
+++ b/crates/ra_hir_ty/src/utils.rs
@@ -5,7 +5,7 @@ use std::sync::Arc;
5use hir_def::{ 5use hir_def::{
6 adt::VariantData, 6 adt::VariantData,
7 db::DefDatabase, 7 db::DefDatabase,
8 generics::{GenericParams, TypeParamData}, 8 generics::{GenericParams, TypeParamData, TypeParamProvenance},
9 path::Path, 9 path::Path,
10 resolver::{HasResolver, TypeNs}, 10 resolver::{HasResolver, TypeNs},
11 type_ref::TypeRef, 11 type_ref::TypeRef,
@@ -117,19 +117,31 @@ impl Generics {
117 pub(crate) fn len(&self) -> usize { 117 pub(crate) fn len(&self) -> usize {
118 self.len_split().0 118 self.len_split().0
119 } 119 }
120
120 /// (total, parents, child) 121 /// (total, parents, child)
121 pub(crate) fn len_split(&self) -> (usize, usize, usize) { 122 pub(crate) fn len_split(&self) -> (usize, usize, usize) {
122 let parent = self.parent_generics.as_ref().map_or(0, |p| p.len()); 123 let parent = self.parent_generics.as_ref().map_or(0, |p| p.len());
123 let child = self.params.types.len(); 124 let child = self.params.types.len();
124 (parent + child, parent, child) 125 (parent + child, parent, child)
125 } 126 }
127
128 /// (self, type param list, impl trait)
129 pub(crate) fn provenance_split(&self) -> (usize, usize, usize) {
130 let self_params = self.params.types.iter().filter(|(_, p)| p.provenance == TypeParamProvenance::TraitSelf).count();
131 let list_params = self.params.types.iter().filter(|(_, p)| p.provenance == TypeParamProvenance::TypeParamList).count();
132 let impl_trait_params = self.params.types.iter().filter(|(_, p)| p.provenance == TypeParamProvenance::ArgumentImplTrait).count();
133 (self_params, list_params, impl_trait_params)
134 }
135
126 pub(crate) fn param_idx(&self, param: TypeParamId) -> u32 { 136 pub(crate) fn param_idx(&self, param: TypeParamId) -> u32 {
127 self.find_param(param).0 137 self.find_param(param).0
128 } 138 }
139
129 pub(crate) fn param_name(&self, param: TypeParamId) -> Name { 140 pub(crate) fn param_name(&self, param: TypeParamId) -> Name {
130 // FIXME make this return Option 141 // FIXME make this return Option
131 self.find_param(param).1.name.clone().unwrap_or_else(Name::missing) 142 self.find_param(param).1.name.clone().unwrap_or_else(Name::missing)
132 } 143 }
144
133 fn find_param(&self, param: TypeParamId) -> (u32, &TypeParamData) { 145 fn find_param(&self, param: TypeParamId) -> (u32, &TypeParamData) {
134 if param.parent == self.def { 146 if param.parent == self.def {
135 let (idx, (_local_id, data)) = self 147 let (idx, (_local_id, data)) = self