@@ -147,12 +147,14 @@ import std::smallintmap::smallintmap;
147
147
import std:: smallintmap:: map;
148
148
import std:: map:: hashmap;
149
149
import middle:: ty;
150
- import middle:: ty:: { ty_vid, region_vid, vid} ;
151
- import syntax:: ast;
150
+ import middle:: ty:: { ty_vid, tys_in_fn_ty , region_vid, vid} ;
151
+ import syntax:: { ast, ast_util } ;
152
152
import syntax:: ast:: { ret_style} ;
153
153
import util:: ppaux:: { ty_to_str, mt_to_str} ;
154
154
import result:: { result, extensions, ok, err, map, map2, iter2} ;
155
- import ty:: type_is_bot;
155
+ import ty:: { mk_fn, type_is_bot} ;
156
+ import check:: regionmanip:: { collect_bound_regions_in_tys,
157
+ replace_bound_regions} ;
156
158
import driver:: session:: session;
157
159
import util:: common:: { indent, indenter} ;
158
160
@@ -453,6 +455,18 @@ impl ty_and_region_var_methods for infer_ctxt {
453
455
fn next_region_var ( ) -> ty:: region {
454
456
ret ty:: re_var ( self . next_region_var_id ( ) ) ;
455
457
}
458
+
459
+ fn ty_to_str ( t : ty:: t ) -> str {
460
+ ty_to_str ( self . tcx ,
461
+ self . resolve_type_vars_if_possible ( t) )
462
+ }
463
+
464
+ fn resolve_type_vars_if_possible ( typ : ty:: t ) -> ty:: t {
465
+ alt infer:: resolve_deep ( self , typ, false ) {
466
+ result:: ok ( new_type) { ret new_type; }
467
+ result:: err ( _) { ret typ; }
468
+ }
469
+ }
456
470
}
457
471
458
472
impl unify_methods for infer_ctxt {
@@ -1579,6 +1593,67 @@ impl of combine for sub {
1579
1593
}
1580
1594
}
1581
1595
1596
+ fn fns( a: ty:: fn_ty, b: ty:: fn_ty) -> cres < ty:: fn_ty > {
1597
+ // Rather than checking the subtype relationship between `a` and `b`
1598
+ // as-is, we need to do some extra work here in order to make sure
1599
+ // that function subtyping works correctly with respect to regions
1600
+ // (issue #2263).
1601
+
1602
+ // First, we instantiate each bound region in the subtype with a fresh
1603
+ // region variable.
1604
+ let a_isr =
1605
+ collect_bound_regions_in_tys( self . tcx,
1606
+ @nil,
1607
+ tys_in_fn_ty( a) ) {
1608
+ |br|
1609
+ let rvar = self . infcx( ) . next_region_var( ) ;
1610
+ #debug[ "Bound region %s maps to %s" ,
1611
+ bound_region_to_str( self . tcx, br) ,
1612
+ region_to_str( self . tcx, rvar) ] ;
1613
+ rvar
1614
+ } ;
1615
+
1616
+ let a_ty = replace_bound_regions( self . tcx,
1617
+ ast_util:: dummy_sp( ) ,
1618
+ a_isr,
1619
+ mk_fn( self . tcx, a) ) ;
1620
+ #debug[ "a_ty: %s" , self . infcx( ) . ty_to_str( a_ty) ] ;
1621
+
1622
+ // Second, we instantiate each bound region in the supertype with a
1623
+ // fresh concrete region.
1624
+ let b_isr =
1625
+ collect_bound_regions_in_tys( self . tcx,
1626
+ @nil,
1627
+ tys_in_fn_ty( b) ) {
1628
+ |br| ty:: re_bound( br) } ;
1629
+ // FIXME: or maybe re_skolemized? What would that look like?
1630
+ // (issue #2263)
1631
+
1632
+ let b_ty = replace_bound_regions( self . tcx,
1633
+ ast_util:: dummy_sp( ) ,
1634
+ b_isr,
1635
+ mk_fn( self . tcx, b) ) ;
1636
+ #debug[ "b_ty: %s" , self . infcx( ) . ty_to_str( b_ty) ] ;
1637
+
1638
+ // Turn back into ty::fn_ty.
1639
+ alt ( ty:: get( a_ty) . struct , ty:: get( b_ty) . struct ) {
1640
+ ( ty:: ty_fn( a_fn_ty) , ty:: ty_fn( b_fn_ty) ) {
1641
+ // Try to compare the supertype and subtype now that they've been
1642
+ // instantiated.
1643
+ super_fns( self , a_fn_ty, b_fn_ty)
1644
+
1645
+ }
1646
+ _ {
1647
+ // Shouldn't happen.
1648
+ self . infcx( ) . tcx. sess. bug(
1649
+ #fmt[ "%s: at least one of %s and %s isn't a fn_ty" ,
1650
+ self . tag( ) ,
1651
+ self . infcx( ) . ty_to_str( a_ty) ,
1652
+ self . infcx( ) . ty_to_str( b_ty) ] ) ;
1653
+ }
1654
+ }
1655
+ }
1656
+
1582
1657
// Traits please:
1583
1658
1584
1659
fn flds( a: ty:: field, b: ty:: field) -> cres < ty:: field > {
@@ -1598,10 +1673,6 @@ impl of combine for sub {
1598
1673
super_args( self , a, b)
1599
1674
}
1600
1675
1601
- fn fns( a: ty:: fn_ty, b: ty:: fn_ty) -> cres < ty:: fn_ty > {
1602
- super_fns( self , a, b)
1603
- }
1604
-
1605
1676
fn substs( as: ty:: substs, bs: ty:: substs) -> cres < ty:: substs > {
1606
1677
super_substs( self , as, bs)
1607
1678
}
0 commit comments