@@ -1373,23 +1373,28 @@ impl of combine for lub {
1373
1373
ok( ty:: re_static) // nothing lives longer than static
1374
1374
}
1375
1375
1376
- ( ty:: re_var( a_id) , ty:: re_var( b_id) ) {
1377
- lattice_vars( self , self . infcx( ) . rb,
1378
- a, a_id, b_id,
1379
- { |x, y| self . regions( x, y) } )
1380
- }
1381
-
1382
- ( ty:: re_var( v_id) , r) | ( r, ty:: re_var( v_id) ) {
1383
- lattice_var_t( self , self . infcx( ) . rb,
1384
- v_id, r,
1385
- { |x, y| self . regions( x, y) } )
1376
+ ( ty:: re_var( _) , _) | ( _, ty:: re_var( _) ) {
1377
+ lattice_rvars( self , a, b)
1386
1378
}
1387
1379
1388
- ( f @ ty:: re_free( f_id, f_br) , ty:: re_scope( s_id) ) |
1389
- ( ty:: re_scope( s_id) , f @ ty:: re_free( f_id, f_br) ) {
1390
- // for LUB, the scope is within the function and the free
1391
- // region is always a parameter to the method.
1392
- ok( f) // NDM--not so for nested functions
1380
+ ( f @ ty:: re_free( f_id, _) , ty:: re_scope( s_id) ) |
1381
+ ( ty:: re_scope( s_id) , f @ ty:: re_free( f_id, _) ) {
1382
+ // For LUB, generally the scope is within the fn and
1383
+ // the free region is a parameter to the fn. In that case,
1384
+ // the free region will always live as long as the fn,
1385
+ // which is longer than the scope.
1386
+ //
1387
+ // However, with nested fns, it can happen that the
1388
+ // scope surrounds the fn itself. In that case, we do
1389
+ // not know which will live longer---it depends on the
1390
+ // value provided for the free region in any given
1391
+ // call. And so we must just back off to re_static as
1392
+ // the LUB.
1393
+ let rm = self . infcx( ) . tcx. region_map;
1394
+ alt region:: nearest_common_ancestor( rm, f_id, s_id) {
1395
+ some( r_id) if r_id == f_id { ok( f) }
1396
+ _ { ok( ty:: re_static) }
1397
+ }
1393
1398
}
1394
1399
1395
1400
( ty:: re_scope( a_id) , ty:: re_scope( b_id) ) {
@@ -1399,7 +1404,7 @@ impl of combine for lub {
1399
1404
let rm = self . infcx( ) . tcx. region_map;
1400
1405
alt region:: nearest_common_ancestor( rm, a_id, b_id) {
1401
1406
some( r_id) { ok( ty:: re_scope( r_id) ) }
1402
- _ { err ( ty:: terr_regions_differ ( b , a ) ) }
1407
+ _ { ok ( ty:: re_static ) }
1403
1408
}
1404
1409
}
1405
1410
@@ -1414,7 +1419,7 @@ impl of combine for lub {
1414
1419
if a == b {
1415
1420
ok( a)
1416
1421
} else {
1417
- err ( ty:: terr_regions_differ ( b , a ) )
1422
+ ok ( ty:: re_static )
1418
1423
}
1419
1424
}
1420
1425
}
@@ -1551,24 +1556,26 @@ impl of combine for glb {
1551
1556
ok( r)
1552
1557
}
1553
1558
1554
- ( ty:: re_var( a_id) , ty:: re_var( b_id) ) {
1555
- lattice_vars( self , self . infcx( ) . rb,
1556
- a, a_id, b_id,
1557
- { |x, y| self . regions( x, y) } )
1558
- }
1559
-
1560
- ( ty:: re_var( v_id) , r) | ( r, ty:: re_var( v_id) ) {
1561
- lattice_var_t( self , self . infcx( ) . rb,
1562
- v_id, r,
1563
- { |x, y| self . regions( x, y) } )
1559
+ ( ty:: re_var( _) , _) | ( _, ty:: re_var( _) ) {
1560
+ lattice_rvars( self , a, b)
1564
1561
}
1565
1562
1566
- ( f @ ty:: re_free( f_id, f_br) , ty:: re_scope( s_id) ) |
1567
- ( ty:: re_scope( s_id) , f @ ty:: re_free( f_id, f_br) ) {
1568
- // for GLB, the scope is within the function and the free
1569
- // region is always a parameter to the method. So the GLB
1570
- // must be the scope.
1571
- ok( b) // NDM--not so for nested functions
1563
+ ( ty:: re_free( f_id, _) , s @ ty:: re_scope( s_id) ) |
1564
+ ( s @ ty:: re_scope( s_id) , ty:: re_free( f_id, _) ) {
1565
+ // For GLB, generally the scope is within the fn and
1566
+ // the free region is a parameter to the fn. In that case,
1567
+ // the scope is always shorter than the free region.
1568
+ //
1569
+ // However, with nested fns, it can happen that the
1570
+ // scope surrounds the fn itself. In that case, we do
1571
+ // not know which will live longer---it depends on the
1572
+ // value provided for the free region in any given
1573
+ // call. And so we cannot give a GLB.
1574
+ let rm = self . infcx( ) . tcx. region_map;
1575
+ alt region:: nearest_common_ancestor( rm, f_id, s_id) {
1576
+ some( r_id) if r_id == f_id { ok( s) }
1577
+ _ { err( ty:: terr_regions_differ( b, a) ) }
1578
+ }
1572
1579
}
1573
1580
1574
1581
( ty:: re_scope( a_id) , ty:: re_scope( b_id) ) {
@@ -1704,6 +1711,34 @@ fn lattice_tys<L:lattice_ops combine>(
1704
1711
}
1705
1712
}
1706
1713
1714
+ // Pull out some common code from LUB/GLB for handling region vars:
1715
+ fn lattice_rvars<L : lattice_ops combine>(
1716
+ self : L , a: ty:: region, b: ty:: region) -> cres<ty:: region> {
1717
+
1718
+ alt ( a, b) {
1719
+ ( ty:: re_var( a_id) , ty:: re_var( b_id) ) {
1720
+ lattice_vars( self , self . infcx( ) . rb,
1721
+ a, a_id, b_id,
1722
+ { |x, y| self . regions( x, y) } )
1723
+ }
1724
+
1725
+ ( ty:: re_var( v_id) , r) | ( r, ty:: re_var( v_id) ) {
1726
+ lattice_var_t( self , self . infcx( ) . rb,
1727
+ v_id, r,
1728
+ { |x, y| self . regions( x, y) } )
1729
+ }
1730
+
1731
+ _ {
1732
+ self . infcx( ) . tcx. sess. bug(
1733
+ #fmt[ "%s: lattice_rvars invoked with a=%s and b=%s, \
1734
+ neither of which are region variables",
1735
+ self . tag( ) ,
1736
+ a. to_str( self . infcx( ) ) ,
1737
+ b. to_str( self . infcx( ) ) ] ) ;
1738
+ }
1739
+ }
1740
+ }
1741
+
1707
1742
fn lattice_vars < V : copy vid, T : copy to_str st, L : lattice_ops combine> (
1708
1743
self : L , vb: vals_and_bindings < V , T > ,
1709
1744
a_t: T , a_vid: V , b_vid: V ,
0 commit comments