aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir/src/lib.rs19
-rw-r--r--crates/hir_ty/src/db.rs11
-rw-r--r--crates/hir_ty/src/display.rs40
-rw-r--r--crates/hir_ty/src/infer/expr.rs5
-rw-r--r--crates/hir_ty/src/infer/unify.rs15
-rw-r--r--crates/hir_ty/src/lib.rs78
-rw-r--r--crates/hir_ty/src/lower.rs53
-rw-r--r--crates/hir_ty/src/traits/chalk.rs10
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs92
-rw-r--r--crates/hir_ty/src/utils.rs2
10 files changed, 212 insertions, 113 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index e3ac37e4c..a325b6691 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -57,8 +57,8 @@ use hir_ty::{
57 to_assoc_type_id, 57 to_assoc_type_id,
58 traits::{FnTrait, Solution, SolutionVariables}, 58 traits::{FnTrait, Solution, SolutionVariables},
59 AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, Cast, DebruijnIndex, 59 AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, Cast, DebruijnIndex,
60 InEnvironment, Interner, ProjectionTy, Scalar, Substitution, Ty, TyDefId, TyKind, 60 InEnvironment, Interner, ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, Ty,
61 TyVariableKind, WhereClause, 61 TyDefId, TyKind, TyVariableKind, WhereClause,
62}; 62};
63use itertools::Itertools; 63use itertools::Itertools;
64use rustc_hash::FxHashSet; 64use rustc_hash::FxHashSet;
@@ -1460,7 +1460,7 @@ impl TypeParam {
1460 pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> { 1460 pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> {
1461 db.generic_predicates_for_param(self.id) 1461 db.generic_predicates_for_param(self.id)
1462 .into_iter() 1462 .into_iter()
1463 .filter_map(|pred| match &pred.value { 1463 .filter_map(|pred| match &pred.skip_binders().skip_binders() {
1464 hir_ty::WhereClause::Implemented(trait_ref) => { 1464 hir_ty::WhereClause::Implemented(trait_ref) => {
1465 Some(Trait::from(trait_ref.hir_trait_id())) 1465 Some(Trait::from(trait_ref.hir_trait_id()))
1466 } 1466 }
@@ -2022,7 +2022,7 @@ impl Type {
2022 pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> { 2022 pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> {
2023 self.ty.value.impl_trait_bounds(db).map(|it| { 2023 self.ty.value.impl_trait_bounds(db).map(|it| {
2024 it.into_iter() 2024 it.into_iter()
2025 .filter_map(|pred| match pred { 2025 .filter_map(|pred| match pred.skip_binders() {
2026 hir_ty::WhereClause::Implemented(trait_ref) => { 2026 hir_ty::WhereClause::Implemented(trait_ref) => {
2027 Some(Trait::from(trait_ref.hir_trait_id())) 2027 Some(Trait::from(trait_ref.hir_trait_id()))
2028 } 2028 }
@@ -2061,11 +2061,11 @@ impl Type {
2061 fn walk_bounds( 2061 fn walk_bounds(
2062 db: &dyn HirDatabase, 2062 db: &dyn HirDatabase,
2063 type_: &Type, 2063 type_: &Type,
2064 bounds: &[WhereClause], 2064 bounds: &[QuantifiedWhereClause],
2065 cb: &mut impl FnMut(Type), 2065 cb: &mut impl FnMut(Type),
2066 ) { 2066 ) {
2067 for pred in bounds { 2067 for pred in bounds {
2068 match pred { 2068 match pred.skip_binders() {
2069 WhereClause::Implemented(trait_ref) => { 2069 WhereClause::Implemented(trait_ref) => {
2070 cb(type_.clone()); 2070 cb(type_.clone());
2071 // skip the self type. it's likely the type we just got the bounds from 2071 // skip the self type. it's likely the type we just got the bounds from
@@ -2107,7 +2107,12 @@ impl Type {
2107 } 2107 }
2108 } 2108 }
2109 TyKind::Dyn(bounds) => { 2109 TyKind::Dyn(bounds) => {
2110 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); 2110 walk_bounds(
2111 db,
2112 &type_.derived(ty.clone()),
2113 bounds.bounds.skip_binders().interned(),
2114 cb,
2115 );
2111 } 2116 }
2112 2117
2113 TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => { 2118 TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => {
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 9d3b79be3..cc6b93d37 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> {
@@ -328,9 +328,9 @@ impl HirDisplay for Ty {
328 328
329 // FIXME: all this just to decide whether to use parentheses... 329 // FIXME: all this just to decide whether to use parentheses...
330 let datas; 330 let datas;
331 let predicates = match t.interned(&Interner) { 331 let predicates: Vec<_> = match t.interned(&Interner) {
332 TyKind::Dyn(predicates) if predicates.len() > 1 => { 332 TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => {
333 Cow::Borrowed(predicates.as_ref()) 333 dyn_ty.bounds.skip_binders().interned().iter().cloned().collect()
334 } 334 }
335 &TyKind::Alias(AliasTy::Opaque(OpaqueTy { 335 &TyKind::Alias(AliasTy::Opaque(OpaqueTy {
336 opaque_ty_id, 336 opaque_ty_id,
@@ -345,17 +345,21 @@ impl HirDisplay for Ty {
345 .as_ref() 345 .as_ref()
346 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 346 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
347 let bounds = data.subst(parameters); 347 let bounds = data.subst(parameters);
348 Cow::Owned(bounds.value) 348 bounds.value
349 } else { 349 } else {
350 Cow::Borrowed(&[][..]) 350 Vec::new()
351 } 351 }
352 } 352 }
353 _ => Cow::Borrowed(&[][..]), 353 _ => Vec::new(),
354 }; 354 };
355 355
356 if let [WhereClause::Implemented(trait_ref), _] = predicates.as_ref() { 356 if let Some(WhereClause::Implemented(trait_ref)) =
357 predicates.get(0).map(|b| b.skip_binders())
358 {
357 let trait_ = trait_ref.hir_trait_id(); 359 let trait_ = trait_ref.hir_trait_id();
358 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) { 360 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_)
361 && predicates.len() <= 2
362 {
359 return write!(f, "{}", ty_display); 363 return write!(f, "{}", ty_display);
360 } 364 }
361 } 365 }
@@ -577,7 +581,7 @@ impl HirDisplay for Ty {
577 .generic_predicates(id.parent) 581 .generic_predicates(id.parent)
578 .into_iter() 582 .into_iter()
579 .map(|pred| pred.clone().subst(&substs)) 583 .map(|pred| pred.clone().subst(&substs))
580 .filter(|wc| match &wc { 584 .filter(|wc| match &wc.skip_binders() {
581 WhereClause::Implemented(tr) => tr.self_type_parameter() == self, 585 WhereClause::Implemented(tr) => tr.self_type_parameter() == self,
582 WhereClause::AliasEq(AliasEq { 586 WhereClause::AliasEq(AliasEq {
583 alias: AliasTy::Projection(proj), 587 alias: AliasTy::Projection(proj),
@@ -591,8 +595,12 @@ impl HirDisplay for Ty {
591 } 595 }
592 } 596 }
593 TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, 597 TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?,
594 TyKind::Dyn(predicates) => { 598 TyKind::Dyn(dyn_ty) => {
595 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; 599 write_bounds_like_dyn_trait_with_prefix(
600 "dyn",
601 dyn_ty.bounds.skip_binders().interned(),
602 f,
603 )?;
596 } 604 }
597 TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?, 605 TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?,
598 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { 606 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
@@ -661,7 +669,7 @@ fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator<Item = Trai
661 669
662pub fn write_bounds_like_dyn_trait_with_prefix( 670pub fn write_bounds_like_dyn_trait_with_prefix(
663 prefix: &str, 671 prefix: &str,
664 predicates: &[WhereClause], 672 predicates: &[QuantifiedWhereClause],
665 f: &mut HirFormatter, 673 f: &mut HirFormatter,
666) -> Result<(), HirDisplayError> { 674) -> Result<(), HirDisplayError> {
667 write!(f, "{}", prefix)?; 675 write!(f, "{}", prefix)?;
@@ -674,7 +682,7 @@ pub fn write_bounds_like_dyn_trait_with_prefix(
674} 682}
675 683
676fn write_bounds_like_dyn_trait( 684fn write_bounds_like_dyn_trait(
677 predicates: &[WhereClause], 685 predicates: &[QuantifiedWhereClause],
678 f: &mut HirFormatter, 686 f: &mut HirFormatter,
679) -> Result<(), HirDisplayError> { 687) -> Result<(), HirDisplayError> {
680 // Note: This code is written to produce nice results (i.e. 688 // Note: This code is written to produce nice results (i.e.
@@ -687,7 +695,7 @@ fn write_bounds_like_dyn_trait(
687 let mut angle_open = false; 695 let mut angle_open = false;
688 let mut is_fn_trait = false; 696 let mut is_fn_trait = false;
689 for p in predicates.iter() { 697 for p in predicates.iter() {
690 match p { 698 match p.skip_binders() {
691 WhereClause::Implemented(trait_ref) => { 699 WhereClause::Implemented(trait_ref) => {
692 let trait_ = trait_ref.hir_trait_id(); 700 let trait_ = trait_ref.hir_trait_id();
693 if !is_fn_trait { 701 if !is_fn_trait {
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 24deff707..05cbde4e3 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::{
@@ -936,7 +937,9 @@ impl<'a> InferenceContext<'a> {
936 let def: CallableDefId = from_chalk(self.db, *fn_def); 937 let def: CallableDefId = from_chalk(self.db, *fn_def);
937 let generic_predicates = self.db.generic_predicates(def.into()); 938 let generic_predicates = self.db.generic_predicates(def.into());
938 for predicate in generic_predicates.iter() { 939 for predicate in generic_predicates.iter() {
939 let predicate = predicate.clone().subst(parameters); 940 let (predicate, binders) =
941 predicate.clone().subst(parameters).into_value_and_skipped_binders();
942 always!(binders == 0); // quantified where clauses not yet handled
940 self.obligations.push(predicate.cast(&Interner)); 943 self.obligations.push(predicate.cast(&Interner));
941 } 944 }
942 // add obligation for trait implementation, if this is a trait method 945 // add obligation for trait implementation, if this is a trait method
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 1fc03c8f4..35b0a2059 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -310,9 +310,18 @@ impl InferenceTable {
310 310
311 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, 311 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true,
312 312
313 (TyKind::Dyn(dyn1), TyKind::Dyn(dyn2)) if dyn1.len() == dyn2.len() => { 313 (TyKind::Dyn(dyn1), TyKind::Dyn(dyn2))
314 for (pred1, pred2) in dyn1.iter().zip(dyn2.iter()) { 314 if dyn1.bounds.skip_binders().interned().len()
315 if !self.unify_preds(pred1, pred2, depth + 1) { 315 == dyn2.bounds.skip_binders().interned().len() =>
316 {
317 for (pred1, pred2) in dyn1
318 .bounds
319 .skip_binders()
320 .interned()
321 .iter()
322 .zip(dyn2.bounds.skip_binders().interned().iter())
323 {
324 if !self.unify_preds(pred1.skip_binders(), pred2.skip_binders(), depth + 1) {
316 return false; 325 return false;
317 } 326 }
318 } 327 }
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index ad908f957..90b5b17e2 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -132,6 +132,12 @@ impl TypeWalk for ProjectionTy {
132 } 132 }
133} 133}
134 134
135#[derive(Clone, PartialEq, Eq, Debug, Hash)]
136pub struct DynTy {
137 /// The unknown self type.
138 pub bounds: Binders<QuantifiedWhereClauses>,
139}
140
135pub type FnSig = chalk_ir::FnSig<Interner>; 141pub type FnSig = chalk_ir::FnSig<Interner>;
136 142
137#[derive(Clone, PartialEq, Eq, Debug, Hash)] 143#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -283,7 +289,7 @@ pub enum TyKind {
283 /// represents the `Self` type inside the bounds. This is currently 289 /// represents the `Self` type inside the bounds. This is currently
284 /// implicit; Chalk has the `Binders` struct to make it explicit, but it 290 /// implicit; Chalk has the `Binders` struct to make it explicit, but it
285 /// didn't seem worth the overhead yet. 291 /// didn't seem worth the overhead yet.
286 Dyn(Arc<[WhereClause]>), 292 Dyn(DynTy),
287 293
288 /// A placeholder for a type which could not be computed; this is propagated 294 /// A placeholder for a type which could not be computed; this is propagated
289 /// to avoid useless error messages. Doubles as a placeholder where type 295 /// to avoid useless error messages. Doubles as a placeholder where type
@@ -490,6 +496,13 @@ impl<T> Binders<T> {
490 Self { num_binders, value } 496 Self { num_binders, value }
491 } 497 }
492 498
499 pub fn wrap_empty(value: T) -> Self
500 where
501 T: TypeWalk,
502 {
503 Self { num_binders: 0, value: value.shift_bound_vars(DebruijnIndex::ONE) }
504 }
505
493 pub fn as_ref(&self) -> Binders<&T> { 506 pub fn as_ref(&self) -> Binders<&T> {
494 Binders { num_binders: self.num_binders, value: &self.value } 507 Binders { num_binders: self.num_binders, value: &self.value }
495 } 508 }
@@ -501,6 +514,14 @@ impl<T> Binders<T> {
501 pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> { 514 pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> {
502 Some(Binders { num_binders: self.num_binders, value: f(self.value)? }) 515 Some(Binders { num_binders: self.num_binders, value: f(self.value)? })
503 } 516 }
517
518 pub fn skip_binders(&self) -> &T {
519 &self.value
520 }
521
522 pub fn into_value_and_skipped_binders(self) -> (T, usize) {
523 (self.value, self.num_binders)
524 }
504} 525}
505 526
506impl<T: Clone> Binders<&T> { 527impl<T: Clone> Binders<&T> {
@@ -614,6 +635,24 @@ impl TypeWalk for WhereClause {
614 } 635 }
615} 636}
616 637
638pub type QuantifiedWhereClause = Binders<WhereClause>;
639
640#[derive(Debug, Clone, PartialEq, Eq, Hash)]
641pub struct QuantifiedWhereClauses(Arc<[QuantifiedWhereClause]>);
642
643impl QuantifiedWhereClauses {
644 pub fn from_iter(
645 _interner: &Interner,
646 elements: impl IntoIterator<Item = QuantifiedWhereClause>,
647 ) -> Self {
648 QuantifiedWhereClauses(elements.into_iter().collect())
649 }
650
651 pub fn interned(&self) -> &Arc<[QuantifiedWhereClause]> {
652 &self.0
653 }
654}
655
617/// Basically a claim (currently not validated / checked) that the contained 656/// Basically a claim (currently not validated / checked) that the contained
618/// type / trait ref contains no inference variables; any inference variables it 657/// type / trait ref contains no inference variables; any inference variables it
619/// contained have been replaced by bound variables, and `kinds` tells us how 658/// contained have been replaced by bound variables, and `kinds` tells us how
@@ -810,12 +849,14 @@ impl Ty {
810 } 849 }
811 850
812 /// If this is a `dyn Trait` type, this returns the `Trait` part. 851 /// If this is a `dyn Trait` type, this returns the `Trait` part.
813 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { 852 fn dyn_trait_ref(&self) -> Option<&TraitRef> {
814 match self.interned(&Interner) { 853 match self.interned(&Interner) {
815 TyKind::Dyn(bounds) => bounds.get(0).and_then(|b| match b { 854 TyKind::Dyn(dyn_ty) => {
816 WhereClause::Implemented(trait_ref) => Some(trait_ref), 855 dyn_ty.bounds.value.interned().get(0).and_then(|b| match b.skip_binders() {
817 _ => None, 856 WhereClause::Implemented(trait_ref) => Some(trait_ref),
818 }), 857 _ => None,
858 })
859 }
819 _ => None, 860 _ => None,
820 } 861 }
821 } 862 }
@@ -892,7 +933,7 @@ impl Ty {
892 } 933 }
893 } 934 }
894 935
895 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<WhereClause>> { 936 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>> {
896 match self.interned(&Interner) { 937 match self.interned(&Interner) {
897 TyKind::OpaqueType(opaque_ty_id, ..) => { 938 TyKind::OpaqueType(opaque_ty_id, ..) => {
898 match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { 939 match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
@@ -905,10 +946,13 @@ impl Ty {
905 // This is only used by type walking. 946 // This is only used by type walking.
906 // Parameters will be walked outside, and projection predicate is not used. 947 // Parameters will be walked outside, and projection predicate is not used.
907 // So just provide the Future trait. 948 // So just provide the Future trait.
908 let impl_bound = WhereClause::Implemented(TraitRef { 949 let impl_bound = Binders::new(
909 trait_id: to_chalk_trait_id(future_trait), 950 0,
910 substitution: Substitution::empty(), 951 WhereClause::Implemented(TraitRef {
911 }); 952 trait_id: to_chalk_trait_id(future_trait),
953 substitution: Substitution::empty(),
954 }),
955 );
912 Some(vec![impl_bound]) 956 Some(vec![impl_bound])
913 } else { 957 } else {
914 None 958 None
@@ -945,7 +989,7 @@ impl Ty {
945 .generic_predicates(id.parent) 989 .generic_predicates(id.parent)
946 .into_iter() 990 .into_iter()
947 .map(|pred| pred.clone().subst(&substs)) 991 .map(|pred| pred.clone().subst(&substs))
948 .filter(|wc| match &wc { 992 .filter(|wc| match &wc.skip_binders() {
949 WhereClause::Implemented(tr) => tr.self_type_parameter() == self, 993 WhereClause::Implemented(tr) => tr.self_type_parameter() == self,
950 WhereClause::AliasEq(AliasEq { 994 WhereClause::AliasEq(AliasEq {
951 alias: AliasTy::Projection(proj), 995 alias: AliasTy::Projection(proj),
@@ -1094,8 +1138,8 @@ impl TypeWalk for Ty {
1094 t.walk(f); 1138 t.walk(f);
1095 } 1139 }
1096 } 1140 }
1097 TyKind::Dyn(predicates) => { 1141 TyKind::Dyn(dyn_ty) => {
1098 for p in predicates.iter() { 1142 for p in dyn_ty.bounds.value.interned().iter() {
1099 p.walk(f); 1143 p.walk(f);
1100 } 1144 }
1101 } 1145 }
@@ -1122,8 +1166,8 @@ impl TypeWalk for Ty {
1122 TyKind::Alias(AliasTy::Projection(p_ty)) => { 1166 TyKind::Alias(AliasTy::Projection(p_ty)) => {
1123 p_ty.substitution.walk_mut_binders(f, binders); 1167 p_ty.substitution.walk_mut_binders(f, binders);
1124 } 1168 }
1125 TyKind::Dyn(predicates) => { 1169 TyKind::Dyn(dyn_ty) => {
1126 for p in make_mut_slice(predicates) { 1170 for p in make_mut_slice(&mut dyn_ty.bounds.value.0) {
1127 p.walk_mut_binders(f, binders.shifted_in()); 1171 p.walk_mut_binders(f, binders.shifted_in());
1128 } 1172 }
1129 } 1173 }
@@ -1173,7 +1217,7 @@ pub struct ReturnTypeImplTraits {
1173 1217
1174#[derive(Clone, PartialEq, Eq, Debug, Hash)] 1218#[derive(Clone, PartialEq, Eq, Debug, Hash)]
1175pub(crate) struct ReturnTypeImplTrait { 1219pub(crate) struct ReturnTypeImplTrait {
1176 pub(crate) bounds: Binders<Vec<WhereClause>>, 1220 pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>,
1177} 1221}
1178 1222
1179pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { 1223pub 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 fd451a823..f60cec649 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,13 +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 193 QuantifiedWhereClauses::from_iter(
193 .iter() 194 &Interner,
194 .flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)) 195 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
195 .collect() 196 )
196 }); 197 });
197 TyKind::Dyn(predicates).intern(&Interner) 198 let bounds = Binders::new(1, bounds);
199 TyKind::Dyn(DynTy { bounds }).intern(&Interner)
198 } 200 }
199 TypeRef::ImplTrait(bounds) => { 201 TypeRef::ImplTrait(bounds) => {
200 match self.impl_trait_mode { 202 match self.impl_trait_mode {
@@ -376,7 +378,16 @@ impl<'a> TyLoweringContext<'a> {
376 // FIXME report error (ambiguous associated type) 378 // FIXME report error (ambiguous associated type)
377 TyKind::Unknown.intern(&Interner) 379 TyKind::Unknown.intern(&Interner)
378 } else { 380 } else {
379 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)
380 }; 391 };
381 return (ty, None); 392 return (ty, None);
382 } 393 }
@@ -670,7 +681,7 @@ impl<'a> TyLoweringContext<'a> {
670 &'a self, 681 &'a self,
671 where_predicate: &'a WherePredicate, 682 where_predicate: &'a WherePredicate,
672 ignore_bindings: bool, 683 ignore_bindings: bool,
673 ) -> impl Iterator<Item = WhereClause> + 'a { 684 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
674 match where_predicate { 685 match where_predicate {
675 WherePredicate::ForLifetime { target, bound, .. } 686 WherePredicate::ForLifetime { target, bound, .. }
676 | WherePredicate::TypeBound { target, bound } => { 687 | WherePredicate::TypeBound { target, bound } => {
@@ -705,12 +716,12 @@ impl<'a> TyLoweringContext<'a> {
705 bound: &'a TypeBound, 716 bound: &'a TypeBound,
706 self_ty: Ty, 717 self_ty: Ty,
707 ignore_bindings: bool, 718 ignore_bindings: bool,
708 ) -> impl Iterator<Item = WhereClause> + 'a { 719 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
709 let mut bindings = None; 720 let mut bindings = None;
710 let trait_ref = match bound { 721 let trait_ref = match bound {
711 TypeBound::Path(path) => { 722 TypeBound::Path(path) => {
712 bindings = self.lower_trait_ref_from_path(path, Some(self_ty)); 723 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
713 bindings.clone().map(WhereClause::Implemented) 724 bindings.clone().map(WhereClause::Implemented).map(|b| Binders::wrap_empty(b))
714 } 725 }
715 TypeBound::Lifetime(_) => None, 726 TypeBound::Lifetime(_) => None,
716 TypeBound::Error => None, 727 TypeBound::Error => None,
@@ -727,7 +738,7 @@ impl<'a> TyLoweringContext<'a> {
727 &'a self, 738 &'a self,
728 bound: &'a TypeBound, 739 bound: &'a TypeBound,
729 trait_ref: TraitRef, 740 trait_ref: TraitRef,
730 ) -> impl Iterator<Item = WhereClause> + 'a { 741 ) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
731 let last_segment = match bound { 742 let last_segment = match bound {
732 TypeBound::Path(path) => path.segments().last(), 743 TypeBound::Path(path) => path.segments().last(),
733 TypeBound::Error | TypeBound::Lifetime(_) => None, 744 TypeBound::Error | TypeBound::Lifetime(_) => None,
@@ -743,7 +754,7 @@ impl<'a> TyLoweringContext<'a> {
743 &binding.name, 754 &binding.name,
744 ); 755 );
745 let (super_trait_ref, associated_ty) = match found { 756 let (super_trait_ref, associated_ty) = match found {
746 None => return SmallVec::<[WhereClause; 1]>::new(), 757 None => return SmallVec::<[QuantifiedWhereClause; 1]>::new(),
747 Some(t) => t, 758 Some(t) => t,
748 }; 759 };
749 let projection_ty = ProjectionTy { 760 let projection_ty = ProjectionTy {
@@ -757,7 +768,7 @@ impl<'a> TyLoweringContext<'a> {
757 let ty = self.lower_ty(type_ref); 768 let ty = self.lower_ty(type_ref);
758 let alias_eq = 769 let alias_eq =
759 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty }; 770 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
760 preds.push(WhereClause::AliasEq(alias_eq)); 771 preds.push(Binders::wrap_empty(WhereClause::AliasEq(alias_eq)));
761 } 772 }
762 for bound in &binding.bounds { 773 for bound in &binding.bounds {
763 preds.extend(self.lower_type_bound( 774 preds.extend(self.lower_type_bound(
@@ -814,7 +825,7 @@ pub fn associated_type_shorthand_candidates<R>(
814 let predicates = db.generic_predicates_for_param(param_id); 825 let predicates = db.generic_predicates_for_param(param_id);
815 let mut traits_: Vec<_> = predicates 826 let mut traits_: Vec<_> = predicates
816 .iter() 827 .iter()
817 .filter_map(|pred| match &pred.value { 828 .filter_map(|pred| match &pred.value.value {
818 WhereClause::Implemented(tr) => Some(tr.clone()), 829 WhereClause::Implemented(tr) => Some(tr.clone()),
819 _ => None, 830 _ => None,
820 }) 831 })
@@ -887,7 +898,7 @@ pub(crate) fn field_types_query(
887pub(crate) fn generic_predicates_for_param_query( 898pub(crate) fn generic_predicates_for_param_query(
888 db: &dyn HirDatabase, 899 db: &dyn HirDatabase,
889 param_id: TypeParamId, 900 param_id: TypeParamId,
890) -> Arc<[Binders<WhereClause>]> { 901) -> Arc<[Binders<QuantifiedWhereClause>]> {
891 let resolver = param_id.parent.resolver(db.upcast()); 902 let resolver = param_id.parent.resolver(db.upcast());
892 let ctx = 903 let ctx =
893 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 904 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
@@ -915,7 +926,7 @@ pub(crate) fn generic_predicates_for_param_recover(
915 _db: &dyn HirDatabase, 926 _db: &dyn HirDatabase,
916 _cycle: &[String], 927 _cycle: &[String],
917 _param_id: &TypeParamId, 928 _param_id: &TypeParamId,
918) -> Arc<[Binders<WhereClause>]> { 929) -> Arc<[Binders<QuantifiedWhereClause>]> {
919 Arc::new([]) 930 Arc::new([])
920} 931}
921 932
@@ -930,7 +941,7 @@ pub(crate) fn trait_environment_query(
930 let mut clauses = Vec::new(); 941 let mut clauses = Vec::new();
931 for pred in resolver.where_predicates_in_scope() { 942 for pred in resolver.where_predicates_in_scope() {
932 for pred in ctx.lower_where_predicate(pred, false) { 943 for pred in ctx.lower_where_predicate(pred, false) {
933 if let WhereClause::Implemented(tr) = &pred { 944 if let WhereClause::Implemented(tr) = &pred.skip_binders() {
934 traits_in_scope.push((tr.self_type_parameter().clone(), tr.hir_trait_id())); 945 traits_in_scope.push((tr.self_type_parameter().clone(), tr.hir_trait_id()));
935 } 946 }
936 let program_clause: chalk_ir::ProgramClause<Interner> = 947 let program_clause: chalk_ir::ProgramClause<Interner> =
@@ -970,7 +981,7 @@ pub(crate) fn trait_environment_query(
970pub(crate) fn generic_predicates_query( 981pub(crate) fn generic_predicates_query(
971 db: &dyn HirDatabase, 982 db: &dyn HirDatabase,
972 def: GenericDefId, 983 def: GenericDefId,
973) -> Arc<[Binders<WhereClause>]> { 984) -> Arc<[Binders<QuantifiedWhereClause>]> {
974 let resolver = def.resolver(db.upcast()); 985 let resolver = def.resolver(db.upcast());
975 let ctx = 986 let ctx =
976 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 987 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index 944145603..4019fdf17 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -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),
@@ -397,7 +400,6 @@ pub(crate) fn associated_ty_data_query(
397 .iter() 400 .iter()
398 .flat_map(|bound| ctx.lower_type_bound(bound, self_ty.clone(), false)) 401 .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)) 402 .filter_map(|pred| generic_predicate_to_inline_bound(db, &pred, &self_ty))
400 .map(|bound| make_binders(bound.shifted_in(&Interner), 0))
401 .collect(); 403 .collect();
402 404
403 let where_clauses = convert_where_clauses(db, type_alias.into(), &bound_vars); 405 let where_clauses = convert_where_clauses(db, type_alias.into(), &bound_vars);
@@ -720,3 +722,7 @@ impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> {
720 chalk_ir::ClosureId(id.as_intern_id()) 722 chalk_ir::ClosureId(id.as_intern_id())
721 } 723 }
722} 724}
725
726fn wrap_in_empty_binders<T: crate::TypeWalk>(value: T) -> crate::Binders<T> {
727 crate::Binders::wrap_empty(value)
728}
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index 65feb82e5..7209dd14e 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))
@@ -500,6 +492,29 @@ where
500 } 492 }
501} 493}
502 494
495impl<T: ToChalk> ToChalk for crate::Binders<T>
496where
497 T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>,
498{
499 type Chalk = chalk_ir::Binders<T::Chalk>;
500
501 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Binders<T::Chalk> {
502 chalk_ir::Binders::new(
503 chalk_ir::VariableKinds::from_iter(
504 &Interner,
505 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
506 .take(self.num_binders),
507 ),
508 self.value.to_chalk(db),
509 )
510 }
511
512 fn from_chalk(db: &dyn HirDatabase, binders: chalk_ir::Binders<T::Chalk>) -> crate::Binders<T> {
513 let (v, b) = binders.into_value_and_skipped_binders();
514 crate::Binders::new(b.len(&Interner), from_chalk(db, v))
515 }
516}
517
503pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> 518pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T>
504where 519where
505 T: HasInterner<Interner = Interner>, 520 T: HasInterner<Interner = Interner>,
@@ -529,14 +544,15 @@ pub(super) fn convert_where_clauses(
529 544
530pub(super) fn generic_predicate_to_inline_bound( 545pub(super) fn generic_predicate_to_inline_bound(
531 db: &dyn HirDatabase, 546 db: &dyn HirDatabase,
532 pred: &WhereClause, 547 pred: &QuantifiedWhereClause,
533 self_ty: &Ty, 548 self_ty: &Ty,
534) -> Option<rust_ir::InlineBound<Interner>> { 549) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> {
535 // An InlineBound is like a GenericPredicate, except the self type is left out. 550 // 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. 551 // We don't have a special type for this, but Chalk does.
537 match pred { 552 let self_ty_shifted_in = self_ty.clone().shift_bound_vars(DebruijnIndex::ONE);
553 match &pred.value {
538 WhereClause::Implemented(trait_ref) => { 554 WhereClause::Implemented(trait_ref) => {
539 if &trait_ref.substitution[0] != self_ty { 555 if trait_ref.self_type_parameter() != &self_ty_shifted_in {
540 // we can only convert predicates back to type bounds if they 556 // we can only convert predicates back to type bounds if they
541 // have the expected self type 557 // have the expected self type
542 return None; 558 return None;
@@ -546,19 +562,13 @@ pub(super) fn generic_predicate_to_inline_bound(
546 .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) 562 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
547 .collect(); 563 .collect();
548 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; 564 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
549 Some(rust_ir::InlineBound::TraitBound(trait_bound)) 565 Some(make_binders(rust_ir::InlineBound::TraitBound(trait_bound), pred.num_binders))
550 } 566 }
551 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { 567 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
552 if &projection_ty.substitution[0] != self_ty { 568 if projection_ty.self_type_parameter() != &self_ty_shifted_in {
553 return None; 569 return None;
554 } 570 }
555 let trait_ = match from_assoc_type_id(projection_ty.associated_ty_id) 571 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..] 572 let args_no_self = projection_ty.substitution[1..]
563 .iter() 573 .iter()
564 .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) 574 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
@@ -569,7 +579,7 @@ pub(super) fn generic_predicate_to_inline_bound(
569 associated_ty_id: projection_ty.associated_ty_id, 579 associated_ty_id: projection_ty.associated_ty_id,
570 parameters: Vec::new(), // FIXME we don't support generic associated types yet 580 parameters: Vec::new(), // FIXME we don't support generic associated types yet
571 }; 581 };
572 Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound)) 582 Some(make_binders(rust_ir::InlineBound::AliasEqBound(alias_eq_bound), pred.num_binders))
573 } 583 }
574 _ => None, 584 _ => None,
575 } 585 }
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index 1ec1ecd43..19874e42b 100644
--- a/crates/hir_ty/src/utils.rs
+++ b/crates/hir_ty/src/utils.rs
@@ -63,7 +63,7 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
63 db.generic_predicates_for_param(trait_self) 63 db.generic_predicates_for_param(trait_self)
64 .iter() 64 .iter()
65 .filter_map(|pred| { 65 .filter_map(|pred| {
66 pred.as_ref().filter_map(|pred| match pred { 66 pred.as_ref().filter_map(|pred| match pred.skip_binders() {
67 WhereClause::Implemented(tr) => Some(tr.clone()), 67 WhereClause::Implemented(tr) => Some(tr.clone()),
68 _ => None, 68 _ => None,
69 }) 69 })