@@ -419,24 +419,9 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
419
419
infer:: AutoBorrow ( expr. span ) ) ;
420
420
}
421
421
}
422
- ty:: AutoObject ( ast:: BorrowedSigil , Some ( trait_region) , _, _, _, _) => {
423
- // Determine if we are casting `expr` to an trait
424
- // instance. If so, we have to be sure that the type of
425
- // the source obeys the trait's region bound.
426
- //
427
- // Note: there is a subtle point here concerning type
428
- // parameters. It is possible that the type of `source`
429
- // contains type parameters, which in turn may contain
430
- // regions that are not visible to us (only the caller
431
- // knows about them). The kind checker is ultimately
432
- // responsible for guaranteeing region safety in that
433
- // particular case. There is an extensive comment on the
434
- // function check_cast_for_escaping_regions() in kind.rs
435
- // explaining how it goes about doing that.
436
-
437
- let source_ty = rcx. fcx . expr_ty ( expr) ;
438
- constrain_regions_in_type ( rcx, trait_region,
439
- infer:: RelateObjectBound ( expr. span ) , source_ty) ;
422
+ ty:: AutoObject ( _, maybe_region, _, _, _, ref substs) => {
423
+ let source_ty = rcx. resolve_node_type ( expr. id ) ;
424
+ constrain_trait_cast ( rcx, expr, maybe_region, substs, source_ty) ;
440
425
}
441
426
_ => { }
442
427
}
@@ -540,13 +525,15 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
540
525
// explaining how it goes about doing that.
541
526
let target_ty = rcx. resolve_node_type ( expr. id ) ;
542
527
match ty:: get ( target_ty) . sty {
543
- ty:: ty_trait( ~ty:: TyTrait { store : ty :: RegionTraitStore ( trait_region ) , .. } ) => {
528
+ ty:: ty_trait( ~ty:: TyTrait { store : trait_store , substs : ref substs , .. } ) => {
544
529
let source_ty = rcx. resolve_expr_type_adjusted ( source) ;
545
- constrain_regions_in_type (
546
- rcx,
547
- trait_region,
548
- infer:: RelateObjectBound ( expr. span ) ,
549
- source_ty) ;
530
+
531
+ let trait_region = match trait_store {
532
+ ty:: RegionTraitStore ( r) => Some ( r) ,
533
+ ty:: UniqTraitStore => None
534
+ } ;
535
+
536
+ constrain_trait_cast ( rcx, expr, trait_region, substs, source_ty) ;
550
537
}
551
538
_ => ( )
552
539
}
@@ -933,6 +920,56 @@ fn constrain_index(rcx: &mut Rcx,
933
920
}
934
921
}
935
922
923
+ fn constrain_trait_cast ( rcx : & mut Rcx ,
924
+ expr : & ast:: Expr ,
925
+ trait_region : Option < ty:: Region > ,
926
+ trait_substs : & ty:: substs ,
927
+ source_ty : ty:: t ) {
928
+ // If we are casting `source` to a trait
929
+ // instance, we have to be sure that the type of
930
+ // the source obeys the trait's region bound.
931
+ //
932
+ // Note: there is a subtle point here concerning type
933
+ // parameters. It is possible that the type of `source`
934
+ // contains type parameters, which in turn may contain
935
+ // regions that are not visible to us (only the caller
936
+ // knows about them). The kind checker is ultimately
937
+ // responsible for guaranteeing region safety in that
938
+ // particular case. There is an extensive comment on the
939
+ // function check_cast_for_escaping_regions() in kind.rs
940
+ // explaining how it goes about doing that.
941
+
942
+ debug ! ( "constrain_trait_cast(expr={:?}, trait_region={:?}, trait_substs={:?}, source_ty={:?}" ,
943
+ expr, trait_region, trait_substs, ty:: get( source_ty) ) ;
944
+
945
+ let mut regions = Vec :: new ( ) ;
946
+
947
+ match trait_substs. regions {
948
+ ty:: NonerasedRegions ( ref regs) => {
949
+ for r in regs. iter ( ) {
950
+ regions. push ( * r) ;
951
+ }
952
+ }
953
+ ty:: ErasedRegions => ( )
954
+ }
955
+
956
+ match trait_region {
957
+ Some ( region) => {
958
+ regions. push ( region) ;
959
+ }
960
+ None => {
961
+ // casting to owned trait with no lifetime params in trait def
962
+ if regions. is_empty ( ) {
963
+ regions. push ( ty:: ReStatic ) ;
964
+ }
965
+ }
966
+ }
967
+
968
+ for r in regions. iter ( ) {
969
+ constrain_regions_in_type ( rcx, * r, infer:: RelateObjectBound ( expr. span ) , source_ty) ;
970
+ }
971
+ }
972
+
936
973
fn constrain_regions_in_type_of_node (
937
974
rcx : & mut Rcx ,
938
975
id : ast:: NodeId ,
0 commit comments