@@ -222,7 +222,7 @@ pub trait Combine<'tcx> {
222
222
} ;
223
223
let unsafety = try!( self . unsafeties ( a. unsafety , b. unsafety ) ) ;
224
224
let onceness = try!( self . oncenesses ( a. onceness , b. onceness ) ) ;
225
- let bounds = try!( self . existential_bounds ( a. bounds , b. bounds ) ) ;
225
+ let bounds = try!( self . existential_bounds ( & a. bounds , & b. bounds ) ) ;
226
226
let sig = try!( self . binders ( & a. sig , & b. sig ) ) ;
227
227
let abi = try!( self . abi ( a. abi , b. abi ) ) ;
228
228
Ok ( ty:: ClosureTy {
@@ -289,15 +289,61 @@ pub trait Combine<'tcx> {
289
289
290
290
fn oncenesses ( & self , a : Onceness , b : Onceness ) -> cres < ' tcx , Onceness > ;
291
291
292
+ fn projection_tys ( & self ,
293
+ a : & ty:: ProjectionTy < ' tcx > ,
294
+ b : & ty:: ProjectionTy < ' tcx > )
295
+ -> cres < ' tcx , ty:: ProjectionTy < ' tcx > >
296
+ {
297
+ if a. item_name != b. item_name {
298
+ Err ( ty:: terr_projection_name_mismatched (
299
+ expected_found ( self , a. item_name , b. item_name ) ) )
300
+ } else {
301
+ let trait_ref = try!( self . trait_refs ( & * a. trait_ref , & * b. trait_ref ) ) ;
302
+ Ok ( ty:: ProjectionTy { trait_ref : Rc :: new ( trait_ref) , item_name : a. item_name } )
303
+ }
304
+ }
305
+
306
+ fn projection_predicates ( & self ,
307
+ a : & ty:: ProjectionPredicate < ' tcx > ,
308
+ b : & ty:: ProjectionPredicate < ' tcx > )
309
+ -> cres < ' tcx , ty:: ProjectionPredicate < ' tcx > >
310
+ {
311
+ let projection_ty = try!( self . projection_tys ( & a. projection_ty , & b. projection_ty ) ) ;
312
+ let ty = try!( self . tys ( a. ty , b. ty ) ) ;
313
+ Ok ( ty:: ProjectionPredicate { projection_ty : projection_ty, ty : ty } )
314
+ }
315
+
316
+ fn projection_bounds ( & self ,
317
+ a : & Vec < ty:: PolyProjectionPredicate < ' tcx > > ,
318
+ b : & Vec < ty:: PolyProjectionPredicate < ' tcx > > )
319
+ -> cres < ' tcx , Vec < ty:: PolyProjectionPredicate < ' tcx > > >
320
+ {
321
+ // To be compatible, `a` and `b` must be for precisely the
322
+ // same set of traits and item names. We always require that
323
+ // projection bounds lists are sorted by trait-def-id and item-name,
324
+ // so we can just iterate through the lists pairwise, so long as they are the
325
+ // same length.
326
+ if a. len ( ) != b. len ( ) {
327
+ Err ( ty:: terr_projection_bounds_length ( expected_found ( self , a. len ( ) , b. len ( ) ) ) )
328
+ } else {
329
+ a. iter ( )
330
+ . zip ( b. iter ( ) )
331
+ . map ( |( a, b) | self . binders ( a, b) )
332
+ . collect ( )
333
+ }
334
+ }
335
+
292
336
fn existential_bounds ( & self ,
293
- a : ty:: ExistentialBounds ,
294
- b : ty:: ExistentialBounds )
295
- -> cres < ' tcx , ty:: ExistentialBounds >
337
+ a : & ty:: ExistentialBounds < ' tcx > ,
338
+ b : & ty:: ExistentialBounds < ' tcx > )
339
+ -> cres < ' tcx , ty:: ExistentialBounds < ' tcx > >
296
340
{
297
341
let r = try!( self . contraregions ( a. region_bound , b. region_bound ) ) ;
298
342
let nb = try!( self . builtin_bounds ( a. builtin_bounds , b. builtin_bounds ) ) ;
343
+ let pb = try!( self . projection_bounds ( & a. projection_bounds , & b. projection_bounds ) ) ;
299
344
Ok ( ty:: ExistentialBounds { region_bound : r,
300
- builtin_bounds : nb } )
345
+ builtin_bounds : nb,
346
+ projection_bounds : pb } )
301
347
}
302
348
303
349
fn builtin_bounds ( & self ,
@@ -381,6 +427,16 @@ impl<'tcx> Combineable<'tcx> for ty::TraitRef<'tcx> {
381
427
}
382
428
}
383
429
430
+ impl < ' tcx > Combineable < ' tcx > for ty:: ProjectionPredicate < ' tcx > {
431
+ fn combine < C : Combine < ' tcx > > ( combiner : & C ,
432
+ a : & ty:: ProjectionPredicate < ' tcx > ,
433
+ b : & ty:: ProjectionPredicate < ' tcx > )
434
+ -> cres < ' tcx , ty:: ProjectionPredicate < ' tcx > >
435
+ {
436
+ combiner. projection_predicates ( a, b)
437
+ }
438
+ }
439
+
384
440
impl < ' tcx > Combineable < ' tcx > for ty:: FnSig < ' tcx > {
385
441
fn combine < C : Combine < ' tcx > > ( combiner : & C ,
386
442
a : & ty:: FnSig < ' tcx > ,
@@ -496,7 +552,7 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
496
552
& ty:: ty_trait( ref b_) ) => {
497
553
debug ! ( "Trying to match traits {} and {}" , a, b) ;
498
554
let principal = try!( this. binders ( & a_. principal , & b_. principal ) ) ;
499
- let bounds = try!( this. existential_bounds ( a_. bounds , b_. bounds ) ) ;
555
+ let bounds = try!( this. existential_bounds ( & a_. bounds , & b_. bounds ) ) ;
500
556
Ok ( ty:: mk_trait ( tcx, principal, bounds) )
501
557
}
502
558
@@ -595,12 +651,8 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
595
651
}
596
652
597
653
( & ty:: ty_projection( ref a_data) , & ty:: ty_projection( ref b_data) ) => {
598
- if a_data. item_name == b_data. item_name {
599
- let trait_ref = try!( this. trait_refs ( & * a_data. trait_ref , & * b_data. trait_ref ) ) ;
600
- Ok ( ty:: mk_projection ( tcx, Rc :: new ( trait_ref) , a_data. item_name ) )
601
- } else {
602
- Err ( ty:: terr_sorts ( expected_found ( this, a, b) ) )
603
- }
654
+ let projection_ty = try!( this. projection_tys ( a_data, b_data) ) ;
655
+ Ok ( ty:: mk_projection ( tcx, projection_ty. trait_ref , projection_ty. item_name ) )
604
656
}
605
657
606
658
_ => Err ( ty:: terr_sorts ( expected_found ( this, a, b) ) )
0 commit comments