@@ -5,6 +5,7 @@ use fold::shift::Shift;
55use lalrpop_intern:: InternedString ;
66use std:: collections:: { BTreeMap , BTreeSet } ;
77use std:: sync:: Arc ;
8+ use std:: iter;
89
910#[ macro_use]
1011mod macros;
@@ -265,6 +266,19 @@ pub enum InlineBound {
265266 ProjectionEqBound ( ProjectionEqBound ) ,
266267}
267268
269+ impl InlineBound {
270+ /// Applies the `InlineBound` to `self_ty` and lowers to a [`DomainGoal`].
271+ ///
272+ /// Because an `InlineBound` not know anything about what it's binding, you
273+ /// must provide that type as `self_ty`.
274+ pub fn lower_with_self ( & self , self_ty : Ty ) -> Vec < DomainGoal > {
275+ match self {
276+ InlineBound :: TraitBound ( b) => b. lower_with_self ( self_ty) ,
277+ InlineBound :: ProjectionEqBound ( b) => b. lower_with_self ( self_ty) ,
278+ }
279+ }
280+ }
281+
268282/// Represents a trait bound on e.g. a type or type parameter.
269283/// Does not know anything about what it's binding.
270284#[ derive( Clone , Debug , PartialEq , Eq , Hash ) ]
@@ -273,6 +287,21 @@ pub struct TraitBound {
273287 crate args_no_self : Vec < Parameter > ,
274288}
275289
290+ impl TraitBound {
291+ pub fn lower_with_self ( & self , self_ty : Ty ) -> Vec < DomainGoal > {
292+ let trait_ref = self . as_trait_ref ( self_ty) ;
293+ vec ! [ DomainGoal :: Holds ( WhereClauseAtom :: Implemented ( trait_ref) ) ]
294+ }
295+
296+ fn as_trait_ref ( & self , self_ty : Ty ) -> TraitRef {
297+ let self_ty = ParameterKind :: Ty ( self_ty) ;
298+ TraitRef {
299+ trait_id : self . trait_id ,
300+ parameters : iter:: once ( self_ty) . chain ( self . args_no_self . iter ( ) . cloned ( ) ) . collect ( ) ,
301+ }
302+ }
303+ }
304+
276305/// Represents a projection equality bound on e.g. a type or type parameter.
277306/// Does not know anything about what it's binding.
278307#[ derive( Clone , Debug , PartialEq , Eq , Hash ) ]
@@ -284,6 +313,26 @@ pub struct ProjectionEqBound {
284313 crate value : Ty ,
285314}
286315
316+ impl ProjectionEqBound {
317+ pub fn lower_with_self ( & self , self_ty : Ty ) -> Vec < DomainGoal > {
318+ let trait_ref = self . trait_bound . as_trait_ref ( self_ty) ;
319+
320+ let mut parameters = self . parameters . clone ( ) ;
321+ parameters. extend ( trait_ref. parameters . clone ( ) ) ;
322+
323+ vec ! [
324+ DomainGoal :: Holds ( WhereClauseAtom :: Implemented ( trait_ref) ) ,
325+ DomainGoal :: Holds ( WhereClauseAtom :: ProjectionEq ( ProjectionEq {
326+ projection: ProjectionTy {
327+ associated_ty_id: self . associated_ty_id,
328+ parameters: parameters,
329+ } ,
330+ ty: self . value. clone( ) ,
331+ } ) )
332+ ]
333+ }
334+ }
335+
287336#[ derive( Clone , Debug , PartialEq , Eq , Hash ) ]
288337pub struct AssociatedTyDatum {
289338 /// The trait this associated type is defined in.
@@ -309,6 +358,27 @@ pub struct AssociatedTyDatum {
309358 crate where_clauses : Vec < QuantifiedDomainGoal > ,
310359}
311360
361+ impl AssociatedTyDatum {
362+ /// Returns the associated ty's bounds applied to the projection type, e.g.:
363+ ///
364+ /// ```notrust
365+ /// Implemented(<?0 as Foo>::Item<?1>: Sized)
366+ /// ```
367+ pub fn bounds_on_self ( & self ) -> Vec < DomainGoal > {
368+ let parameters = self . parameter_kinds
369+ . anonymize ( )
370+ . iter ( )
371+ . zip ( 0 ..)
372+ . map ( |p| p. to_parameter ( ) )
373+ . collect ( ) ;
374+ let self_ty = Ty :: Projection ( ProjectionTy {
375+ associated_ty_id : self . id ,
376+ parameters
377+ } ) ;
378+ self . bounds . iter ( ) . flat_map ( |b| b. lower_with_self ( self_ty. clone ( ) ) ) . collect ( )
379+ }
380+ }
381+
312382#[ derive( Clone , Debug , PartialEq , Eq , Hash ) ]
313383pub struct AssociatedTyValue {
314384 crate associated_ty_id : ItemId ,
0 commit comments