aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty')
-rw-r--r--crates/hir_ty/src/autoderef.rs51
-rw-r--r--crates/hir_ty/src/db.rs11
-rw-r--r--crates/hir_ty/src/display.rs65
-rw-r--r--crates/hir_ty/src/infer.rs2
-rw-r--r--crates/hir_ty/src/infer/coerce.rs6
-rw-r--r--crates/hir_ty/src/infer/expr.rs27
-rw-r--r--crates/hir_ty/src/infer/pat.rs34
-rw-r--r--crates/hir_ty/src/infer/unify.rs66
-rw-r--r--crates/hir_ty/src/lib.rs138
-rw-r--r--crates/hir_ty/src/lower.rs109
-rw-r--r--crates/hir_ty/src/method_resolution.rs53
-rw-r--r--crates/hir_ty/src/tests.rs69
-rw-r--r--crates/hir_ty/src/tests/macros.rs23
-rw-r--r--crates/hir_ty/src/tests/patterns.rs22
-rw-r--r--crates/hir_ty/src/tests/regression.rs13
-rw-r--r--crates/hir_ty/src/tests/traits.rs96
-rw-r--r--crates/hir_ty/src/traits.rs17
-rw-r--r--crates/hir_ty/src/traits/chalk.rs20
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs124
-rw-r--r--crates/hir_ty/src/utils.rs10
20 files changed, 694 insertions, 262 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index 23ab042c1..dc5fc759a 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -16,8 +16,8 @@ use crate::{
16 to_assoc_type_id, to_chalk_trait_id, 16 to_assoc_type_id, to_chalk_trait_id,
17 traits::{InEnvironment, Solution}, 17 traits::{InEnvironment, Solution},
18 utils::generics, 18 utils::generics,
19 AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, Interner, ProjectionTy, Substitution, 19 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner,
20 TraitRef, Ty, TyKind, 20 ProjectionTy, Substitution, TraitRef, Ty, TyKind,
21}; 21};
22 22
23const AUTODEREF_RECURSION_LIMIT: usize = 10; 23const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -27,9 +27,9 @@ pub fn autoderef<'a>(
27 krate: Option<CrateId>, 27 krate: Option<CrateId>,
28 ty: InEnvironment<Canonical<Ty>>, 28 ty: InEnvironment<Canonical<Ty>>,
29) -> impl Iterator<Item = Canonical<Ty>> + 'a { 29) -> impl Iterator<Item = Canonical<Ty>> + 'a {
30 let InEnvironment { value: ty, environment } = ty; 30 let InEnvironment { goal: ty, environment } = ty;
31 successors(Some(ty), move |ty| { 31 successors(Some(ty), move |ty| {
32 deref(db, krate?, InEnvironment { value: ty, environment: environment.clone() }) 32 deref(db, krate?, InEnvironment { goal: ty, environment: environment.clone() })
33 }) 33 })
34 .take(AUTODEREF_RECURSION_LIMIT) 34 .take(AUTODEREF_RECURSION_LIMIT)
35} 35}
@@ -39,8 +39,8 @@ pub(crate) fn deref(
39 krate: CrateId, 39 krate: CrateId,
40 ty: InEnvironment<&Canonical<Ty>>, 40 ty: InEnvironment<&Canonical<Ty>>,
41) -> Option<Canonical<Ty>> { 41) -> Option<Canonical<Ty>> {
42 if let Some(derefed) = ty.value.value.builtin_deref() { 42 if let Some(derefed) = ty.goal.value.builtin_deref() {
43 Some(Canonical { value: derefed, kinds: ty.value.kinds.clone() }) 43 Some(Canonical { value: derefed, binders: ty.goal.binders.clone() })
44 } else { 44 } else {
45 deref_by_trait(db, krate, ty) 45 deref_by_trait(db, krate, ty)
46 } 46 }
@@ -67,15 +67,15 @@ fn deref_by_trait(
67 // FIXME make the Canonical / bound var handling nicer 67 // FIXME make the Canonical / bound var handling nicer
68 68
69 let parameters = 69 let parameters =
70 Substitution::build_for_generics(&generic_params).push(ty.value.value.clone()).build(); 70 Substitution::build_for_generics(&generic_params).push(ty.goal.value.clone()).build();
71 71
72 // Check that the type implements Deref at all 72 // Check that the type implements Deref at all
73 let trait_ref = 73 let trait_ref =
74 TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() }; 74 TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() };
75 let implements_goal = Canonical { 75 let implements_goal = Canonical {
76 kinds: ty.value.kinds.clone(), 76 binders: ty.goal.binders.clone(),
77 value: InEnvironment { 77 value: InEnvironment {
78 value: trait_ref.cast(&Interner), 78 goal: trait_ref.cast(&Interner),
79 environment: ty.environment.clone(), 79 environment: ty.environment.clone(),
80 }, 80 },
81 }; 81 };
@@ -89,18 +89,27 @@ fn deref_by_trait(
89 associated_ty_id: to_assoc_type_id(target), 89 associated_ty_id: to_assoc_type_id(target),
90 substitution: parameters, 90 substitution: parameters,
91 }), 91 }),
92 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())) 92 ty: TyKind::BoundVar(BoundVar::new(
93 .intern(&Interner), 93 DebruijnIndex::INNERMOST,
94 ty.goal.binders.len(&Interner),
95 ))
96 .intern(&Interner),
94 }; 97 };
95 98
96 let obligation = projection.cast(&Interner); 99 let obligation = projection.cast(&Interner);
97 100
98 let in_env = InEnvironment { value: obligation, environment: ty.environment }; 101 let in_env = InEnvironment { goal: obligation, environment: ty.environment };
99 102
100 let canonical = Canonical::new( 103 let canonical = Canonical {
101 in_env, 104 value: in_env,
102 ty.value.kinds.iter().copied().chain(Some(chalk_ir::TyVariableKind::General)), 105 binders: CanonicalVarKinds::from_iter(
103 ); 106 &Interner,
107 ty.goal.binders.iter(&Interner).cloned().chain(Some(chalk_ir::WithKind::new(
108 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
109 chalk_ir::UniverseIndex::ROOT,
110 ))),
111 ),
112 };
104 113
105 let solution = db.trait_solve(krate, canonical)?; 114 let solution = db.trait_solve(krate, canonical)?;
106 115
@@ -121,21 +130,21 @@ fn deref_by_trait(
121 // assumptions will be broken. We would need to properly introduce 130 // assumptions will be broken. We would need to properly introduce
122 // new variables in that case 131 // new variables in that case
123 132
124 for i in 1..vars.0.kinds.len() { 133 for i in 1..vars.0.binders.len(&Interner) {
125 if vars.0.value[i - 1].interned(&Interner) 134 if vars.0.value[i - 1].interned(&Interner)
126 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) 135 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
127 { 136 {
128 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); 137 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution);
129 return None; 138 return None;
130 } 139 }
131 } 140 }
132 Some(Canonical { 141 Some(Canonical {
133 value: vars.0.value[vars.0.value.len() - 1].clone(), 142 value: vars.0.value[vars.0.value.len() - 1].clone(),
134 kinds: vars.0.kinds.clone(), 143 binders: vars.0.binders.clone(),
135 }) 144 })
136 } 145 }
137 Solution::Ambig(_) => { 146 Solution::Ambig(_) => {
138 info!("Ambiguous solution for derefing {:?}: {:?}", ty.value, solution); 147 info!("Ambiguous solution for derefing {:?}: {:?}", ty.goal, solution);
139 None 148 None
140 } 149 }
141 } 150 }
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs
index 91a2e0b5b..58e4247c6 100644
--- a/crates/hir_ty/src/db.rs
+++ b/crates/hir_ty/src/db.rs
@@ -12,8 +12,8 @@ use la_arena::ArenaMap;
12use crate::{ 12use crate::{
13 method_resolution::{InherentImpls, TraitImpls}, 13 method_resolution::{InherentImpls, TraitImpls},
14 traits::chalk, 14 traits::chalk,
15 Binders, CallableDefId, FnDefId, ImplTraitId, InferenceResult, PolyFnSig, ReturnTypeImplTraits, 15 Binders, CallableDefId, FnDefId, ImplTraitId, InferenceResult, PolyFnSig,
16 TraitRef, Ty, TyDefId, ValueTyDefId, WhereClause, 16 QuantifiedWhereClause, ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId,
17}; 17};
18use hir_expand::name::Name; 18use hir_expand::name::Name;
19 19
@@ -57,10 +57,13 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
57 57
58 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)] 58 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)]
59 #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)] 59 #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)]
60 fn generic_predicates_for_param(&self, param_id: TypeParamId) -> Arc<[Binders<WhereClause>]>; 60 fn generic_predicates_for_param(
61 &self,
62 param_id: TypeParamId,
63 ) -> Arc<[Binders<QuantifiedWhereClause>]>;
61 64
62 #[salsa::invoke(crate::lower::generic_predicates_query)] 65 #[salsa::invoke(crate::lower::generic_predicates_query)]
63 fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<WhereClause>]>; 66 fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<QuantifiedWhereClause>]>;
64 67
65 #[salsa::invoke(crate::lower::trait_environment_query)] 68 #[salsa::invoke(crate::lower::trait_environment_query)]
66 fn trait_environment(&self, def: GenericDefId) -> Arc<crate::TraitEnvironment>; 69 fn trait_environment(&self, def: GenericDefId) -> Arc<crate::TraitEnvironment>;
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 3845009ae..6149067c7 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use std::{borrow::Cow, fmt}; 3use std::fmt;
4 4
5use arrayvec::ArrayVec; 5use arrayvec::ArrayVec;
6use chalk_ir::Mutability; 6use chalk_ir::Mutability;
@@ -20,7 +20,7 @@ use crate::{
20 db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive, 20 db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive,
21 to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy, 21 to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy,
22 CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy, 22 CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy,
23 ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause, 23 ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause,
24}; 24};
25 25
26pub struct HirFormatter<'a> { 26pub struct HirFormatter<'a> {
@@ -190,6 +190,7 @@ impl DisplayTarget {
190pub enum DisplaySourceCodeError { 190pub enum DisplaySourceCodeError {
191 PathNotFound, 191 PathNotFound,
192 UnknownType, 192 UnknownType,
193 Closure,
193} 194}
194 195
195pub enum HirDisplayError { 196pub enum HirDisplayError {
@@ -328,9 +329,9 @@ impl HirDisplay for Ty {
328 329
329 // FIXME: all this just to decide whether to use parentheses... 330 // FIXME: all this just to decide whether to use parentheses...
330 let datas; 331 let datas;
331 let predicates = match t.interned(&Interner) { 332 let predicates: Vec<_> = match t.interned(&Interner) {
332 TyKind::Dyn(predicates) if predicates.len() > 1 => { 333 TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => {
333 Cow::Borrowed(predicates.as_ref()) 334 dyn_ty.bounds.skip_binders().interned().iter().cloned().collect()
334 } 335 }
335 &TyKind::Alias(AliasTy::Opaque(OpaqueTy { 336 &TyKind::Alias(AliasTy::Opaque(OpaqueTy {
336 opaque_ty_id, 337 opaque_ty_id,
@@ -345,17 +346,21 @@ impl HirDisplay for Ty {
345 .as_ref() 346 .as_ref()
346 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 347 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
347 let bounds = data.subst(parameters); 348 let bounds = data.subst(parameters);
348 Cow::Owned(bounds.value) 349 bounds.value
349 } else { 350 } else {
350 Cow::Borrowed(&[][..]) 351 Vec::new()
351 } 352 }
352 } 353 }
353 _ => Cow::Borrowed(&[][..]), 354 _ => Vec::new(),
354 }; 355 };
355 356
356 if let [WhereClause::Implemented(trait_ref), _] = predicates.as_ref() { 357 if let Some(WhereClause::Implemented(trait_ref)) =
358 predicates.get(0).map(|b| b.skip_binders())
359 {
357 let trait_ = trait_ref.hir_trait_id(); 360 let trait_ = trait_ref.hir_trait_id();
358 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) { 361 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_)
362 && predicates.len() <= 2
363 {
359 return write!(f, "{}", ty_display); 364 return write!(f, "{}", ty_display);
360 } 365 }
361 } 366 }
@@ -539,6 +544,11 @@ impl HirDisplay for Ty {
539 } 544 }
540 } 545 }
541 TyKind::Closure(.., substs) => { 546 TyKind::Closure(.., substs) => {
547 if f.display_target.is_source_code() {
548 return Err(HirDisplayError::DisplaySourceCodeError(
549 DisplaySourceCodeError::Closure,
550 ));
551 }
542 let sig = substs[0].callable_sig(f.db); 552 let sig = substs[0].callable_sig(f.db);
543 if let Some(sig) = sig { 553 if let Some(sig) = sig {
544 if sig.params().is_empty() { 554 if sig.params().is_empty() {
@@ -571,19 +581,32 @@ impl HirDisplay for Ty {
571 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? 581 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))?
572 } 582 }
573 TypeParamProvenance::ArgumentImplTrait => { 583 TypeParamProvenance::ArgumentImplTrait => {
574 let bounds = f.db.generic_predicates_for_param(id);
575 let substs = Substitution::type_params_for_generics(f.db, &generics); 584 let substs = Substitution::type_params_for_generics(f.db, &generics);
576 write_bounds_like_dyn_trait_with_prefix( 585 let bounds = f
577 "impl", 586 .db
578 &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(), 587 .generic_predicates(id.parent)
579 f, 588 .into_iter()
580 )?; 589 .map(|pred| pred.clone().subst(&substs))
590 .filter(|wc| match &wc.skip_binders() {
591 WhereClause::Implemented(tr) => tr.self_type_parameter() == self,
592 WhereClause::AliasEq(AliasEq {
593 alias: AliasTy::Projection(proj),
594 ty: _,
595 }) => proj.self_type_parameter() == self,
596 _ => false,
597 })
598 .collect::<Vec<_>>();
599 write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?;
581 } 600 }
582 } 601 }
583 } 602 }
584 TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, 603 TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?,
585 TyKind::Dyn(predicates) => { 604 TyKind::Dyn(dyn_ty) => {
586 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; 605 write_bounds_like_dyn_trait_with_prefix(
606 "dyn",
607 dyn_ty.bounds.skip_binders().interned(),
608 f,
609 )?;
587 } 610 }
588 TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?, 611 TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?,
589 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { 612 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
@@ -652,7 +675,7 @@ fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator<Item = Trai
652 675
653pub fn write_bounds_like_dyn_trait_with_prefix( 676pub fn write_bounds_like_dyn_trait_with_prefix(
654 prefix: &str, 677 prefix: &str,
655 predicates: &[WhereClause], 678 predicates: &[QuantifiedWhereClause],
656 f: &mut HirFormatter, 679 f: &mut HirFormatter,
657) -> Result<(), HirDisplayError> { 680) -> Result<(), HirDisplayError> {
658 write!(f, "{}", prefix)?; 681 write!(f, "{}", prefix)?;
@@ -665,7 +688,7 @@ pub fn write_bounds_like_dyn_trait_with_prefix(
665} 688}
666 689
667fn write_bounds_like_dyn_trait( 690fn write_bounds_like_dyn_trait(
668 predicates: &[WhereClause], 691 predicates: &[QuantifiedWhereClause],
669 f: &mut HirFormatter, 692 f: &mut HirFormatter,
670) -> Result<(), HirDisplayError> { 693) -> Result<(), HirDisplayError> {
671 // Note: This code is written to produce nice results (i.e. 694 // Note: This code is written to produce nice results (i.e.
@@ -678,7 +701,7 @@ fn write_bounds_like_dyn_trait(
678 let mut angle_open = false; 701 let mut angle_open = false;
679 let mut is_fn_trait = false; 702 let mut is_fn_trait = false;
680 for p in predicates.iter() { 703 for p in predicates.iter() {
681 match p { 704 match p.skip_binders() {
682 WhereClause::Implemented(trait_ref) => { 705 WhereClause::Implemented(trait_ref) => {
683 let trait_ = trait_ref.hir_trait_id(); 706 let trait_ = trait_ref.hir_trait_id();
684 if !is_fn_trait { 707 if !is_fn_trait {
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index b9e434c78..8f9cf7480 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -331,7 +331,7 @@ impl<'a> InferenceContext<'a> {
331 fn resolve_obligations_as_possible(&mut self) { 331 fn resolve_obligations_as_possible(&mut self) {
332 let obligations = mem::replace(&mut self.obligations, Vec::new()); 332 let obligations = mem::replace(&mut self.obligations, Vec::new());
333 for obligation in obligations { 333 for obligation in obligations {
334 let in_env = InEnvironment::new(self.trait_env.clone(), obligation.clone()); 334 let in_env = InEnvironment::new(self.trait_env.env.clone(), obligation.clone());
335 let canonicalized = self.canonicalizer().canonicalize_obligation(in_env); 335 let canonicalized = self.canonicalizer().canonicalize_obligation(in_env);
336 let solution = 336 let solution =
337 self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone()); 337 self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone());
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 07eb96573..9c62932b1 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -142,7 +142,7 @@ impl<'a> InferenceContext<'a> {
142 .build(); 142 .build();
143 let trait_ref = 143 let trait_ref =
144 TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs }; 144 TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs };
145 let goal = InEnvironment::new(self.trait_env.clone(), trait_ref.cast(&Interner)); 145 let goal = InEnvironment::new(self.trait_env.env.clone(), trait_ref.cast(&Interner));
146 146
147 let canonicalizer = self.canonicalizer(); 147 let canonicalizer = self.canonicalizer();
148 let canonicalized = canonicalizer.canonicalize_obligation(goal); 148 let canonicalized = canonicalizer.canonicalize_obligation(goal);
@@ -170,8 +170,8 @@ impl<'a> InferenceContext<'a> {
170 self.db, 170 self.db,
171 self.resolver.krate(), 171 self.resolver.krate(),
172 InEnvironment { 172 InEnvironment {
173 value: canonicalized.value.clone(), 173 goal: canonicalized.value.clone(),
174 environment: self.trait_env.clone(), 174 environment: self.trait_env.env.clone(),
175 }, 175 },
176 ) { 176 ) {
177 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); 177 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value);
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 46d713a7b..3f3187ea2 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -11,6 +11,7 @@ use hir_def::{
11 AssocContainerId, FieldId, Lookup, 11 AssocContainerId, FieldId, Lookup,
12}; 12};
13use hir_expand::name::{name, Name}; 13use hir_expand::name::{name, Name};
14use stdx::always;
14use syntax::ast::RangeOp; 15use syntax::ast::RangeOp;
15 16
16use crate::{ 17use crate::{
@@ -89,12 +90,12 @@ impl<'a> InferenceContext<'a> {
89 let substs = 90 let substs =
90 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 91 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
91 92
92 let trait_env = Arc::clone(&self.trait_env); 93 let trait_env = self.trait_env.env.clone();
93 let implements_fn_trait: DomainGoal = 94 let implements_fn_trait: DomainGoal =
94 TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() } 95 TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() }
95 .cast(&Interner); 96 .cast(&Interner);
96 let goal = self.canonicalizer().canonicalize_obligation(InEnvironment { 97 let goal = self.canonicalizer().canonicalize_obligation(InEnvironment {
97 value: implements_fn_trait.clone(), 98 goal: implements_fn_trait.clone(),
98 environment: trait_env, 99 environment: trait_env,
99 }); 100 });
100 if self.db.trait_solve(krate, goal.value).is_some() { 101 if self.db.trait_solve(krate, goal.value).is_some() {
@@ -298,8 +299,8 @@ impl<'a> InferenceContext<'a> {
298 self.db, 299 self.db,
299 self.resolver.krate(), 300 self.resolver.krate(),
300 InEnvironment { 301 InEnvironment {
301 value: canonicalized.value.clone(), 302 goal: canonicalized.value.clone(),
302 environment: self.trait_env.clone(), 303 environment: self.trait_env.env.clone(),
303 }, 304 },
304 ); 305 );
305 let (param_tys, ret_ty): (Vec<Ty>, Ty) = derefs 306 let (param_tys, ret_ty): (Vec<Ty>, Ty) = derefs
@@ -437,8 +438,8 @@ impl<'a> InferenceContext<'a> {
437 self.db, 438 self.db,
438 self.resolver.krate(), 439 self.resolver.krate(),
439 InEnvironment { 440 InEnvironment {
440 value: canonicalized.value.clone(), 441 goal: canonicalized.value.clone(),
441 environment: self.trait_env.clone(), 442 environment: self.trait_env.env.clone(),
442 }, 443 },
443 ) 444 )
444 .find_map(|derefed_ty| { 445 .find_map(|derefed_ty| {
@@ -533,10 +534,10 @@ impl<'a> InferenceContext<'a> {
533 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 534 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
534 if let Some(box_) = self.resolve_boxed_box() { 535 if let Some(box_) = self.resolve_boxed_box() {
535 let mut sb = 536 let mut sb =
536 Substitution::builder(generics(self.db.upcast(), box_.into()).len()); 537 Substitution::build_for_generics(&generics(self.db.upcast(), box_.into()));
537 sb = sb.push(inner_ty); 538 sb = sb.push(inner_ty);
538 match self.db.generic_defaults(box_.into()).as_ref() { 539 match self.db.generic_defaults(box_.into()).get(1) {
539 [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => { 540 Some(alloc_ty) if !alloc_ty.value.is_unknown() && sb.remaining() > 0 => {
540 sb = sb.push(alloc_ty.value.clone()); 541 sb = sb.push(alloc_ty.value.clone());
541 } 542 }
542 _ => (), 543 _ => (),
@@ -557,8 +558,8 @@ impl<'a> InferenceContext<'a> {
557 self.db, 558 self.db,
558 krate, 559 krate,
559 InEnvironment { 560 InEnvironment {
560 value: &canonicalized.value, 561 goal: &canonicalized.value,
561 environment: self.trait_env.clone(), 562 environment: self.trait_env.env.clone(),
562 }, 563 },
563 ) { 564 ) {
564 Some(derefed_ty) => { 565 Some(derefed_ty) => {
@@ -957,7 +958,9 @@ impl<'a> InferenceContext<'a> {
957 let def: CallableDefId = from_chalk(self.db, *fn_def); 958 let def: CallableDefId = from_chalk(self.db, *fn_def);
958 let generic_predicates = self.db.generic_predicates(def.into()); 959 let generic_predicates = self.db.generic_predicates(def.into());
959 for predicate in generic_predicates.iter() { 960 for predicate in generic_predicates.iter() {
960 let predicate = predicate.clone().subst(parameters); 961 let (predicate, binders) =
962 predicate.clone().subst(parameters).into_value_and_skipped_binders();
963 always!(binders == 0); // quantified where clauses not yet handled
961 self.obligations.push(predicate.cast(&Interner)); 964 self.obligations.push(predicate.cast(&Interner));
962 } 965 }
963 // add obligation for trait implementation, if this is a trait method 966 // add obligation for trait implementation, if this is a trait method
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index befa0d69b..474363709 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -13,7 +13,9 @@ use hir_expand::name::Name;
13 13
14use super::{BindingMode, Expectation, InferenceContext}; 14use super::{BindingMode, Expectation, InferenceContext};
15use crate::{ 15use crate::{
16 lower::lower_to_chalk_mutability, utils::variant_data, Interner, Substitution, Ty, TyKind, 16 lower::lower_to_chalk_mutability,
17 utils::{generics, variant_data},
18 Interner, Substitution, Ty, TyKind,
17}; 19};
18 20
19impl<'a> InferenceContext<'a> { 21impl<'a> InferenceContext<'a> {
@@ -38,7 +40,7 @@ impl<'a> InferenceContext<'a> {
38 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 40 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
39 let (pre, post) = match ellipsis { 41 let (pre, post) = match ellipsis {
40 Some(idx) => subpats.split_at(idx), 42 Some(idx) => subpats.split_at(idx),
41 None => (&subpats[..], &[][..]), 43 None => (subpats, &[][..]),
42 }; 44 };
43 let post_idx_offset = field_tys.iter().count() - post.len(); 45 let post_idx_offset = field_tys.iter().count() - post.len();
44 46
@@ -233,13 +235,31 @@ impl<'a> InferenceContext<'a> {
233 Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())), 235 Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())),
234 Pat::Box { inner } => match self.resolve_boxed_box() { 236 Pat::Box { inner } => match self.resolve_boxed_box() {
235 Some(box_adt) => { 237 Some(box_adt) => {
236 let inner_expected = match expected.as_adt() { 238 let (inner_ty, alloc_ty) = match expected.as_adt() {
237 Some((adt, substs)) if adt == box_adt => substs.as_single().clone(), 239 Some((adt, subst)) if adt == box_adt => {
238 _ => self.result.standard_types.unknown.clone(), 240 (subst[0].clone(), subst.get(1).cloned())
241 }
242 _ => (self.result.standard_types.unknown.clone(), None),
239 }; 243 };
240 244
241 let inner_ty = self.infer_pat(*inner, &inner_expected, default_bm); 245 let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm);
242 Ty::adt_ty(box_adt, Substitution::single(inner_ty)) 246 let mut sb = Substitution::build_for_generics(&generics(
247 self.db.upcast(),
248 box_adt.into(),
249 ));
250 sb = sb.push(inner_ty);
251 if sb.remaining() == 1 {
252 sb = sb.push(match alloc_ty {
253 Some(alloc_ty) if !alloc_ty.is_unknown() => alloc_ty,
254 _ => match self.db.generic_defaults(box_adt.into()).get(1) {
255 Some(alloc_ty) if !alloc_ty.value.is_unknown() => {
256 alloc_ty.value.clone()
257 }
258 _ => self.table.new_type_var(),
259 },
260 });
261 }
262 Ty::adt_ty(box_adt, sb.build())
243 } 263 }
244 None => self.err_ty(), 264 None => self.err_ty(),
245 }, 265 },
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 1fc03c8f4..75250a369 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -2,13 +2,13 @@
2 2
3use std::borrow::Cow; 3use std::borrow::Cow;
4 4
5use chalk_ir::{FloatTy, IntTy, TyVariableKind}; 5use chalk_ir::{FloatTy, IntTy, TyVariableKind, UniverseIndex, VariableKind};
6use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; 6use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
7 7
8use super::{DomainGoal, InferenceContext}; 8use super::{DomainGoal, InferenceContext};
9use crate::{ 9use crate::{
10 AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, FnPointer, InEnvironment, InferenceVar, 10 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer,
11 Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause, 11 InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause,
12}; 12};
13 13
14impl<'a> InferenceContext<'a> { 14impl<'a> InferenceContext<'a> {
@@ -76,8 +76,17 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
76 } 76 }
77 77
78 fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> { 78 fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> {
79 let kinds = self.free_vars.iter().map(|&(_, k)| k).collect(); 79 let kinds = self
80 Canonicalized { value: Canonical { value: result, kinds }, free_vars: self.free_vars } 80 .free_vars
81 .iter()
82 .map(|&(_, k)| chalk_ir::WithKind::new(VariableKind::Ty(k), UniverseIndex::ROOT));
83 Canonicalized {
84 value: Canonical {
85 value: result,
86 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
87 },
88 free_vars: self.free_vars,
89 }
81 } 90 }
82 91
83 pub(crate) fn canonicalize_ty(mut self, ty: Ty) -> Canonicalized<Ty> { 92 pub(crate) fn canonicalize_ty(mut self, ty: Ty) -> Canonicalized<Ty> {
@@ -89,15 +98,12 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
89 mut self, 98 mut self,
90 obligation: InEnvironment<DomainGoal>, 99 obligation: InEnvironment<DomainGoal>,
91 ) -> Canonicalized<InEnvironment<DomainGoal>> { 100 ) -> Canonicalized<InEnvironment<DomainGoal>> {
92 let result = match obligation.value { 101 let result = match obligation.goal {
93 DomainGoal::Holds(wc) => { 102 DomainGoal::Holds(wc) => {
94 DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST)) 103 DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST))
95 } 104 }
96 }; 105 };
97 self.into_canonicalized(InEnvironment { 106 self.into_canonicalized(InEnvironment { goal: result, environment: obligation.environment })
98 value: result,
99 environment: obligation.environment,
100 })
101 } 107 }
102} 108}
103 109
@@ -125,12 +131,19 @@ impl<T> Canonicalized<T> {
125 // the solution may contain new variables, which we need to convert to new inference vars 131 // the solution may contain new variables, which we need to convert to new inference vars
126 let new_vars = Substitution( 132 let new_vars = Substitution(
127 solution 133 solution
128 .kinds 134 .binders
129 .iter() 135 .iter(&Interner)
130 .map(|k| match k { 136 .map(|k| match k.kind {
131 TyVariableKind::General => ctx.table.new_type_var(), 137 VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(),
132 TyVariableKind::Integer => ctx.table.new_integer_var(), 138 VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(),
133 TyVariableKind::Float => ctx.table.new_float_var(), 139 VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(),
140 // HACK: Chalk can sometimes return new lifetime variables. We
141 // want to just skip them, but to not mess up the indices of
142 // other variables, we'll just create a new type variable in
143 // their place instead. This should not matter (we never see the
144 // actual *uses* of the lifetime variable).
145 VariableKind::Lifetime => ctx.table.new_type_var(),
146 _ => panic!("const variable in solution"),
134 }) 147 })
135 .collect(), 148 .collect(),
136 ); 149 );
@@ -147,8 +160,8 @@ impl<T> Canonicalized<T> {
147pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { 160pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
148 let mut table = InferenceTable::new(); 161 let mut table = InferenceTable::new();
149 let vars = Substitution( 162 let vars = Substitution(
150 tys.kinds 163 tys.binders
151 .iter() 164 .iter(&Interner)
152 // we always use type vars here because we want everything to 165 // we always use type vars here because we want everything to
153 // fallback to Unknown in the end (kind of hacky, as below) 166 // fallback to Unknown in the end (kind of hacky, as below)
154 .map(|_| table.new_type_var()) 167 .map(|_| table.new_type_var())
@@ -170,7 +183,7 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
170 } 183 }
171 } 184 }
172 Some( 185 Some(
173 Substitution::builder(tys.kinds.len()) 186 Substitution::builder(tys.binders.len(&Interner))
174 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) 187 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone())))
175 .build(), 188 .build(),
176 ) 189 )
@@ -310,9 +323,18 @@ impl InferenceTable {
310 323
311 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, 324 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true,
312 325
313 (TyKind::Dyn(dyn1), TyKind::Dyn(dyn2)) if dyn1.len() == dyn2.len() => { 326 (TyKind::Dyn(dyn1), TyKind::Dyn(dyn2))
314 for (pred1, pred2) in dyn1.iter().zip(dyn2.iter()) { 327 if dyn1.bounds.skip_binders().interned().len()
315 if !self.unify_preds(pred1, pred2, depth + 1) { 328 == dyn2.bounds.skip_binders().interned().len() =>
329 {
330 for (pred1, pred2) in dyn1
331 .bounds
332 .skip_binders()
333 .interned()
334 .iter()
335 .zip(dyn2.bounds.skip_binders().interned().iter())
336 {
337 if !self.unify_preds(pred1.skip_binders(), pred2.skip_binders(), depth + 1) {
316 return false; 338 return false;
317 } 339 }
318 } 340 }
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index c46529879..69265286f 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -61,6 +61,8 @@ pub type ClosureId = chalk_ir::ClosureId<Interner>;
61pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; 61pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
62pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; 62pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
63 63
64pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>;
65
64pub type ChalkTraitId = chalk_ir::TraitId<Interner>; 66pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
65 67
66#[derive(Clone, PartialEq, Eq, Debug, Hash)] 68#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -106,6 +108,10 @@ impl ProjectionTy {
106 } 108 }
107 } 109 }
108 110
111 pub fn self_type_parameter(&self) -> &Ty {
112 &self.substitution[0]
113 }
114
109 fn trait_(&self, db: &dyn HirDatabase) -> TraitId { 115 fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
110 match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container { 116 match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container {
111 AssocContainerId::TraitId(it) => it, 117 AssocContainerId::TraitId(it) => it,
@@ -128,6 +134,12 @@ impl TypeWalk for ProjectionTy {
128 } 134 }
129} 135}
130 136
137#[derive(Clone, PartialEq, Eq, Debug, Hash)]
138pub struct DynTy {
139 /// The unknown self type.
140 pub bounds: Binders<QuantifiedWhereClauses>,
141}
142
131pub type FnSig = chalk_ir::FnSig<Interner>; 143pub type FnSig = chalk_ir::FnSig<Interner>;
132 144
133#[derive(Clone, PartialEq, Eq, Debug, Hash)] 145#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -279,7 +291,7 @@ pub enum TyKind {
279 /// represents the `Self` type inside the bounds. This is currently 291 /// represents the `Self` type inside the bounds. This is currently
280 /// implicit; Chalk has the `Binders` struct to make it explicit, but it 292 /// implicit; Chalk has the `Binders` struct to make it explicit, but it
281 /// didn't seem worth the overhead yet. 293 /// didn't seem worth the overhead yet.
282 Dyn(Arc<[WhereClause]>), 294 Dyn(DynTy),
283 295
284 /// A placeholder for a type which could not be computed; this is propagated 296 /// A placeholder for a type which could not be computed; this is propagated
285 /// to avoid useless error messages. Doubles as a placeholder where type 297 /// to avoid useless error messages. Doubles as a placeholder where type
@@ -486,6 +498,13 @@ impl<T> Binders<T> {
486 Self { num_binders, value } 498 Self { num_binders, value }
487 } 499 }
488 500
501 pub fn wrap_empty(value: T) -> Self
502 where
503 T: TypeWalk,
504 {
505 Self { num_binders: 0, value: value.shift_bound_vars(DebruijnIndex::ONE) }
506 }
507
489 pub fn as_ref(&self) -> Binders<&T> { 508 pub fn as_ref(&self) -> Binders<&T> {
490 Binders { num_binders: self.num_binders, value: &self.value } 509 Binders { num_binders: self.num_binders, value: &self.value }
491 } 510 }
@@ -497,6 +516,14 @@ impl<T> Binders<T> {
497 pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> { 516 pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> {
498 Some(Binders { num_binders: self.num_binders, value: f(self.value)? }) 517 Some(Binders { num_binders: self.num_binders, value: f(self.value)? })
499 } 518 }
519
520 pub fn skip_binders(&self) -> &T {
521 &self.value
522 }
523
524 pub fn into_value_and_skipped_binders(self) -> (T, usize) {
525 (self.value, self.num_binders)
526 }
500} 527}
501 528
502impl<T: Clone> Binders<&T> { 529impl<T: Clone> Binders<&T> {
@@ -511,12 +538,6 @@ impl<T: TypeWalk> Binders<T> {
511 assert_eq!(subst.len(), self.num_binders); 538 assert_eq!(subst.len(), self.num_binders);
512 self.value.subst_bound_vars(subst) 539 self.value.subst_bound_vars(subst)
513 } 540 }
514
515 /// Substitutes just a prefix of the variables (shifting the rest).
516 pub fn subst_prefix(self, subst: &Substitution) -> Binders<T> {
517 assert!(subst.len() < self.num_binders);
518 Binders::new(self.num_binders - subst.len(), self.value.subst_bound_vars(subst))
519 }
520} 541}
521 542
522impl<T: TypeWalk> TypeWalk for Binders<T> { 543impl<T: TypeWalk> TypeWalk for Binders<T> {
@@ -610,6 +631,24 @@ impl TypeWalk for WhereClause {
610 } 631 }
611} 632}
612 633
634pub type QuantifiedWhereClause = Binders<WhereClause>;
635
636#[derive(Debug, Clone, PartialEq, Eq, Hash)]
637pub struct QuantifiedWhereClauses(Arc<[QuantifiedWhereClause]>);
638
639impl QuantifiedWhereClauses {
640 pub fn from_iter(
641 _interner: &Interner,
642 elements: impl IntoIterator<Item = QuantifiedWhereClause>,
643 ) -> Self {
644 QuantifiedWhereClauses(elements.into_iter().collect())
645 }
646
647 pub fn interned(&self) -> &Arc<[QuantifiedWhereClause]> {
648 &self.0
649 }
650}
651
613/// Basically a claim (currently not validated / checked) that the contained 652/// Basically a claim (currently not validated / checked) that the contained
614/// type / trait ref contains no inference variables; any inference variables it 653/// type / trait ref contains no inference variables; any inference variables it
615/// contained have been replaced by bound variables, and `kinds` tells us how 654/// contained have been replaced by bound variables, and `kinds` tells us how
@@ -619,12 +658,18 @@ impl TypeWalk for WhereClause {
619#[derive(Debug, Clone, PartialEq, Eq, Hash)] 658#[derive(Debug, Clone, PartialEq, Eq, Hash)]
620pub struct Canonical<T> { 659pub struct Canonical<T> {
621 pub value: T, 660 pub value: T,
622 pub kinds: Arc<[TyVariableKind]>, 661 pub binders: CanonicalVarKinds,
623} 662}
624 663
625impl<T> Canonical<T> { 664impl<T> Canonical<T> {
626 pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self { 665 pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self {
627 Self { value, kinds: kinds.into_iter().collect() } 666 let kinds = kinds.into_iter().map(|tk| {
667 chalk_ir::CanonicalVarKind::new(
668 chalk_ir::VariableKind::Ty(tk),
669 chalk_ir::UniverseIndex::ROOT,
670 )
671 });
672 Self { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) }
628 } 673 }
629} 674}
630 675
@@ -647,7 +692,15 @@ impl CallableSig {
647 692
648 pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { 693 pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
649 CallableSig { 694 CallableSig {
650 params_and_return: fn_ptr.substs.interned(&Interner).iter().cloned().collect(), 695 // FIXME: what to do about lifetime params?
696 params_and_return: fn_ptr
697 .substs
698 .clone()
699 .shift_bound_vars_out(DebruijnIndex::ONE)
700 .interned(&Interner)
701 .iter()
702 .cloned()
703 .collect(),
651 is_varargs: fn_ptr.sig.variadic, 704 is_varargs: fn_ptr.sig.variadic,
652 } 705 }
653 } 706 }
@@ -806,12 +859,14 @@ impl Ty {
806 } 859 }
807 860
808 /// If this is a `dyn Trait` type, this returns the `Trait` part. 861 /// If this is a `dyn Trait` type, this returns the `Trait` part.
809 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { 862 fn dyn_trait_ref(&self) -> Option<&TraitRef> {
810 match self.interned(&Interner) { 863 match self.interned(&Interner) {
811 TyKind::Dyn(bounds) => bounds.get(0).and_then(|b| match b { 864 TyKind::Dyn(dyn_ty) => {
812 WhereClause::Implemented(trait_ref) => Some(trait_ref), 865 dyn_ty.bounds.value.interned().get(0).and_then(|b| match b.skip_binders() {
813 _ => None, 866 WhereClause::Implemented(trait_ref) => Some(trait_ref),
814 }), 867 _ => None,
868 })
869 }
815 _ => None, 870 _ => None,
816 } 871 }
817 } 872 }
@@ -888,7 +943,7 @@ impl Ty {
888 } 943 }
889 } 944 }
890 945
891 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<WhereClause>> { 946 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>> {
892 match self.interned(&Interner) { 947 match self.interned(&Interner) {
893 TyKind::OpaqueType(opaque_ty_id, ..) => { 948 TyKind::OpaqueType(opaque_ty_id, ..) => {
894 match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { 949 match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
@@ -901,10 +956,13 @@ impl Ty {
901 // This is only used by type walking. 956 // This is only used by type walking.
902 // Parameters will be walked outside, and projection predicate is not used. 957 // Parameters will be walked outside, and projection predicate is not used.
903 // So just provide the Future trait. 958 // So just provide the Future trait.
904 let impl_bound = WhereClause::Implemented(TraitRef { 959 let impl_bound = Binders::new(
905 trait_id: to_chalk_trait_id(future_trait), 960 0,
906 substitution: Substitution::empty(), 961 WhereClause::Implemented(TraitRef {
907 }); 962 trait_id: to_chalk_trait_id(future_trait),
963 substitution: Substitution::empty(),
964 }),
965 );
908 Some(vec![impl_bound]) 966 Some(vec![impl_bound])
909 } else { 967 } else {
910 None 968 None
@@ -936,10 +994,19 @@ impl Ty {
936 let param_data = &generic_params.types[id.local_id]; 994 let param_data = &generic_params.types[id.local_id];
937 match param_data.provenance { 995 match param_data.provenance {
938 hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { 996 hir_def::generics::TypeParamProvenance::ArgumentImplTrait => {
997 let substs = Substitution::type_params(db, id.parent);
939 let predicates = db 998 let predicates = db
940 .generic_predicates_for_param(id) 999 .generic_predicates(id.parent)
941 .into_iter() 1000 .into_iter()
942 .map(|pred| pred.value.clone()) 1001 .map(|pred| pred.clone().subst(&substs))
1002 .filter(|wc| match &wc.skip_binders() {
1003 WhereClause::Implemented(tr) => tr.self_type_parameter() == self,
1004 WhereClause::AliasEq(AliasEq {
1005 alias: AliasTy::Projection(proj),
1006 ty: _,
1007 }) => proj.self_type_parameter() == self,
1008 _ => false,
1009 })
943 .collect_vec(); 1010 .collect_vec();
944 1011
945 Some(predicates) 1012 Some(predicates)
@@ -1066,6 +1133,23 @@ pub trait TypeWalk {
1066 DebruijnIndex::INNERMOST, 1133 DebruijnIndex::INNERMOST,
1067 ) 1134 )
1068 } 1135 }
1136
1137 /// Shifts debruijn indices of `TyKind::Bound` vars out (down) by `n`.
1138 fn shift_bound_vars_out(self, n: DebruijnIndex) -> Self
1139 where
1140 Self: Sized + std::fmt::Debug,
1141 {
1142 self.fold_binders(
1143 &mut |ty, binders| match ty.interned(&Interner) {
1144 TyKind::BoundVar(bound) if bound.debruijn >= binders => {
1145 TyKind::BoundVar(bound.shifted_out_to(n).unwrap_or(bound.clone()))
1146 .intern(&Interner)
1147 }
1148 _ => ty,
1149 },
1150 DebruijnIndex::INNERMOST,
1151 )
1152 }
1069} 1153}
1070 1154
1071impl TypeWalk for Ty { 1155impl TypeWalk for Ty {
@@ -1081,8 +1165,8 @@ impl TypeWalk for Ty {
1081 t.walk(f); 1165 t.walk(f);
1082 } 1166 }
1083 } 1167 }
1084 TyKind::Dyn(predicates) => { 1168 TyKind::Dyn(dyn_ty) => {
1085 for p in predicates.iter() { 1169 for p in dyn_ty.bounds.value.interned().iter() {
1086 p.walk(f); 1170 p.walk(f);
1087 } 1171 }
1088 } 1172 }
@@ -1109,8 +1193,8 @@ impl TypeWalk for Ty {
1109 TyKind::Alias(AliasTy::Projection(p_ty)) => { 1193 TyKind::Alias(AliasTy::Projection(p_ty)) => {
1110 p_ty.substitution.walk_mut_binders(f, binders); 1194 p_ty.substitution.walk_mut_binders(f, binders);
1111 } 1195 }
1112 TyKind::Dyn(predicates) => { 1196 TyKind::Dyn(dyn_ty) => {
1113 for p in make_mut_slice(predicates) { 1197 for p in make_mut_slice(&mut dyn_ty.bounds.value.0) {
1114 p.walk_mut_binders(f, binders.shifted_in()); 1198 p.walk_mut_binders(f, binders.shifted_in());
1115 } 1199 }
1116 } 1200 }
@@ -1160,7 +1244,7 @@ pub struct ReturnTypeImplTraits {
1160 1244
1161#[derive(Clone, PartialEq, Eq, Debug, Hash)] 1245#[derive(Clone, PartialEq, Eq, Debug, Hash)]
1162pub(crate) struct ReturnTypeImplTrait { 1246pub(crate) struct ReturnTypeImplTrait {
1163 pub(crate) bounds: Binders<Vec<WhereClause>>, 1247 pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>,
1164} 1248}
1165 1249
1166pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { 1250pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId {
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index cbbb535e5..c87789d45 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -33,9 +33,10 @@ use crate::{
33 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, 33 all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
34 variant_data, 34 variant_data,
35 }, 35 },
36 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, ImplTraitId, 36 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
37 OpaqueTy, PolyFnSig, ProjectionTy, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, 37 ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses,
38 TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, WhereClause, 38 ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty,
39 TyKind, TypeWalk, WhereClause,
39}; 40};
40 41
41#[derive(Debug)] 42#[derive(Debug)]
@@ -188,10 +189,14 @@ impl<'a> TyLoweringContext<'a> {
188 TypeRef::DynTrait(bounds) => { 189 TypeRef::DynTrait(bounds) => {
189 let self_ty = 190 let self_ty =
190 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner); 191 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner);
191 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { 192 let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
192 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone())).collect() 193 QuantifiedWhereClauses::from_iter(
194 &Interner,
195 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
196 )
193 }); 197 });
194 TyKind::Dyn(predicates).intern(&Interner) 198 let bounds = Binders::new(1, bounds);
199 TyKind::Dyn(DynTy { bounds }).intern(&Interner)
195 } 200 }
196 TypeRef::ImplTrait(bounds) => { 201 TypeRef::ImplTrait(bounds) => {
197 match self.impl_trait_mode { 202 match self.impl_trait_mode {
@@ -373,7 +378,16 @@ impl<'a> TyLoweringContext<'a> {
373 // FIXME report error (ambiguous associated type) 378 // FIXME report error (ambiguous associated type)
374 TyKind::Unknown.intern(&Interner) 379 TyKind::Unknown.intern(&Interner)
375 } else { 380 } else {
376 TyKind::Dyn(Arc::new([WhereClause::Implemented(trait_ref)])).intern(&Interner) 381 let dyn_ty = DynTy {
382 bounds: Binders::new(
383 1,
384 QuantifiedWhereClauses::from_iter(
385 &Interner,
386 Some(Binders::wrap_empty(WhereClause::Implemented(trait_ref))),
387 ),
388 ),
389 };
390 TyKind::Dyn(dyn_ty).intern(&Interner)
377 }; 391 };
378 return (ty, None); 392 return (ty, None);
379 } 393 }
@@ -507,7 +521,7 @@ impl<'a> TyLoweringContext<'a> {
507 TyDefId::AdtId(it) => Some(it.into()), 521 TyDefId::AdtId(it) => Some(it.into()),
508 TyDefId::TypeAliasId(it) => Some(it.into()), 522 TyDefId::TypeAliasId(it) => Some(it.into()),
509 }; 523 };
510 let substs = self.substs_from_path_segment(segment, generic_def, infer_args); 524 let substs = self.substs_from_path_segment(segment, generic_def, infer_args, None);
511 self.db.ty(typeable).subst(&substs) 525 self.db.ty(typeable).subst(&substs)
512 } 526 }
513 527
@@ -544,7 +558,7 @@ impl<'a> TyLoweringContext<'a> {
544 (segment, Some(var.parent.into())) 558 (segment, Some(var.parent.into()))
545 } 559 }
546 }; 560 };
547 self.substs_from_path_segment(segment, generic_def, infer_args) 561 self.substs_from_path_segment(segment, generic_def, infer_args, None)
548 } 562 }
549 563
550 fn substs_from_path_segment( 564 fn substs_from_path_segment(
@@ -552,6 +566,7 @@ impl<'a> TyLoweringContext<'a> {
552 segment: PathSegment<'_>, 566 segment: PathSegment<'_>,
553 def_generic: Option<GenericDefId>, 567 def_generic: Option<GenericDefId>,
554 infer_args: bool, 568 infer_args: bool,
569 explicit_self_ty: Option<Ty>,
555 ) -> Substitution { 570 ) -> Substitution {
556 let mut substs = Vec::new(); 571 let mut substs = Vec::new();
557 let def_generics = def_generic.map(|def| generics(self.db.upcast(), def)); 572 let def_generics = def_generic.map(|def| generics(self.db.upcast(), def));
@@ -562,11 +577,19 @@ impl<'a> TyLoweringContext<'a> {
562 577
563 substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(parent_params)); 578 substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(parent_params));
564 579
580 let fill_self_params = || {
581 substs.extend(
582 explicit_self_ty
583 .into_iter()
584 .chain(iter::repeat(TyKind::Unknown.intern(&Interner)))
585 .take(self_params),
586 )
587 };
565 let mut had_explicit_type_args = false; 588 let mut had_explicit_type_args = false;
566 589
567 if let Some(generic_args) = &segment.args_and_bindings { 590 if let Some(generic_args) = &segment.args_and_bindings {
568 if !generic_args.has_self_type { 591 if !generic_args.has_self_type {
569 substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(self_params)); 592 fill_self_params();
570 } 593 }
571 let expected_num = 594 let expected_num =
572 if generic_args.has_self_type { self_params + type_params } else { type_params }; 595 if generic_args.has_self_type { self_params + type_params } else { type_params };
@@ -588,6 +611,8 @@ impl<'a> TyLoweringContext<'a> {
588 GenericArg::Lifetime(_) => {} 611 GenericArg::Lifetime(_) => {}
589 } 612 }
590 } 613 }
614 } else {
615 fill_self_params();
591 } 616 }
592 617
593 // handle defaults. In expression or pattern path segments without 618 // handle defaults. In expression or pattern path segments without
@@ -636,10 +661,7 @@ impl<'a> TyLoweringContext<'a> {
636 segment: PathSegment<'_>, 661 segment: PathSegment<'_>,
637 explicit_self_ty: Option<Ty>, 662 explicit_self_ty: Option<Ty>,
638 ) -> TraitRef { 663 ) -> TraitRef {
639 let mut substs = self.trait_ref_substs_from_path(segment, resolved); 664 let substs = self.trait_ref_substs_from_path(segment, resolved, explicit_self_ty);
640 if let Some(self_ty) = explicit_self_ty {
641 substs.0[0] = self_ty;
642 }
643 TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs } 665 TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
644 } 666 }
645 667
@@ -659,14 +681,16 @@ impl<'a> TyLoweringContext<'a> {
659 &self, 681 &self,
660 segment: PathSegment<'_>, 682 segment: PathSegment<'_>,
661 resolved: TraitId, 683 resolved: TraitId,
684 explicit_self_ty: Option<Ty>,
662 ) -> Substitution { 685 ) -> Substitution {
663 self.substs_from_path_segment(segment, Some(resolved.into()), false) 686 self.substs_from_path_segment(segment, Some(resolved.into()), false, explicit_self_ty)
664 } 687 }
665 688
666 pub(crate) fn lower_where_predicate( 689 pub(crate) fn lower_where_predicate(
667 &'a self, 690 &'a self,
668 where_predicate: &'a WherePredicate, 691 where_predicate: &'a WherePredicate,
669 ) -> impl Iterator<Item = WhereClause> + 'a { 692 ignore_bindings: bool,
693 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
670 match where_predicate { 694 match where_predicate {
671 WherePredicate::ForLifetime { target, bound, .. } 695 WherePredicate::ForLifetime { target, bound, .. }
672 | WherePredicate::TypeBound { target, bound } => { 696 | WherePredicate::TypeBound { target, bound } => {
@@ -688,7 +712,9 @@ impl<'a> TyLoweringContext<'a> {
688 .intern(&Interner) 712 .intern(&Interner)
689 } 713 }
690 }; 714 };
691 self.lower_type_bound(bound, self_ty).collect::<Vec<_>>().into_iter() 715 self.lower_type_bound(bound, self_ty, ignore_bindings)
716 .collect::<Vec<_>>()
717 .into_iter()
692 } 718 }
693 WherePredicate::Lifetime { .. } => vec![].into_iter(), 719 WherePredicate::Lifetime { .. } => vec![].into_iter(),
694 } 720 }
@@ -698,12 +724,13 @@ impl<'a> TyLoweringContext<'a> {
698 &'a self, 724 &'a self,
699 bound: &'a TypeBound, 725 bound: &'a TypeBound,
700 self_ty: Ty, 726 self_ty: Ty,
701 ) -> impl Iterator<Item = WhereClause> + 'a { 727 ignore_bindings: bool,
728 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
702 let mut bindings = None; 729 let mut bindings = None;
703 let trait_ref = match bound { 730 let trait_ref = match bound {
704 TypeBound::Path(path) => { 731 TypeBound::Path(path) => {
705 bindings = self.lower_trait_ref_from_path(path, Some(self_ty)); 732 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
706 bindings.clone().map(WhereClause::Implemented) 733 bindings.clone().map(WhereClause::Implemented).map(|b| Binders::wrap_empty(b))
707 } 734 }
708 TypeBound::Lifetime(_) => None, 735 TypeBound::Lifetime(_) => None,
709 TypeBound::Error => None, 736 TypeBound::Error => None,
@@ -711,6 +738,7 @@ impl<'a> TyLoweringContext<'a> {
711 trait_ref.into_iter().chain( 738 trait_ref.into_iter().chain(
712 bindings 739 bindings
713 .into_iter() 740 .into_iter()
741 .filter(move |_| !ignore_bindings)
714 .flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)), 742 .flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)),
715 ) 743 )
716 } 744 }
@@ -719,7 +747,7 @@ impl<'a> TyLoweringContext<'a> {
719 &'a self, 747 &'a self,
720 bound: &'a TypeBound, 748 bound: &'a TypeBound,
721 trait_ref: TraitRef, 749 trait_ref: TraitRef,
722 ) -> impl Iterator<Item = WhereClause> + 'a { 750 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
723 let last_segment = match bound { 751 let last_segment = match bound {
724 TypeBound::Path(path) => path.segments().last(), 752 TypeBound::Path(path) => path.segments().last(),
725 TypeBound::Error | TypeBound::Lifetime(_) => None, 753 TypeBound::Error | TypeBound::Lifetime(_) => None,
@@ -735,7 +763,7 @@ impl<'a> TyLoweringContext<'a> {
735 &binding.name, 763 &binding.name,
736 ); 764 );
737 let (super_trait_ref, associated_ty) = match found { 765 let (super_trait_ref, associated_ty) = match found {
738 None => return SmallVec::<[WhereClause; 1]>::new(), 766 None => return SmallVec::<[QuantifiedWhereClause; 1]>::new(),
739 Some(t) => t, 767 Some(t) => t,
740 }; 768 };
741 let projection_ty = ProjectionTy { 769 let projection_ty = ProjectionTy {
@@ -749,12 +777,13 @@ impl<'a> TyLoweringContext<'a> {
749 let ty = self.lower_ty(type_ref); 777 let ty = self.lower_ty(type_ref);
750 let alias_eq = 778 let alias_eq =
751 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty }; 779 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
752 preds.push(WhereClause::AliasEq(alias_eq)); 780 preds.push(Binders::wrap_empty(WhereClause::AliasEq(alias_eq)));
753 } 781 }
754 for bound in &binding.bounds { 782 for bound in &binding.bounds {
755 preds.extend(self.lower_type_bound( 783 preds.extend(self.lower_type_bound(
756 bound, 784 bound,
757 TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(&Interner), 785 TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(&Interner),
786 false,
758 )); 787 ));
759 } 788 }
760 preds 789 preds
@@ -766,7 +795,7 @@ impl<'a> TyLoweringContext<'a> {
766 let self_ty = 795 let self_ty =
767 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner); 796 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner);
768 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { 797 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
769 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone())).collect() 798 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)).collect()
770 }); 799 });
771 ReturnTypeImplTrait { bounds: Binders::new(1, predicates) } 800 ReturnTypeImplTrait { bounds: Binders::new(1, predicates) }
772 } 801 }
@@ -799,14 +828,18 @@ pub fn associated_type_shorthand_candidates<R>(
799 let traits_from_env: Vec<_> = match res { 828 let traits_from_env: Vec<_> = match res {
800 TypeNs::SelfType(impl_id) => match db.impl_trait(impl_id) { 829 TypeNs::SelfType(impl_id) => match db.impl_trait(impl_id) {
801 None => vec![], 830 None => vec![],
802 Some(trait_ref) => vec![trait_ref.value], 831 // FIXME: how to correctly handle higher-ranked bounds here?
832 Some(trait_ref) => vec![trait_ref.value.shift_bound_vars_out(DebruijnIndex::ONE)],
803 }, 833 },
804 TypeNs::GenericParam(param_id) => { 834 TypeNs::GenericParam(param_id) => {
805 let predicates = db.generic_predicates_for_param(param_id); 835 let predicates = db.generic_predicates_for_param(param_id);
806 let mut traits_: Vec<_> = predicates 836 let mut traits_: Vec<_> = predicates
807 .iter() 837 .iter()
808 .filter_map(|pred| match &pred.value { 838 .filter_map(|pred| match &pred.value.value {
809 WhereClause::Implemented(tr) => Some(tr.clone()), 839 // FIXME: how to correctly handle higher-ranked bounds here?
840 WhereClause::Implemented(tr) => {
841 Some(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE))
842 }
810 _ => None, 843 _ => None,
811 }) 844 })
812 .collect(); 845 .collect();
@@ -878,7 +911,7 @@ pub(crate) fn field_types_query(
878pub(crate) fn generic_predicates_for_param_query( 911pub(crate) fn generic_predicates_for_param_query(
879 db: &dyn HirDatabase, 912 db: &dyn HirDatabase,
880 param_id: TypeParamId, 913 param_id: TypeParamId,
881) -> Arc<[Binders<WhereClause>]> { 914) -> Arc<[Binders<QuantifiedWhereClause>]> {
882 let resolver = param_id.parent.resolver(db.upcast()); 915 let resolver = param_id.parent.resolver(db.upcast());
883 let ctx = 916 let ctx =
884 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 917 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
@@ -896,7 +929,9 @@ pub(crate) fn generic_predicates_for_param_query(
896 }, 929 },
897 WherePredicate::Lifetime { .. } => false, 930 WherePredicate::Lifetime { .. } => false,
898 }) 931 })
899 .flat_map(|pred| ctx.lower_where_predicate(pred).map(|p| Binders::new(generics.len(), p))) 932 .flat_map(|pred| {
933 ctx.lower_where_predicate(pred, true).map(|p| Binders::new(generics.len(), p))
934 })
900 .collect() 935 .collect()
901} 936}
902 937
@@ -904,7 +939,7 @@ pub(crate) fn generic_predicates_for_param_recover(
904 _db: &dyn HirDatabase, 939 _db: &dyn HirDatabase,
905 _cycle: &[String], 940 _cycle: &[String],
906 _param_id: &TypeParamId, 941 _param_id: &TypeParamId,
907) -> Arc<[Binders<WhereClause>]> { 942) -> Arc<[Binders<QuantifiedWhereClause>]> {
908 Arc::new([]) 943 Arc::new([])
909} 944}
910 945
@@ -918,8 +953,8 @@ pub(crate) fn trait_environment_query(
918 let mut traits_in_scope = Vec::new(); 953 let mut traits_in_scope = Vec::new();
919 let mut clauses = Vec::new(); 954 let mut clauses = Vec::new();
920 for pred in resolver.where_predicates_in_scope() { 955 for pred in resolver.where_predicates_in_scope() {
921 for pred in ctx.lower_where_predicate(pred) { 956 for pred in ctx.lower_where_predicate(pred, false) {
922 if let WhereClause::Implemented(tr) = &pred { 957 if let WhereClause::Implemented(tr) = &pred.skip_binders() {
923 traits_in_scope.push((tr.self_type_parameter().clone(), tr.hir_trait_id())); 958 traits_in_scope.push((tr.self_type_parameter().clone(), tr.hir_trait_id()));
924 } 959 }
925 let program_clause: chalk_ir::ProgramClause<Interner> = 960 let program_clause: chalk_ir::ProgramClause<Interner> =
@@ -946,8 +981,7 @@ pub(crate) fn trait_environment_query(
946 let substs = Substitution::type_params(db, trait_id); 981 let substs = Substitution::type_params(db, trait_id);
947 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs }; 982 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
948 let pred = WhereClause::Implemented(trait_ref); 983 let pred = WhereClause::Implemented(trait_ref);
949 let program_clause: chalk_ir::ProgramClause<Interner> = 984 let program_clause: chalk_ir::ProgramClause<Interner> = pred.to_chalk(db).cast(&Interner);
950 pred.clone().to_chalk(db).cast(&Interner);
951 clauses.push(program_clause.into_from_env_clause(&Interner)); 985 clauses.push(program_clause.into_from_env_clause(&Interner));
952 } 986 }
953 987
@@ -960,14 +994,16 @@ pub(crate) fn trait_environment_query(
960pub(crate) fn generic_predicates_query( 994pub(crate) fn generic_predicates_query(
961 db: &dyn HirDatabase, 995 db: &dyn HirDatabase,
962 def: GenericDefId, 996 def: GenericDefId,
963) -> Arc<[Binders<WhereClause>]> { 997) -> Arc<[Binders<QuantifiedWhereClause>]> {
964 let resolver = def.resolver(db.upcast()); 998 let resolver = def.resolver(db.upcast());
965 let ctx = 999 let ctx =
966 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1000 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
967 let generics = generics(db.upcast(), def); 1001 let generics = generics(db.upcast(), def);
968 resolver 1002 resolver
969 .where_predicates_in_scope() 1003 .where_predicates_in_scope()
970 .flat_map(|pred| ctx.lower_where_predicate(pred).map(|p| Binders::new(generics.len(), p))) 1004 .flat_map(|pred| {
1005 ctx.lower_where_predicate(pred, false).map(|p| Binders::new(generics.len(), p))
1006 })
971 .collect() 1007 .collect()
972} 1008}
973 1009
@@ -1124,10 +1160,9 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1124 if db.type_alias_data(t).is_extern { 1160 if db.type_alias_data(t).is_extern {
1125 Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner)) 1161 Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner))
1126 } else { 1162 } else {
1127 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST);
1128 let type_ref = &db.type_alias_data(t).type_ref; 1163 let type_ref = &db.type_alias_data(t).type_ref;
1129 let inner = ctx.lower_ty(type_ref.as_ref().unwrap_or(&TypeRef::Error)); 1164 let inner = ctx.lower_ty(type_ref.as_ref().unwrap_or(&TypeRef::Error));
1130 Binders::new(substs.len(), inner) 1165 Binders::new(generics.len(), inner)
1131 } 1166 }
1132} 1167}
1133 1168
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 54192ec30..84d9a1e18 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -6,7 +6,7 @@ use std::{iter, sync::Arc};
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use base_db::CrateId; 8use base_db::CrateId;
9use chalk_ir::{cast::Cast, Mutability}; 9use chalk_ir::{cast::Cast, Mutability, UniverseIndex};
10use hir_def::{ 10use hir_def::{
11 lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, 11 lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule,
12 ImplId, Lookup, ModuleId, TraitId, 12 ImplId, Lookup, ModuleId, TraitId,
@@ -21,8 +21,9 @@ use crate::{
21 primitive::{self, FloatTy, IntTy, UintTy}, 21 primitive::{self, FloatTy, IntTy, UintTy},
22 to_chalk_trait_id, 22 to_chalk_trait_id,
23 utils::all_super_traits, 23 utils::all_super_traits,
24 AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, ForeignDefId, InEnvironment, Interner, 24 AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId,
25 Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, 25 InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind,
26 TypeWalk,
26}; 27};
27 28
28/// This is used as a key for indexing impls. 29/// This is used as a key for indexing impls.
@@ -380,7 +381,7 @@ fn iterate_method_candidates_impl(
380 // Also note that when we've got a receiver like &S, even if the method we 381 // Also note that when we've got a receiver like &S, even if the method we
381 // find in the end takes &self, we still do the autoderef step (just as 382 // find in the end takes &self, we still do the autoderef step (just as
382 // rustc does an autoderef and then autoref again). 383 // rustc does an autoderef and then autoref again).
383 let ty = InEnvironment { value: ty.clone(), environment: env.clone() }; 384 let ty = InEnvironment { goal: ty.clone(), environment: env.env.clone() };
384 385
385 // We have to be careful about the order we're looking at candidates 386 // We have to be careful about the order we're looking at candidates
386 // in here. Consider the case where we're resolving `x.clone()` 387 // in here. Consider the case where we're resolving `x.clone()`
@@ -452,7 +453,7 @@ fn iterate_method_candidates_with_autoref(
452 return true; 453 return true;
453 } 454 }
454 let refed = Canonical { 455 let refed = Canonical {
455 kinds: deref_chain[0].kinds.clone(), 456 binders: deref_chain[0].binders.clone(),
456 value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner), 457 value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner),
457 }; 458 };
458 if iterate_method_candidates_by_receiver( 459 if iterate_method_candidates_by_receiver(
@@ -469,7 +470,7 @@ fn iterate_method_candidates_with_autoref(
469 return true; 470 return true;
470 } 471 }
471 let ref_muted = Canonical { 472 let ref_muted = Canonical {
472 kinds: deref_chain[0].kinds.clone(), 473 binders: deref_chain[0].binders.clone(),
473 value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner), 474 value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner),
474 }; 475 };
475 if iterate_method_candidates_by_receiver( 476 if iterate_method_candidates_by_receiver(
@@ -646,7 +647,7 @@ pub fn resolve_indexing_op(
646 krate: CrateId, 647 krate: CrateId,
647 index_trait: TraitId, 648 index_trait: TraitId,
648) -> Option<Canonical<Ty>> { 649) -> Option<Canonical<Ty>> {
649 let ty = InEnvironment { value: ty.clone(), environment: env.clone() }; 650 let ty = InEnvironment { goal: ty.clone(), environment: env.env.clone() };
650 let deref_chain = autoderef_method_receiver(db, krate, ty); 651 let deref_chain = autoderef_method_receiver(db, krate, ty);
651 for ty in deref_chain { 652 for ty in deref_chain {
652 let goal = generic_implements_goal(db, env.clone(), index_trait, ty.clone()); 653 let goal = generic_implements_goal(db, env.clone(), index_trait, ty.clone());
@@ -710,19 +711,28 @@ pub(crate) fn inherent_impl_substs(
710 // we create a var for each type parameter of the impl; we need to keep in 711 // we create a var for each type parameter of the impl; we need to keep in
711 // mind here that `self_ty` might have vars of its own 712 // mind here that `self_ty` might have vars of its own
712 let vars = Substitution::build_for_def(db, impl_id) 713 let vars = Substitution::build_for_def(db, impl_id)
713 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.kinds.len()) 714 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner))
714 .build(); 715 .build();
715 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); 716 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars);
716 let mut kinds = self_ty.kinds.to_vec(); 717 let mut kinds = self_ty.binders.interned().to_vec();
717 kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(vars.len())); 718 kinds.extend(
718 let tys = Canonical { kinds: kinds.into(), value: (self_ty_with_vars, self_ty.value.clone()) }; 719 iter::repeat(chalk_ir::WithKind::new(
720 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
721 UniverseIndex::ROOT,
722 ))
723 .take(vars.len()),
724 );
725 let tys = Canonical {
726 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
727 value: (self_ty_with_vars, self_ty.value.clone()),
728 };
719 let substs = super::infer::unify(&tys); 729 let substs = super::infer::unify(&tys);
720 // We only want the substs for the vars we added, not the ones from self_ty. 730 // We only want the substs for the vars we added, not the ones from self_ty.
721 // Also, if any of the vars we added are still in there, we replace them by 731 // Also, if any of the vars we added are still in there, we replace them by
722 // Unknown. I think this can only really happen if self_ty contained 732 // Unknown. I think this can only really happen if self_ty contained
723 // Unknown, and in that case we want the result to contain Unknown in those 733 // Unknown, and in that case we want the result to contain Unknown in those
724 // places again. 734 // places again.
725 substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.kinds.len())) 735 substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.binders.len(&Interner)))
726} 736}
727 737
728/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past 738/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
@@ -801,15 +811,24 @@ fn generic_implements_goal(
801 trait_: TraitId, 811 trait_: TraitId,
802 self_ty: Canonical<Ty>, 812 self_ty: Canonical<Ty>,
803) -> Canonical<InEnvironment<super::DomainGoal>> { 813) -> Canonical<InEnvironment<super::DomainGoal>> {
804 let mut kinds = self_ty.kinds.to_vec(); 814 let mut kinds = self_ty.binders.interned().to_vec();
805 let substs = super::Substitution::build_for_def(db, trait_) 815 let substs = super::Substitution::build_for_def(db, trait_)
806 .push(self_ty.value) 816 .push(self_ty.value)
807 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) 817 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
808 .build(); 818 .build();
809 kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(substs.len() - 1)); 819 kinds.extend(
820 iter::repeat(chalk_ir::WithKind::new(
821 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
822 UniverseIndex::ROOT,
823 ))
824 .take(substs.len() - 1),
825 );
810 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }; 826 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
811 let obligation = trait_ref.cast(&Interner); 827 let obligation = trait_ref.cast(&Interner);
812 Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) } 828 Canonical {
829 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
830 value: InEnvironment::new(env.env.clone(), obligation),
831 }
813} 832}
814 833
815fn autoderef_method_receiver( 834fn autoderef_method_receiver(
@@ -822,9 +841,9 @@ fn autoderef_method_receiver(
822 if let Some(TyKind::Array(parameters)) = 841 if let Some(TyKind::Array(parameters)) =
823 deref_chain.last().map(|ty| ty.value.interned(&Interner)) 842 deref_chain.last().map(|ty| ty.value.interned(&Interner))
824 { 843 {
825 let kinds = deref_chain.last().unwrap().kinds.clone(); 844 let kinds = deref_chain.last().unwrap().binders.clone();
826 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); 845 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner);
827 deref_chain.push(Canonical { value: unsized_ty, kinds }) 846 deref_chain.push(Canonical { value: unsized_ty, binders: kinds })
828 } 847 }
829 deref_chain 848 deref_chain
830} 849}
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs
index 0a4141e69..ad283c1e0 100644
--- a/crates/hir_ty/src/tests.rs
+++ b/crates/hir_ty/src/tests.rs
@@ -369,3 +369,72 @@ fn check_infer_with_mismatches(ra_fixture: &str, expect: Expect) {
369 actual.push('\n'); 369 actual.push('\n');
370 expect.assert_eq(&actual); 370 expect.assert_eq(&actual);
371} 371}
372
373#[test]
374fn salsa_bug() {
375 let (mut db, pos) = TestDB::with_position(
376 "
377 //- /lib.rs
378 trait Index {
379 type Output;
380 }
381
382 type Key<S: UnificationStoreBase> = <S as UnificationStoreBase>::Key;
383
384 pub trait UnificationStoreBase: Index<Output = Key<Self>> {
385 type Key;
386
387 fn len(&self) -> usize;
388 }
389
390 pub trait UnificationStoreMut: UnificationStoreBase {
391 fn push(&mut self, value: Self::Key);
392 }
393
394 fn main() {
395 let x = 1;
396 x.push(1);$0
397 }
398 ",
399 );
400
401 let module = db.module_for_file(pos.file_id);
402 let crate_def_map = module.def_map(&db);
403 visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
404 db.infer(def);
405 });
406
407 let new_text = "
408 //- /lib.rs
409 trait Index {
410 type Output;
411 }
412
413 type Key<S: UnificationStoreBase> = <S as UnificationStoreBase>::Key;
414
415 pub trait UnificationStoreBase: Index<Output = Key<Self>> {
416 type Key;
417
418 fn len(&self) -> usize;
419 }
420
421 pub trait UnificationStoreMut: UnificationStoreBase {
422 fn push(&mut self, value: Self::Key);
423 }
424
425 fn main() {
426
427 let x = 1;
428 x.push(1);
429 }
430 "
431 .to_string();
432
433 db.set_file_text(pos.file_id, Arc::new(new_text));
434
435 let module = db.module_for_file(pos.file_id);
436 let crate_def_map = module.def_map(&db);
437 visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
438 db.infer(def);
439 });
440}
diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs
index 88ba9b118..7eda51866 100644
--- a/crates/hir_ty/src/tests/macros.rs
+++ b/crates/hir_ty/src/tests/macros.rs
@@ -607,6 +607,29 @@ fn bar() -> u32 {0}
607} 607}
608 608
609#[test] 609#[test]
610fn infer_builtin_macros_include_child_mod() {
611 check_types(
612 r#"
613//- /main.rs
614#[rustc_builtin_macro]
615macro_rules! include {() => {}}
616
617include!("f/foo.rs");
618
619fn main() {
620 bar::bar();
621} //^ u32
622
623//- /f/foo.rs
624pub mod bar;
625
626//- /f/bar.rs
627pub fn bar() -> u32 {0}
628"#,
629 );
630}
631
632#[test]
610fn infer_builtin_macros_include_str() { 633fn infer_builtin_macros_include_str() {
611 check_types( 634 check_types(
612 r#" 635 r#"
diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs
index 5da19ba5f..85a28e76b 100644
--- a/crates/hir_ty/src/tests/patterns.rs
+++ b/crates/hir_ty/src/tests/patterns.rs
@@ -658,6 +658,28 @@ fn slice_tail_pattern() {
658fn box_pattern() { 658fn box_pattern() {
659 check_infer( 659 check_infer(
660 r#" 660 r#"
661 pub struct Global;
662 #[lang = "owned_box"]
663 pub struct Box<T, A = Global>(T);
664
665 fn foo(params: Box<i32>) {
666 match params {
667 box integer => {}
668 }
669 }
670 "#,
671 expect![[r#"
672 83..89 'params': Box<i32, Global>
673 101..155 '{ ... } }': ()
674 107..153 'match ... }': ()
675 113..119 'params': Box<i32, Global>
676 130..141 'box integer': Box<i32, Global>
677 134..141 'integer': i32
678 145..147 '{}': ()
679 "#]],
680 );
681 check_infer(
682 r#"
661 #[lang = "owned_box"] 683 #[lang = "owned_box"]
662 pub struct Box<T>(T); 684 pub struct Box<T>(T);
663 685
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs
index 69314e245..b69f86050 100644
--- a/crates/hir_ty/src/tests/regression.rs
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -961,3 +961,16 @@ fn issue_6852() {
961 "#]], 961 "#]],
962 ); 962 );
963} 963}
964
965#[test]
966fn param_overrides_fn() {
967 check_types(
968 r#"
969 fn example(example: i32) {
970 fn f() {}
971 example;
972 //^^^^^^^ i32
973 }
974 "#,
975 )
976}
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index f7ee6def6..2ba97f814 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -2272,6 +2272,56 @@ fn test<T, U>() where T: Trait<U::Item>, U: Trait<T::Item> {
2272} 2272}
2273 2273
2274#[test] 2274#[test]
2275fn unselected_projection_in_trait_env_cycle_3() {
2276 // this is a cycle for rustc; we currently accept it
2277 check_types(
2278 r#"
2279//- /main.rs
2280trait Trait {
2281 type Item;
2282 type OtherItem;
2283}
2284
2285fn test<T>() where T: Trait<OtherItem = T::Item> {
2286 let x: T::Item = no_matter;
2287} //^ Trait::Item<T>
2288"#,
2289 );
2290}
2291
2292#[test]
2293fn unselected_projection_in_trait_env_no_cycle() {
2294 // this is not a cycle
2295 check_types(
2296 r#"
2297//- /main.rs
2298trait Index {
2299 type Output;
2300}
2301
2302type Key<S: UnificationStoreBase> = <S as UnificationStoreBase>::Key;
2303
2304pub trait UnificationStoreBase: Index<Output = Key<Self>> {
2305 type Key;
2306
2307 fn len(&self) -> usize;
2308}
2309
2310pub trait UnificationStoreMut: UnificationStoreBase {
2311 fn push(&mut self, value: Self::Key);
2312}
2313
2314fn test<T>(t: T) where T: UnificationStoreMut {
2315 let x;
2316 t.push(x);
2317 let y: Key<T>;
2318 (x, y);
2319} //^ (UnificationStoreBase::Key<T>, UnificationStoreBase::Key<T>)
2320"#,
2321 );
2322}
2323
2324#[test]
2275fn inline_assoc_type_bounds_1() { 2325fn inline_assoc_type_bounds_1() {
2276 check_types( 2326 check_types(
2277 r#" 2327 r#"
@@ -3274,3 +3324,49 @@ fn f() {
3274 "#]], 3324 "#]],
3275 ) 3325 )
3276} 3326}
3327
3328#[test]
3329fn infer_default_trait_type_parameter() {
3330 check_infer(
3331 r#"
3332struct A;
3333
3334trait Op<RHS=Self> {
3335 type Output;
3336
3337 fn do_op(self, rhs: RHS) -> Self::Output;
3338}
3339
3340impl Op for A {
3341 type Output = bool;
3342
3343 fn do_op(self, rhs: Self) -> Self::Output {
3344 true
3345 }
3346}
3347
3348fn test() {
3349 let x = A;
3350 let y = A;
3351 let r = x.do_op(y);
3352}
3353 "#,
3354 expect![[r#"
3355 63..67 'self': Self
3356 69..72 'rhs': RHS
3357 153..157 'self': A
3358 159..162 'rhs': A
3359 186..206 '{ ... }': bool
3360 196..200 'true': bool
3361 220..277 '{ ...(y); }': ()
3362 230..231 'x': A
3363 234..235 'A': A
3364 245..246 'y': A
3365 249..250 'A': A
3366 260..261 'r': bool
3367 264..265 'x': A
3368 264..274 'x.do_op(y)': bool
3369 272..273 'y': A
3370 "#]],
3371 )
3372}
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index 7dadd1ffb..ccee0e5ad 100644
--- a/crates/hir_ty/src/traits.rs
+++ b/crates/hir_ty/src/traits.rs
@@ -1,6 +1,5 @@
1//! Trait solving using Chalk. 1//! Trait solving using Chalk.
2use std::env::var; 2use std::env::var;
3use std::sync::Arc;
4 3
5use base_db::CrateId; 4use base_db::CrateId;
6use chalk_ir::cast::Cast; 5use chalk_ir::cast::Cast;
@@ -44,7 +43,7 @@ pub struct TraitEnvironment {
44 // When we're using Chalk's Ty we can make this a BTreeMap since it's Ord, 43 // When we're using Chalk's Ty we can make this a BTreeMap since it's Ord,
45 // but for now it's too annoying... 44 // but for now it's too annoying...
46 pub(crate) traits_from_clauses: Vec<(Ty, TraitId)>, 45 pub(crate) traits_from_clauses: Vec<(Ty, TraitId)>,
47 pub(crate) env: chalk_ir::Environment<Interner>, 46 pub env: chalk_ir::Environment<Interner>,
48} 47}
49 48
50impl TraitEnvironment { 49impl TraitEnvironment {
@@ -74,13 +73,13 @@ impl Default for TraitEnvironment {
74/// Something (usually a goal), along with an environment. 73/// Something (usually a goal), along with an environment.
75#[derive(Clone, Debug, PartialEq, Eq, Hash)] 74#[derive(Clone, Debug, PartialEq, Eq, Hash)]
76pub struct InEnvironment<T> { 75pub struct InEnvironment<T> {
77 pub environment: Arc<TraitEnvironment>, 76 pub environment: chalk_ir::Environment<Interner>,
78 pub value: T, 77 pub goal: T,
79} 78}
80 79
81impl<T> InEnvironment<T> { 80impl<T> InEnvironment<T> {
82 pub fn new(environment: Arc<TraitEnvironment>, value: T) -> InEnvironment<T> { 81 pub fn new(environment: chalk_ir::Environment<Interner>, value: T) -> InEnvironment<T> {
83 InEnvironment { environment, value } 82 InEnvironment { environment, goal: value }
84 } 83 }
85} 84}
86 85
@@ -126,18 +125,18 @@ pub(crate) fn trait_solve_query(
126 krate: CrateId, 125 krate: CrateId,
127 goal: Canonical<InEnvironment<DomainGoal>>, 126 goal: Canonical<InEnvironment<DomainGoal>>,
128) -> Option<Solution> { 127) -> Option<Solution> {
129 let _p = profile::span("trait_solve_query").detail(|| match &goal.value.value { 128 let _p = profile::span("trait_solve_query").detail(|| match &goal.value.goal {
130 DomainGoal::Holds(WhereClause::Implemented(it)) => { 129 DomainGoal::Holds(WhereClause::Implemented(it)) => {
131 db.trait_data(it.hir_trait_id()).name.to_string() 130 db.trait_data(it.hir_trait_id()).name.to_string()
132 } 131 }
133 DomainGoal::Holds(WhereClause::AliasEq(_)) => "alias_eq".to_string(), 132 DomainGoal::Holds(WhereClause::AliasEq(_)) => "alias_eq".to_string(),
134 }); 133 });
135 log::info!("trait_solve_query({})", goal.value.value.display(db)); 134 log::info!("trait_solve_query({})", goal.value.goal.display(db));
136 135
137 if let DomainGoal::Holds(WhereClause::AliasEq(AliasEq { 136 if let DomainGoal::Holds(WhereClause::AliasEq(AliasEq {
138 alias: AliasTy::Projection(projection_ty), 137 alias: AliasTy::Projection(projection_ty),
139 .. 138 ..
140 })) = &goal.value.value 139 })) = &goal.value.goal
141 { 140 {
142 if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) { 141 if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) {
143 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible 142 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index 734679414..011bef6f6 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -21,8 +21,8 @@ use crate::{
21 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, 21 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
22 to_assoc_type_id, to_chalk_trait_id, 22 to_assoc_type_id, to_chalk_trait_id,
23 utils::generics, 23 utils::generics,
24 AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, ProjectionTy, 24 AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, ProjectionTy, Substitution,
25 Substitution, TraitRef, Ty, TyKind, WhereClause, 25 TraitRef, Ty, TyKind, WhereClause,
26}; 26};
27use mapping::{ 27use mapping::{
28 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, 28 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
@@ -238,7 +238,10 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
238 }); 238 });
239 let bound = OpaqueTyDatumBound { 239 let bound = OpaqueTyDatumBound {
240 bounds: make_binders( 240 bounds: make_binders(
241 vec![impl_bound.to_chalk(self.db), proj_bound.to_chalk(self.db)], 241 vec![
242 wrap_in_empty_binders(impl_bound).to_chalk(self.db),
243 wrap_in_empty_binders(proj_bound).to_chalk(self.db),
244 ],
242 1, 245 1,
243 ), 246 ),
244 where_clauses: make_binders(vec![], 0), 247 where_clauses: make_binders(vec![], 0),
@@ -285,9 +288,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
285 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> { 288 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> {
286 let sig_ty: Ty = 289 let sig_ty: Ty =
287 from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone()); 290 from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone());
288 let sig = CallableSig::from_substs( 291 let sig = &sig_ty.callable_sig(self.db).expect("first closure param should be fn ptr");
289 &sig_ty.substs().expect("first closure param should be fn ptr"),
290 );
291 let io = rust_ir::FnDefInputsAndOutputDatum { 292 let io = rust_ir::FnDefInputsAndOutputDatum {
292 argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(), 293 argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(),
293 return_type: sig.ret().clone().to_chalk(self.db), 294 return_type: sig.ret().clone().to_chalk(self.db),
@@ -395,9 +396,8 @@ pub(crate) fn associated_ty_data_query(
395 let bounds = type_alias_data 396 let bounds = type_alias_data
396 .bounds 397 .bounds
397 .iter() 398 .iter()
398 .flat_map(|bound| ctx.lower_type_bound(bound, self_ty.clone())) 399 .flat_map(|bound| ctx.lower_type_bound(bound, self_ty.clone(), false))
399 .filter_map(|pred| generic_predicate_to_inline_bound(db, &pred, &self_ty)) 400 .filter_map(|pred| generic_predicate_to_inline_bound(db, &pred, &self_ty))
400 .map(|bound| make_binders(bound.shifted_in(&Interner), 0))
401 .collect(); 401 .collect();
402 402
403 let where_clauses = convert_where_clauses(db, type_alias.into(), &bound_vars); 403 let where_clauses = convert_where_clauses(db, type_alias.into(), &bound_vars);
@@ -720,3 +720,7 @@ impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> {
720 chalk_ir::ClosureId(id.as_intern_id()) 720 chalk_ir::ClosureId(id.as_intern_id())
721 } 721 }
722} 722}
723
724fn wrap_in_empty_binders<T: crate::TypeWalk>(value: T) -> crate::Binders<T> {
725 crate::Binders::wrap_empty(value)
726}
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index 65feb82e5..aef6b8a15 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -7,15 +7,14 @@ use chalk_ir::{cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeDa
7use chalk_solve::rust_ir; 7use chalk_solve::rust_ir;
8 8
9use base_db::salsa::InternKey; 9use base_db::salsa::InternKey;
10use hir_def::{AssocContainerId, GenericDefId, Lookup, TypeAliasId}; 10use hir_def::{GenericDefId, TypeAliasId};
11 11
12use crate::{ 12use crate::{
13 db::HirDatabase, 13 db::HirDatabase,
14 from_assoc_type_id,
15 primitive::UintTy, 14 primitive::UintTy,
16 traits::{Canonical, DomainGoal}, 15 traits::{Canonical, DomainGoal},
17 AliasTy, CallableDefId, FnPointer, InEnvironment, OpaqueTy, ProjectionTy, Scalar, Substitution, 16 AliasTy, CallableDefId, FnPointer, InEnvironment, OpaqueTy, ProjectionTy,
18 TraitRef, Ty, WhereClause, 17 QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TypeWalk, WhereClause,
19}; 18};
20 19
21use super::interner::*; 20use super::interner::*;
@@ -95,10 +94,10 @@ impl ToChalk for Ty {
95 TyKind::Placeholder(idx) => idx.to_ty::<Interner>(&Interner), 94 TyKind::Placeholder(idx) => idx.to_ty::<Interner>(&Interner),
96 TyKind::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner), 95 TyKind::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner),
97 TyKind::InferenceVar(..) => panic!("uncanonicalized infer ty"), 96 TyKind::InferenceVar(..) => panic!("uncanonicalized infer ty"),
98 TyKind::Dyn(predicates) => { 97 TyKind::Dyn(dyn_ty) => {
99 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( 98 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
100 &Interner, 99 &Interner,
101 predicates.iter().cloned().map(|p| p.to_chalk(db)), 100 dyn_ty.bounds.value.interned().iter().cloned().map(|p| p.to_chalk(db)),
102 ); 101 );
103 let bounded_ty = chalk_ir::DynTy { 102 let bounded_ty = chalk_ir::DynTy {
104 bounds: make_binders(where_clauses, 1), 103 bounds: make_binders(where_clauses, 1),
@@ -144,13 +143,17 @@ impl ToChalk for Ty {
144 chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Unknown, 143 chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Unknown,
145 chalk_ir::TyKind::Dyn(where_clauses) => { 144 chalk_ir::TyKind::Dyn(where_clauses) => {
146 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1); 145 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1);
147 let predicates = where_clauses 146 let bounds = where_clauses
148 .bounds 147 .bounds
149 .skip_binders() 148 .skip_binders()
150 .iter(&Interner) 149 .iter(&Interner)
151 .map(|c| from_chalk(db, c.clone())) 150 .map(|c| from_chalk(db, c.clone()));
152 .collect(); 151 TyKind::Dyn(crate::DynTy {
153 TyKind::Dyn(predicates) 152 bounds: crate::Binders::new(
153 1,
154 crate::QuantifiedWhereClauses::from_iter(&Interner, bounds),
155 ),
156 })
154 } 157 }
155 158
156 chalk_ir::TyKind::Adt(adt_id, subst) => TyKind::Adt(adt_id, from_chalk(db, subst)), 159 chalk_ir::TyKind::Adt(adt_id, subst) => TyKind::Adt(adt_id, from_chalk(db, subst)),
@@ -305,33 +308,22 @@ impl ToChalk for TypeAliasAsValue {
305} 308}
306 309
307impl ToChalk for WhereClause { 310impl ToChalk for WhereClause {
308 type Chalk = chalk_ir::QuantifiedWhereClause<Interner>; 311 type Chalk = chalk_ir::WhereClause<Interner>;
309 312
310 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::QuantifiedWhereClause<Interner> { 313 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::WhereClause<Interner> {
311 match self { 314 match self {
312 WhereClause::Implemented(trait_ref) => { 315 WhereClause::Implemented(trait_ref) => {
313 let chalk_trait_ref = trait_ref.to_chalk(db); 316 chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db))
314 let chalk_trait_ref = chalk_trait_ref.shifted_in(&Interner);
315 make_binders(chalk_ir::WhereClause::Implemented(chalk_trait_ref), 0)
316 } 317 }
317 WhereClause::AliasEq(alias_eq) => make_binders( 318 WhereClause::AliasEq(alias_eq) => chalk_ir::WhereClause::AliasEq(alias_eq.to_chalk(db)),
318 chalk_ir::WhereClause::AliasEq(alias_eq.to_chalk(db).shifted_in(&Interner)),
319 0,
320 ),
321 } 319 }
322 } 320 }
323 321
324 fn from_chalk( 322 fn from_chalk(
325 db: &dyn HirDatabase, 323 db: &dyn HirDatabase,
326 where_clause: chalk_ir::QuantifiedWhereClause<Interner>, 324 where_clause: chalk_ir::WhereClause<Interner>,
327 ) -> WhereClause { 325 ) -> WhereClause {
328 // we don't produce any where clauses with binders and can't currently deal with them 326 match where_clause {
329 match where_clause
330 .skip_binders()
331 .clone()
332 .shifted_out(&Interner)
333 .expect("unexpected bound vars in where clause")
334 {
335 chalk_ir::WhereClause::Implemented(tr) => WhereClause::Implemented(from_chalk(db, tr)), 327 chalk_ir::WhereClause::Implemented(tr) => WhereClause::Implemented(from_chalk(db, tr)),
336 chalk_ir::WhereClause::AliasEq(alias_eq) => { 328 chalk_ir::WhereClause::AliasEq(alias_eq) => {
337 WhereClause::AliasEq(from_chalk(db, alias_eq)) 329 WhereClause::AliasEq(from_chalk(db, alias_eq))
@@ -447,35 +439,12 @@ where
447 type Chalk = chalk_ir::Canonical<T::Chalk>; 439 type Chalk = chalk_ir::Canonical<T::Chalk>;
448 440
449 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> { 441 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> {
450 let kinds = self.kinds.iter().map(|&tk| {
451 chalk_ir::CanonicalVarKind::new(
452 chalk_ir::VariableKind::Ty(tk),
453 chalk_ir::UniverseIndex::ROOT,
454 )
455 });
456 let value = self.value.to_chalk(db); 442 let value = self.value.to_chalk(db);
457 chalk_ir::Canonical { 443 chalk_ir::Canonical { value, binders: self.binders }
458 value,
459 binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds),
460 }
461 } 444 }
462 445
463 fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> { 446 fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> {
464 let kinds = canonical 447 Canonical { binders: canonical.binders, value: from_chalk(db, canonical.value) }
465 .binders
466 .iter(&Interner)
467 .map(|k| match k.kind {
468 chalk_ir::VariableKind::Ty(tk) => tk,
469 // HACK: Chalk can sometimes return new lifetime variables. We
470 // want to just skip them, but to not mess up the indices of
471 // other variables, we'll just create a new type variable in
472 // their place instead. This should not matter (we never see the
473 // actual *uses* of the lifetime variable).
474 chalk_ir::VariableKind::Lifetime => chalk_ir::TyVariableKind::General,
475 chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"),
476 })
477 .collect();
478 Canonical { kinds, value: from_chalk(db, canonical.value) }
479 } 448 }
480} 449}
481 450
@@ -486,10 +455,7 @@ where
486 type Chalk = chalk_ir::InEnvironment<T::Chalk>; 455 type Chalk = chalk_ir::InEnvironment<T::Chalk>;
487 456
488 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> { 457 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> {
489 chalk_ir::InEnvironment { 458 chalk_ir::InEnvironment { environment: self.environment, goal: self.goal.to_chalk(db) }
490 environment: self.environment.env.clone(),
491 goal: self.value.to_chalk(db),
492 }
493 } 459 }
494 460
495 fn from_chalk( 461 fn from_chalk(
@@ -500,6 +466,29 @@ where
500 } 466 }
501} 467}
502 468
469impl<T: ToChalk> ToChalk for crate::Binders<T>
470where
471 T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>,
472{
473 type Chalk = chalk_ir::Binders<T::Chalk>;
474
475 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Binders<T::Chalk> {
476 chalk_ir::Binders::new(
477 chalk_ir::VariableKinds::from_iter(
478 &Interner,
479 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
480 .take(self.num_binders),
481 ),
482 self.value.to_chalk(db),
483 )
484 }
485
486 fn from_chalk(db: &dyn HirDatabase, binders: chalk_ir::Binders<T::Chalk>) -> crate::Binders<T> {
487 let (v, b) = binders.into_value_and_skipped_binders();
488 crate::Binders::new(b.len(&Interner), from_chalk(db, v))
489 }
490}
491
503pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> 492pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T>
504where 493where
505 T: HasInterner<Interner = Interner>, 494 T: HasInterner<Interner = Interner>,
@@ -529,14 +518,15 @@ pub(super) fn convert_where_clauses(
529 518
530pub(super) fn generic_predicate_to_inline_bound( 519pub(super) fn generic_predicate_to_inline_bound(
531 db: &dyn HirDatabase, 520 db: &dyn HirDatabase,
532 pred: &WhereClause, 521 pred: &QuantifiedWhereClause,
533 self_ty: &Ty, 522 self_ty: &Ty,
534) -> Option<rust_ir::InlineBound<Interner>> { 523) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> {
535 // An InlineBound is like a GenericPredicate, except the self type is left out. 524 // An InlineBound is like a GenericPredicate, except the self type is left out.
536 // We don't have a special type for this, but Chalk does. 525 // We don't have a special type for this, but Chalk does.
537 match pred { 526 let self_ty_shifted_in = self_ty.clone().shift_bound_vars(DebruijnIndex::ONE);
527 match &pred.value {
538 WhereClause::Implemented(trait_ref) => { 528 WhereClause::Implemented(trait_ref) => {
539 if &trait_ref.substitution[0] != self_ty { 529 if trait_ref.self_type_parameter() != &self_ty_shifted_in {
540 // we can only convert predicates back to type bounds if they 530 // we can only convert predicates back to type bounds if they
541 // have the expected self type 531 // have the expected self type
542 return None; 532 return None;
@@ -546,19 +536,13 @@ pub(super) fn generic_predicate_to_inline_bound(
546 .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) 536 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
547 .collect(); 537 .collect();
548 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; 538 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
549 Some(rust_ir::InlineBound::TraitBound(trait_bound)) 539 Some(make_binders(rust_ir::InlineBound::TraitBound(trait_bound), pred.num_binders))
550 } 540 }
551 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { 541 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
552 if &projection_ty.substitution[0] != self_ty { 542 if projection_ty.self_type_parameter() != &self_ty_shifted_in {
553 return None; 543 return None;
554 } 544 }
555 let trait_ = match from_assoc_type_id(projection_ty.associated_ty_id) 545 let trait_ = projection_ty.trait_(db);
556 .lookup(db.upcast())
557 .container
558 {
559 AssocContainerId::TraitId(t) => t,
560 _ => panic!("associated type not in trait"),
561 };
562 let args_no_self = projection_ty.substitution[1..] 546 let args_no_self = projection_ty.substitution[1..]
563 .iter() 547 .iter()
564 .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) 548 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
@@ -569,7 +553,7 @@ pub(super) fn generic_predicate_to_inline_bound(
569 associated_ty_id: projection_ty.associated_ty_id, 553 associated_ty_id: projection_ty.associated_ty_id,
570 parameters: Vec::new(), // FIXME we don't support generic associated types yet 554 parameters: Vec::new(), // FIXME we don't support generic associated types yet
571 }; 555 };
572 Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound)) 556 Some(make_binders(rust_ir::InlineBound::AliasEqBound(alias_eq_bound), pred.num_binders))
573 } 557 }
574 _ => None, 558 _ => None,
575 } 559 }
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index 1ec1ecd43..42d7af146 100644
--- a/crates/hir_ty/src/utils.rs
+++ b/crates/hir_ty/src/utils.rs
@@ -2,6 +2,7 @@
2//! query, but can't be computed directly from `*Data` (ie, which need a `db`). 2//! query, but can't be computed directly from `*Data` (ie, which need a `db`).
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use chalk_ir::DebruijnIndex;
5use hir_def::{ 6use hir_def::{
6 adt::VariantData, 7 adt::VariantData,
7 db::DefDatabase, 8 db::DefDatabase,
@@ -15,7 +16,7 @@ use hir_def::{
15}; 16};
16use hir_expand::name::{name, Name}; 17use hir_expand::name::{name, Name};
17 18
18use crate::{db::HirDatabase, TraitRef, WhereClause}; 19use crate::{db::HirDatabase, TraitRef, TypeWalk, WhereClause};
19 20
20fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> { 21fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
21 let resolver = trait_.resolver(db); 22 let resolver = trait_.resolver(db);
@@ -63,8 +64,11 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
63 db.generic_predicates_for_param(trait_self) 64 db.generic_predicates_for_param(trait_self)
64 .iter() 65 .iter()
65 .filter_map(|pred| { 66 .filter_map(|pred| {
66 pred.as_ref().filter_map(|pred| match pred { 67 pred.as_ref().filter_map(|pred| match pred.skip_binders() {
67 WhereClause::Implemented(tr) => Some(tr.clone()), 68 // FIXME: how to correctly handle higher-ranked bounds here?
69 WhereClause::Implemented(tr) => {
70 Some(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE))
71 }
68 _ => None, 72 _ => None,
69 }) 73 })
70 }) 74 })