aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-08-23 16:19:37 +0100
committerFlorian Diebold <[email protected]>2019-09-03 13:00:35 +0100
commit741e350d4b7c3561f242207541ac9d7cab6ce45f (patch)
tree8ab45d1f2491395eba0e6f938eddc65f15d2667d /crates
parent966ab9abd2253e68d2e410a58dc1328805ee7f61 (diff)
Add support for associated type bindings (`where Trait<Type = X>`)
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/path.rs21
-rw-r--r--crates/ra_hir/src/ty.rs33
-rw-r--r--crates/ra_hir/src/ty/lower.rs85
-rw-r--r--crates/ra_hir/src/ty/tests.rs62
-rw-r--r--crates/ra_hir/src/ty/traits.rs27
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs7
6 files changed, 183 insertions, 52 deletions
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs
index 5ee71e421..24316fc91 100644
--- a/crates/ra_hir/src/path.rs
+++ b/crates/ra_hir/src/path.rs
@@ -31,7 +31,8 @@ pub struct GenericArgs {
31 /// Self type. Otherwise, when we have a path `Trait<X, Y>`, the Self type 31 /// Self type. Otherwise, when we have a path `Trait<X, Y>`, the Self type
32 /// is left out. 32 /// is left out.
33 pub has_self_type: bool, 33 pub has_self_type: bool,
34 // someday also bindings 34 /// Associated type bindings like in `Iterator<Item = T>`.
35 pub bindings: Vec<(Name, TypeRef)>,
35} 36}
36 37
37/// A single generic argument. 38/// A single generic argument.
@@ -170,16 +171,24 @@ impl GenericArgs {
170 let type_ref = TypeRef::from_ast_opt(type_arg.type_ref()); 171 let type_ref = TypeRef::from_ast_opt(type_arg.type_ref());
171 args.push(GenericArg::Type(type_ref)); 172 args.push(GenericArg::Type(type_ref));
172 } 173 }
173 // lifetimes and assoc type args ignored for now 174 // lifetimes ignored for now
174 if !args.is_empty() { 175 let mut bindings = Vec::new();
175 Some(GenericArgs { args, has_self_type: false }) 176 for assoc_type_arg in node.assoc_type_args() {
176 } else { 177 if let Some(name_ref) = assoc_type_arg.name_ref() {
178 let name = name_ref.as_name();
179 let type_ref = TypeRef::from_ast_opt(assoc_type_arg.type_ref());
180 bindings.push((name, type_ref));
181 }
182 }
183 if args.is_empty() && bindings.is_empty() {
177 None 184 None
185 } else {
186 Some(GenericArgs { args, has_self_type: false, bindings })
178 } 187 }
179 } 188 }
180 189
181 pub(crate) fn empty() -> GenericArgs { 190 pub(crate) fn empty() -> GenericArgs {
182 GenericArgs { args: Vec::new(), has_self_type: false } 191 GenericArgs { args: Vec::new(), has_self_type: false, bindings: Vec::new() }
183 } 192 }
184} 193}
185 194
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index b54c80318..035491bff 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -120,12 +120,32 @@ pub struct ProjectionTy {
120 pub parameters: Substs, 120 pub parameters: Substs,
121} 121}
122 122
123impl ProjectionTy {
124 pub fn walk(&self, f: &mut impl FnMut(&Ty)) {
125 self.parameters.walk(f);
126 }
127
128 pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
129 self.parameters.walk_mut(f);
130 }
131}
132
123#[derive(Clone, PartialEq, Eq, Debug, Hash)] 133#[derive(Clone, PartialEq, Eq, Debug, Hash)]
124pub struct UnselectedProjectionTy { 134pub struct UnselectedProjectionTy {
125 pub type_name: Name, 135 pub type_name: Name,
126 pub parameters: Substs, 136 pub parameters: Substs,
127} 137}
128 138
139impl UnselectedProjectionTy {
140 pub fn walk(&self, f: &mut impl FnMut(&Ty)) {
141 self.parameters.walk(f);
142 }
143
144 pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
145 self.parameters.walk_mut(f);
146 }
147}
148
129/// A type. 149/// A type.
130/// 150///
131/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents 151/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
@@ -306,6 +326,8 @@ impl TraitRef {
306pub enum GenericPredicate { 326pub enum GenericPredicate {
307 /// The given trait needs to be implemented for its type parameters. 327 /// The given trait needs to be implemented for its type parameters.
308 Implemented(TraitRef), 328 Implemented(TraitRef),
329 /// An associated type bindings like in `Iterator<Item = T>`.
330 Projection(ProjectionPredicate),
309 /// We couldn't resolve the trait reference. (If some type parameters can't 331 /// We couldn't resolve the trait reference. (If some type parameters can't
310 /// be resolved, they will just be Unknown). 332 /// be resolved, they will just be Unknown).
311 Error, 333 Error,
@@ -324,6 +346,9 @@ impl GenericPredicate {
324 GenericPredicate::Implemented(trait_ref) => { 346 GenericPredicate::Implemented(trait_ref) => {
325 GenericPredicate::Implemented(trait_ref.subst(substs)) 347 GenericPredicate::Implemented(trait_ref.subst(substs))
326 } 348 }
349 GenericPredicate::Projection(projection_predicate) => {
350 GenericPredicate::Projection(projection_predicate.subst(substs))
351 }
327 GenericPredicate::Error => self, 352 GenericPredicate::Error => self,
328 } 353 }
329 } 354 }
@@ -331,6 +356,7 @@ impl GenericPredicate {
331 pub fn walk(&self, f: &mut impl FnMut(&Ty)) { 356 pub fn walk(&self, f: &mut impl FnMut(&Ty)) {
332 match self { 357 match self {
333 GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f), 358 GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f),
359 GenericPredicate::Projection(projection_pred) => projection_pred.walk(f),
334 GenericPredicate::Error => {} 360 GenericPredicate::Error => {}
335 } 361 }
336 } 362 }
@@ -338,6 +364,7 @@ impl GenericPredicate {
338 pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { 364 pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
339 match self { 365 match self {
340 GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut(f), 366 GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut(f),
367 GenericPredicate::Projection(projection_pred) => projection_pred.walk_mut(f),
341 GenericPredicate::Error => {} 368 GenericPredicate::Error => {}
342 } 369 }
343 } 370 }
@@ -754,6 +781,9 @@ impl HirDisplay for Ty {
754 GenericPredicate::Implemented(trait_ref) => { 781 GenericPredicate::Implemented(trait_ref) => {
755 trait_ref.hir_fmt_ext(f, false)? 782 trait_ref.hir_fmt_ext(f, false)?
756 } 783 }
784 GenericPredicate::Projection(_projection_pred) => {
785 // TODO show something
786 }
757 GenericPredicate::Error => p.hir_fmt(f)?, 787 GenericPredicate::Error => p.hir_fmt(f)?,
758 } 788 }
759 } 789 }
@@ -800,6 +830,9 @@ impl HirDisplay for GenericPredicate {
800 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result { 830 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
801 match self { 831 match self {
802 GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?, 832 GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?,
833 GenericPredicate::Projection(projection_pred) => {
834 // TODO print something
835 }
803 GenericPredicate::Error => write!(f, "{{error}}")?, 836 GenericPredicate::Error => write!(f, "{{error}}")?,
804 } 837 }
805 Ok(()) 838 Ok(())
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index 47d161277..0011c06b4 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -8,7 +8,9 @@
8use std::iter; 8use std::iter;
9use std::sync::Arc; 9use std::sync::Arc;
10 10
11use super::{FnSig, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor}; 11use super::{
12 FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
13};
12use crate::{ 14use crate::{
13 adt::VariantDef, 15 adt::VariantDef,
14 generics::HasGenericParams, 16 generics::HasGenericParams,
@@ -62,7 +64,9 @@ impl Ty {
62 let self_ty = Ty::Bound(0); 64 let self_ty = Ty::Bound(0);
63 let predicates = bounds 65 let predicates = bounds
64 .iter() 66 .iter()
65 .map(|b| GenericPredicate::from_type_bound(db, resolver, b, self_ty.clone())) 67 .flat_map(|b| {
68 GenericPredicate::from_type_bound(db, resolver, b, self_ty.clone())
69 })
66 .collect::<Vec<_>>(); 70 .collect::<Vec<_>>();
67 Ty::Dyn(predicates.into()) 71 Ty::Dyn(predicates.into())
68 } 72 }
@@ -70,7 +74,9 @@ impl Ty {
70 let self_ty = Ty::Bound(0); 74 let self_ty = Ty::Bound(0);
71 let predicates = bounds 75 let predicates = bounds
72 .iter() 76 .iter()
73 .map(|b| GenericPredicate::from_type_bound(db, resolver, b, self_ty.clone())) 77 .flat_map(|b| {
78 GenericPredicate::from_type_bound(db, resolver, b, self_ty.clone())
79 })
74 .collect::<Vec<_>>(); 80 .collect::<Vec<_>>();
75 Ty::Opaque(predicates.into()) 81 Ty::Opaque(predicates.into())
76 } 82 }
@@ -326,15 +332,6 @@ impl TraitRef {
326 TraitRef { trait_, substs } 332 TraitRef { trait_, substs }
327 } 333 }
328 334
329 pub(crate) fn from_where_predicate(
330 db: &impl HirDatabase,
331 resolver: &Resolver,
332 pred: &WherePredicate,
333 ) -> Option<TraitRef> {
334 let self_ty = Ty::from_hir(db, resolver, &pred.type_ref);
335 TraitRef::from_type_bound(db, resolver, &pred.bound, self_ty)
336 }
337
338 pub(crate) fn from_type_bound( 335 pub(crate) fn from_type_bound(
339 db: &impl HirDatabase, 336 db: &impl HirDatabase,
340 resolver: &Resolver, 337 resolver: &Resolver,
@@ -349,26 +346,58 @@ impl TraitRef {
349} 346}
350 347
351impl GenericPredicate { 348impl GenericPredicate {
352 pub(crate) fn from_where_predicate( 349 pub(crate) fn from_where_predicate<'a>(
353 db: &impl HirDatabase, 350 db: &'a impl HirDatabase,
354 resolver: &Resolver, 351 resolver: &'a Resolver,
355 where_predicate: &WherePredicate, 352 where_predicate: &'a WherePredicate,
356 ) -> GenericPredicate { 353 ) -> impl Iterator<Item = GenericPredicate> + 'a {
357 TraitRef::from_where_predicate(db, &resolver, where_predicate) 354 let self_ty = Ty::from_hir(db, resolver, &where_predicate.type_ref);
358 .map_or(GenericPredicate::Error, GenericPredicate::Implemented) 355 GenericPredicate::from_type_bound(db, resolver, &where_predicate.bound, self_ty)
359 } 356 }
360 357
361 pub(crate) fn from_type_bound( 358 pub(crate) fn from_type_bound<'a>(
362 db: &impl HirDatabase, 359 db: &'a impl HirDatabase,
363 resolver: &Resolver, 360 resolver: &'a Resolver,
364 bound: &TypeBound, 361 bound: &'a TypeBound,
365 self_ty: Ty, 362 self_ty: Ty,
366 ) -> GenericPredicate { 363 ) -> impl Iterator<Item = GenericPredicate> + 'a {
367 TraitRef::from_type_bound(db, &resolver, bound, self_ty) 364 let trait_ref = TraitRef::from_type_bound(db, &resolver, bound, self_ty);
368 .map_or(GenericPredicate::Error, GenericPredicate::Implemented) 365 iter::once(trait_ref.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented))
366 .chain(
367 trait_ref.into_iter().flat_map(move |tr| {
368 assoc_type_bindings_from_type_bound(db, resolver, bound, tr)
369 }),
370 )
369 } 371 }
370} 372}
371 373
374fn assoc_type_bindings_from_type_bound<'a>(
375 db: &'a impl HirDatabase,
376 resolver: &'a Resolver,
377 bound: &'a TypeBound,
378 trait_ref: TraitRef,
379) -> impl Iterator<Item = GenericPredicate> + 'a {
380 let last_segment = match bound {
381 TypeBound::Path(path) => path.segments.last(),
382 TypeBound::Error => None,
383 };
384 last_segment
385 .into_iter()
386 .flat_map(|segment| segment.args_and_bindings.iter())
387 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter())
388 .map(move |(name, type_ref)| {
389 let associated_ty = match trait_ref.trait_.associated_type_by_name(db, name.clone()) {
390 None => return GenericPredicate::Error,
391 Some(t) => t,
392 };
393 let projection_ty =
394 ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() };
395 let ty = Ty::from_hir(db, resolver, type_ref);
396 let projection_predicate = ProjectionPredicate { projection_ty, ty };
397 GenericPredicate::Projection(projection_predicate)
398 })
399}
400
372/// Build the declared type of an item. This depends on the namespace; e.g. for 401/// Build the declared type of an item. This depends on the namespace; e.g. for
373/// `struct Foo(usize)`, we have two types: The type of the struct itself, and 402/// `struct Foo(usize)`, we have two types: The type of the struct itself, and
374/// the constructor function `(usize) -> Foo` which lives in the values 403/// the constructor function `(usize) -> Foo` which lives in the values
@@ -425,7 +454,7 @@ pub(crate) fn trait_env(
425) -> Arc<super::TraitEnvironment> { 454) -> Arc<super::TraitEnvironment> {
426 let predicates = resolver 455 let predicates = resolver
427 .where_predicates_in_scope() 456 .where_predicates_in_scope()
428 .map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) 457 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
429 .collect::<Vec<_>>(); 458 .collect::<Vec<_>>();
430 459
431 Arc::new(super::TraitEnvironment { predicates }) 460 Arc::new(super::TraitEnvironment { predicates })
@@ -439,7 +468,7 @@ pub(crate) fn generic_predicates_query(
439 let resolver = def.resolver(db); 468 let resolver = def.resolver(db);
440 let predicates = resolver 469 let predicates = resolver
441 .where_predicates_in_scope() 470 .where_predicates_in_scope()
442 .map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) 471 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
443 .collect::<Vec<_>>(); 472 .collect::<Vec<_>>();
444 predicates.into() 473 predicates.into()
445} 474}
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 42bcae157..3e743ef58 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -3586,37 +3586,63 @@ fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) {
3586 [166; 169) '{t}': T 3586 [166; 169) '{t}': T
3587 [167; 168) 't': T 3587 [167; 168) 't': T
3588 [257; 258) 'x': T 3588 [257; 258) 'x': T
3589 [263; 264) 'y': impl Trait 3589 [263; 264) 'y': impl Trait +
3590 [290; 398) '{ ...r>); }': () 3590 [290; 398) '{ ...r>); }': ()
3591 [296; 299) 'get': fn get<T>(T) -> <T as Trait>::Type 3591 [296; 299) 'get': fn get<T>(T) -> <T as Trait>::Type
3592 [296; 302) 'get(x)': {unknown} 3592 [296; 302) 'get(x)': {unknown}
3593 [300; 301) 'x': T 3593 [300; 301) 'x': T
3594 [308; 312) 'get2': fn get2<{unknown}, T>(T) -> U 3594 [308; 312) 'get2': fn get2<{unknown}, S<{unknown}>>(T) -> U
3595 [308; 315) 'get2(x)': {unknown} 3595 [308; 315) 'get2(x)': {unknown}
3596 [313; 314) 'x': T 3596 [313; 314) 'x': T
3597 [321; 324) 'get': fn get<impl Trait>(T) -> <T as Trait>::Type 3597 [321; 324) 'get': fn get<impl Trait + >(T) -> <T as Trait>::Type
3598 [321; 327) 'get(y)': {unknown} 3598 [321; 327) 'get(y)': {unknown}
3599 [325; 326) 'y': impl Trait 3599 [325; 326) 'y': impl Trait +
3600 [333; 337) 'get2': fn get2<{unknown}, impl Trait>(T) -> U 3600 [333; 337) 'get2': fn get2<{unknown}, S<{unknown}>>(T) -> U
3601 [333; 340) 'get2(y)': {unknown} 3601 [333; 340) 'get2(y)': {unknown}
3602 [338; 339) 'y': impl Trait 3602 [338; 339) 'y': impl Trait +
3603 [346; 349) 'get': fn get<S<{unknown}>>(T) -> <T as Trait>::Type 3603 [346; 349) 'get': fn get<S<u64>>(T) -> <T as Trait>::Type
3604 [346; 357) 'get(set(S))': {unknown} 3604 [346; 357) 'get(set(S))': u64
3605 [350; 353) 'set': fn set<S<{unknown}>>(T) -> T 3605 [350; 353) 'set': fn set<S<u64>>(T) -> T
3606 [350; 356) 'set(S)': S<{unknown}> 3606 [350; 356) 'set(S)': S<u64>
3607 [354; 355) 'S': S<{unknown}> 3607 [354; 355) 'S': S<u64>
3608 [363; 367) 'get2': fn get2<{unknown}, S<{unknown}>>(T) -> U 3608 [363; 367) 'get2': fn get2<u64, S<u64>>(T) -> U
3609 [363; 375) 'get2(set(S))': {unknown} 3609 [363; 375) 'get2(set(S))': u64
3610 [368; 371) 'set': fn set<S<{unknown}>>(T) -> T 3610 [368; 371) 'set': fn set<S<u64>>(T) -> T
3611 [368; 374) 'set(S)': S<{unknown}> 3611 [368; 374) 'set(S)': S<u64>
3612 [372; 373) 'S': S<{unknown}> 3612 [372; 373) 'S': S<u64>
3613 [381; 385) 'get2': fn get2<{unknown}, S<str>>(T) -> U 3613 [381; 385) 'get2': fn get2<str, S<str>>(T) -> U
3614 [381; 395) 'get2(S::<str>)': {unknown} 3614 [381; 395) 'get2(S::<str>)': str
3615 [386; 394) 'S::<str>': S<str> 3615 [386; 394) 'S::<str>': S<str>
3616 "### 3616 "###
3617 ); 3617 );
3618} 3618}
3619 3619
3620#[test]
3621fn projection_eq_within_chalk() {
3622 // std::env::set_var("CHALK_DEBUG", "1");
3623 assert_snapshot!(
3624 infer(r#"
3625trait Trait1 {
3626 type Type;
3627}
3628trait Trait2<T> {
3629 fn foo(self) -> T;
3630}
3631impl<T, U> Trait2<T> for U where U: Trait1<Type = T> {}
3632
3633fn test<T: Trait1<Type = u32>>(x: T) {
3634 x.foo();
3635}
3636"#),
3637 @r###"
3638 [62; 66) 'self': Self
3639 [164; 165) 'x': T
3640 [170; 186) '{ ...o(); }': ()
3641 [176; 177) 'x': T
3642 [176; 183) 'x.foo()': {unknown}
3643 "###
3644 );
3645}
3620fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { 3646fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String {
3621 let file = db.parse(pos.file_id).ok().unwrap(); 3647 let file = db.parse(pos.file_id).ok().unwrap();
3622 let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); 3648 let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap();
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs
index b634f0b79..25316bc02 100644
--- a/crates/ra_hir/src/ty/traits.rs
+++ b/crates/ra_hir/src/ty/traits.rs
@@ -124,6 +124,9 @@ impl Obligation {
124 pub fn from_predicate(predicate: GenericPredicate) -> Option<Obligation> { 124 pub fn from_predicate(predicate: GenericPredicate) -> Option<Obligation> {
125 match predicate { 125 match predicate {
126 GenericPredicate::Implemented(trait_ref) => Some(Obligation::Trait(trait_ref)), 126 GenericPredicate::Implemented(trait_ref) => Some(Obligation::Trait(trait_ref)),
127 GenericPredicate::Projection(projection_pred) => {
128 Some(Obligation::Projection(projection_pred))
129 }
127 GenericPredicate::Error => None, 130 GenericPredicate::Error => None,
128 } 131 }
129 } 132 }
@@ -135,6 +138,30 @@ pub struct ProjectionPredicate {
135 pub ty: Ty, 138 pub ty: Ty,
136} 139}
137 140
141impl ProjectionPredicate {
142 pub fn subst(mut self, substs: &super::Substs) -> ProjectionPredicate {
143 self.walk_mut(&mut |ty| match ty {
144 Ty::Param { idx, .. } => {
145 if let Some(t) = substs.get(*idx as usize).cloned() {
146 *ty = t;
147 }
148 }
149 _ => {}
150 });
151 self
152 }
153
154 pub fn walk(&self, f: &mut impl FnMut(&Ty)) {
155 self.projection_ty.walk(f);
156 self.ty.walk(f);
157 }
158
159 pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
160 self.projection_ty.walk_mut(f);
161 self.ty.walk_mut(f);
162 }
163}
164
138/// Solve a trait goal using Chalk. 165/// Solve a trait goal using Chalk.
139pub(crate) fn trait_solve_query( 166pub(crate) fn trait_solve_query(
140 db: &impl HirDatabase, 167 db: &impl HirDatabase,
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 2ebc06135..3ab5b7cca 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -211,6 +211,13 @@ impl ToChalk for GenericPredicate {
211 GenericPredicate::Implemented(trait_ref) => { 211 GenericPredicate::Implemented(trait_ref) => {
212 make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0) 212 make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0)
213 } 213 }
214 GenericPredicate::Projection(projection_pred) => make_binders(
215 chalk_ir::WhereClause::ProjectionEq(chalk_ir::ProjectionEq {
216 projection: projection_pred.projection_ty.to_chalk(db),
217 ty: projection_pred.ty.to_chalk(db),
218 }),
219 0,
220 ),
214 GenericPredicate::Error => { 221 GenericPredicate::Error => {
215 let impossible_trait_ref = chalk_ir::TraitRef { 222 let impossible_trait_ref = chalk_ir::TraitRef {
216 trait_id: UNKNOWN_TRAIT, 223 trait_id: UNKNOWN_TRAIT,