aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--docs/user/manual.adoc6
11 files changed, 215 insertions, 116 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 })
diff --git a/docs/user/manual.adoc b/docs/user/manual.adoc
index 9305d9d1a..8656dd1da 100644
--- a/docs/user/manual.adoc
+++ b/docs/user/manual.adoc
@@ -519,7 +519,7 @@ You can set `RA_LOG` environmental variable to `rust_analyzer=info` to inspect h
519== Security 519== Security
520 520
521At the moment, rust-analyzer assumes that all code is trusted. 521At the moment, rust-analyzer assumes that all code is trusted.
522Here is a **no-exhaustive** list of ways to make rust-analyzer execute arbitrary code: 522Here is a **non-exhaustive** list of ways to make rust-analyzer execute arbitrary code:
523 523
524* proc macros and build scripts are executed by default 524* proc macros and build scripts are executed by default
525* `.cargo/config` can override `rustc` with an arbitrary executable 525* `.cargo/config` can override `rustc` with an arbitrary executable
@@ -527,8 +527,8 @@ Here is a **no-exhaustive** list of ways to make rust-analyzer execute arbitrary
527* rust-analyzer's syntax trees library uses a lot of `unsafe` and hasn't been properly audited for memory safety. 527* rust-analyzer's syntax trees library uses a lot of `unsafe` and hasn't been properly audited for memory safety.
528 528
529rust-analyzer itself doesn't access the network. 529rust-analyzer itself doesn't access the network.
530VS Code plugin doesn't access the network unless the nightly channel is selected in the settings. 530The VS Code plugin doesn't access the network unless the nightly channel is selected in the settings.
531In that case, the plugin uses GitHub API to check for and download updates. 531In that case, the plugin uses the GitHub API to check for and download updates.
532 532
533== Features 533== Features
534 534