@@ -55,7 +55,7 @@ use middle::resolve_lifetime as rl;
55
55
use middle:: subst:: { FnSpace , TypeSpace , SelfSpace , Subst , Substs } ;
56
56
use middle:: traits;
57
57
use middle:: ty:: { self , RegionEscape , ToPolyTraitRef , Ty } ;
58
- use rscope:: { self , UnelidableRscope , RegionScope , SpecificRscope ,
58
+ use rscope:: { self , UnelidableRscope , RegionScope , ElidableRscope ,
59
59
ShiftedRscope , BindingRscope } ;
60
60
use TypeAndSubsts ;
61
61
use util:: common:: { ErrorReported , FN_OUTPUT_NAME } ;
@@ -465,7 +465,7 @@ fn convert_ty_with_lifetime_elision<'tcx>(this: &AstConv<'tcx>,
465
465
{
466
466
match implied_output_region {
467
467
Some ( implied_output_region) => {
468
- let rb = SpecificRscope :: new ( implied_output_region) ;
468
+ let rb = ElidableRscope :: new ( implied_output_region) ;
469
469
ast_ty_to_ty ( this, & rb, ty)
470
470
}
471
471
None => {
@@ -932,7 +932,7 @@ fn trait_ref_to_object_type<'tcx>(this: &AstConv<'tcx>,
932
932
let existential_bounds = conv_existential_bounds ( this,
933
933
rscope,
934
934
span,
935
- Some ( trait_ref. clone ( ) ) ,
935
+ trait_ref. clone ( ) ,
936
936
projection_bounds,
937
937
bounds) ;
938
938
@@ -1518,11 +1518,11 @@ pub fn ty_of_closure<'tcx>(
1518
1518
/// `ExistentialBounds` struct. The `main_trait_refs` argument specifies the `Foo` -- it is absent
1519
1519
/// for closures. Eventually this should all be normalized, I think, so that there is no "main
1520
1520
/// trait ref" and instead we just have a flat list of bounds as the existential type.
1521
- pub fn conv_existential_bounds < ' tcx > (
1521
+ fn conv_existential_bounds < ' tcx > (
1522
1522
this : & AstConv < ' tcx > ,
1523
1523
rscope : & RegionScope ,
1524
1524
span : Span ,
1525
- principal_trait_ref : Option < ty:: PolyTraitRef < ' tcx > > , // None for boxed closures
1525
+ principal_trait_ref : ty:: PolyTraitRef < ' tcx > ,
1526
1526
projection_bounds : Vec < ty:: PolyProjectionPredicate < ' tcx > > ,
1527
1527
ast_bounds : & [ ast:: TyParamBound ] )
1528
1528
-> ty:: ExistentialBounds < ' tcx >
@@ -1546,15 +1546,15 @@ fn conv_ty_poly_trait_ref<'tcx>(
1546
1546
let mut projection_bounds = Vec :: new ( ) ;
1547
1547
let main_trait_bound = if !partitioned_bounds. trait_bounds . is_empty ( ) {
1548
1548
let trait_bound = partitioned_bounds. trait_bounds . remove ( 0 ) ;
1549
- Some ( instantiate_poly_trait_ref ( this,
1550
- rscope,
1551
- trait_bound,
1552
- None ,
1553
- & mut projection_bounds) )
1549
+ instantiate_poly_trait_ref ( this,
1550
+ rscope,
1551
+ trait_bound,
1552
+ None ,
1553
+ & mut projection_bounds)
1554
1554
} else {
1555
1555
span_err ! ( this. tcx( ) . sess, span, E0224 ,
1556
- "at least one non-builtin trait is required for an object type" ) ;
1557
- None
1556
+ "at least one non-builtin trait is required for an object type" ) ;
1557
+ return this . tcx ( ) . types . err ;
1558
1558
} ;
1559
1559
1560
1560
let bounds =
@@ -1565,17 +1565,14 @@ fn conv_ty_poly_trait_ref<'tcx>(
1565
1565
projection_bounds,
1566
1566
partitioned_bounds) ;
1567
1567
1568
- match main_trait_bound {
1569
- None => this. tcx ( ) . types . err ,
1570
- Some ( principal) => ty:: mk_trait ( this. tcx ( ) , principal, bounds)
1571
- }
1568
+ ty:: mk_trait ( this. tcx ( ) , main_trait_bound, bounds)
1572
1569
}
1573
1570
1574
1571
pub fn conv_existential_bounds_from_partitioned_bounds < ' tcx > (
1575
1572
this : & AstConv < ' tcx > ,
1576
1573
rscope : & RegionScope ,
1577
1574
span : Span ,
1578
- principal_trait_ref : Option < ty:: PolyTraitRef < ' tcx > > , // None for boxed closures
1575
+ principal_trait_ref : ty:: PolyTraitRef < ' tcx > ,
1579
1576
mut projection_bounds : Vec < ty:: PolyProjectionPredicate < ' tcx > > , // Empty for boxed closures
1580
1577
partitioned_bounds : PartitionedBounds )
1581
1578
-> ty:: ExistentialBounds < ' tcx >
@@ -1588,16 +1585,15 @@ pub fn conv_existential_bounds_from_partitioned_bounds<'tcx>(
1588
1585
if !trait_bounds. is_empty ( ) {
1589
1586
let b = & trait_bounds[ 0 ] ;
1590
1587
span_err ! ( this. tcx( ) . sess, b. trait_ref. path. span, E0225 ,
1591
- "only the builtin traits can be used \
1592
- as closure or object bounds") ;
1588
+ "only the builtin traits can be used as closure or object bounds" ) ;
1593
1589
}
1594
1590
1595
- let region_bound = compute_region_bound ( this,
1596
- rscope,
1597
- span,
1598
- & region_bounds,
1599
- principal_trait_ref,
1600
- builtin_bounds) ;
1591
+ let region_bound = compute_object_lifetime_bound ( this,
1592
+ rscope,
1593
+ span,
1594
+ & region_bounds,
1595
+ principal_trait_ref,
1596
+ builtin_bounds) ;
1601
1597
1602
1598
ty:: sort_bounds_list ( & mut projection_bounds) ;
1603
1599
@@ -1608,17 +1604,21 @@ pub fn conv_existential_bounds_from_partitioned_bounds<'tcx>(
1608
1604
}
1609
1605
}
1610
1606
1611
- /// Given the bounds on a type parameter / existential type , determines what single region bound
1607
+ /// Given the bounds on an object , determines what single region bound
1612
1608
/// (if any) we can use to summarize this type. The basic idea is that we will use the bound the
1613
1609
/// user provided, if they provided one, and otherwise search the supertypes of trait bounds for
1614
1610
/// region bounds. It may be that we can derive no bound at all, in which case we return `None`.
1615
- fn compute_opt_region_bound < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
1616
- span : Span ,
1617
- explicit_region_bounds : & [ & ast:: Lifetime ] ,
1618
- principal_trait_ref : Option < ty:: PolyTraitRef < ' tcx > > ,
1619
- builtin_bounds : ty:: BuiltinBounds )
1620
- -> Option < ty:: Region >
1611
+ fn compute_object_lifetime_bound < ' tcx > (
1612
+ this : & AstConv < ' tcx > ,
1613
+ rscope : & RegionScope ,
1614
+ span : Span ,
1615
+ explicit_region_bounds : & [ & ast:: Lifetime ] ,
1616
+ principal_trait_ref : ty:: PolyTraitRef < ' tcx > ,
1617
+ builtin_bounds : ty:: BuiltinBounds )
1618
+ -> ty:: Region
1621
1619
{
1620
+ let tcx = this. tcx ( ) ;
1621
+
1622
1622
debug ! ( "compute_opt_region_bound(explicit_region_bounds={:?}, \
1623
1623
principal_trait_ref={}, builtin_bounds={})",
1624
1624
explicit_region_bounds,
@@ -1633,24 +1633,32 @@ fn compute_opt_region_bound<'tcx>(tcx: &ty::ctxt<'tcx>,
1633
1633
if explicit_region_bounds. len ( ) != 0 {
1634
1634
// Explicitly specified region bound. Use that.
1635
1635
let r = explicit_region_bounds[ 0 ] ;
1636
- return Some ( ast_region_to_region ( tcx, r) ) ;
1636
+ return ast_region_to_region ( tcx, r) ;
1637
1637
}
1638
1638
1639
1639
// No explicit region bound specified. Therefore, examine trait
1640
1640
// bounds and see if we can derive region bounds from those.
1641
1641
let derived_region_bounds =
1642
- ty :: object_region_bounds ( tcx, principal_trait_ref. as_ref ( ) , builtin_bounds) ;
1642
+ object_region_bounds ( tcx, & principal_trait_ref, builtin_bounds) ;
1643
1643
1644
1644
// If there are no derived region bounds, then report back that we
1645
1645
// can find no region bound.
1646
1646
if derived_region_bounds. len ( ) == 0 {
1647
- return None ;
1647
+ match rscope. object_lifetime_default ( span) {
1648
+ Some ( r) => { return r; }
1649
+ None => {
1650
+ span_err ! ( this. tcx( ) . sess, span, E0228 ,
1651
+ "the lifetime bound for this object type cannot be deduced \
1652
+ from context; please supply an explicit bound") ;
1653
+ return ty:: ReStatic ;
1654
+ }
1655
+ }
1648
1656
}
1649
1657
1650
1658
// If any of the derived region bounds are 'static, that is always
1651
1659
// the best choice.
1652
1660
if derived_region_bounds. iter ( ) . any ( |r| ty:: ReStatic == * r) {
1653
- return Some ( ty:: ReStatic ) ;
1661
+ return ty:: ReStatic ;
1654
1662
}
1655
1663
1656
1664
// Determine whether there is exactly one unique region in the set
@@ -1659,38 +1667,36 @@ fn compute_opt_region_bound<'tcx>(tcx: &ty::ctxt<'tcx>,
1659
1667
let r = derived_region_bounds[ 0 ] ;
1660
1668
if derived_region_bounds[ 1 ..] . iter ( ) . any ( |r1| r != * r1) {
1661
1669
span_err ! ( tcx. sess, span, E0227 ,
1662
- "ambiguous lifetime bound, \
1663
- explicit lifetime bound required") ;
1670
+ "ambiguous lifetime bound, explicit lifetime bound required" ) ;
1664
1671
}
1665
- return Some ( r ) ;
1672
+ return r ;
1666
1673
}
1667
1674
1668
- /// A version of `compute_opt_region_bound` for use where some region bound is required
1669
- /// (existential types, basically). Reports an error if no region bound can be derived and we are
1670
- /// in an `rscope` that does not provide a default.
1671
- fn compute_region_bound < ' tcx > (
1672
- this : & AstConv < ' tcx > ,
1673
- rscope : & RegionScope ,
1674
- span : Span ,
1675
- region_bounds : & [ & ast:: Lifetime ] ,
1676
- principal_trait_ref : Option < ty:: PolyTraitRef < ' tcx > > , // None for closures
1677
- builtin_bounds : ty:: BuiltinBounds )
1678
- -> ty:: Region
1675
+ pub fn object_region_bounds < ' tcx > (
1676
+ tcx : & ty:: ctxt < ' tcx > ,
1677
+ principal : & ty:: PolyTraitRef < ' tcx > ,
1678
+ others : ty:: BuiltinBounds )
1679
+ -> Vec < ty:: Region >
1679
1680
{
1680
- match compute_opt_region_bound ( this. tcx ( ) , span, region_bounds,
1681
- principal_trait_ref, builtin_bounds) {
1682
- Some ( r) => r,
1683
- None => {
1684
- match rscope. default_region_bound ( span) {
1685
- Some ( r) => { r }
1686
- None => {
1687
- span_err ! ( this. tcx( ) . sess, span, E0228 ,
1688
- "explicit lifetime bound required" ) ;
1689
- ty:: ReStatic
1690
- }
1691
- }
1692
- }
1693
- }
1681
+ // Since we don't actually *know* the self type for an object,
1682
+ // this "open(err)" serves as a kind of dummy standin -- basically
1683
+ // a skolemized type.
1684
+ let open_ty = ty:: mk_infer ( tcx, ty:: FreshTy ( 0 ) ) ;
1685
+
1686
+ // Note that we preserve the overall binding levels here.
1687
+ assert ! ( !open_ty. has_escaping_regions( ) ) ;
1688
+ let substs = tcx. mk_substs ( principal. 0 . substs . with_self_ty ( open_ty) ) ;
1689
+ let trait_refs = vec ! ( ty:: Binder ( Rc :: new( ty:: TraitRef :: new( principal. 0 . def_id, substs) ) ) ) ;
1690
+
1691
+ let param_bounds = ty:: ParamBounds {
1692
+ region_bounds : Vec :: new ( ) ,
1693
+ builtin_bounds : others,
1694
+ trait_bounds : trait_refs,
1695
+ projection_bounds : Vec :: new ( ) , // not relevant to computing region bounds
1696
+ } ;
1697
+
1698
+ let predicates = ty:: predicates ( tcx, open_ty, & param_bounds) ;
1699
+ ty:: required_region_bounds ( tcx, open_ty, predicates)
1694
1700
}
1695
1701
1696
1702
pub struct PartitionedBounds < ' a > {
0 commit comments