@@ -55,7 +55,7 @@ use middle::resolve_lifetime as rl;
5555use middle:: subst:: { FnSpace , TypeSpace , SelfSpace , Subst , Substs } ;
5656use middle:: traits;
5757use middle:: ty:: { self , RegionEscape , ToPolyTraitRef , Ty } ;
58- use rscope:: { self , UnelidableRscope , RegionScope , SpecificRscope ,
58+ use rscope:: { self , UnelidableRscope , RegionScope , ElidableRscope ,
5959 ShiftedRscope , BindingRscope } ;
6060use TypeAndSubsts ;
6161use util:: common:: { ErrorReported , FN_OUTPUT_NAME } ;
@@ -465,7 +465,7 @@ fn convert_ty_with_lifetime_elision<'tcx>(this: &AstConv<'tcx>,
465465{
466466 match implied_output_region {
467467 Some ( implied_output_region) => {
468- let rb = SpecificRscope :: new ( implied_output_region) ;
468+ let rb = ElidableRscope :: new ( implied_output_region) ;
469469 ast_ty_to_ty ( this, & rb, ty)
470470 }
471471 None => {
@@ -932,7 +932,7 @@ fn trait_ref_to_object_type<'tcx>(this: &AstConv<'tcx>,
932932 let existential_bounds = conv_existential_bounds ( this,
933933 rscope,
934934 span,
935- Some ( trait_ref. clone ( ) ) ,
935+ trait_ref. clone ( ) ,
936936 projection_bounds,
937937 bounds) ;
938938
@@ -1518,11 +1518,11 @@ pub fn ty_of_closure<'tcx>(
15181518/// `ExistentialBounds` struct. The `main_trait_refs` argument specifies the `Foo` -- it is absent
15191519/// for closures. Eventually this should all be normalized, I think, so that there is no "main
15201520/// 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 > (
15221522 this : & AstConv < ' tcx > ,
15231523 rscope : & RegionScope ,
15241524 span : Span ,
1525- principal_trait_ref : Option < ty:: PolyTraitRef < ' tcx > > , // None for boxed closures
1525+ principal_trait_ref : ty:: PolyTraitRef < ' tcx > ,
15261526 projection_bounds : Vec < ty:: PolyProjectionPredicate < ' tcx > > ,
15271527 ast_bounds : & [ ast:: TyParamBound ] )
15281528 -> ty:: ExistentialBounds < ' tcx >
@@ -1546,15 +1546,15 @@ fn conv_ty_poly_trait_ref<'tcx>(
15461546 let mut projection_bounds = Vec :: new ( ) ;
15471547 let main_trait_bound = if !partitioned_bounds. trait_bounds . is_empty ( ) {
15481548 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)
15541554 } else {
15551555 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 ;
15581558 } ;
15591559
15601560 let bounds =
@@ -1565,17 +1565,14 @@ fn conv_ty_poly_trait_ref<'tcx>(
15651565 projection_bounds,
15661566 partitioned_bounds) ;
15671567
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)
15721569}
15731570
15741571pub fn conv_existential_bounds_from_partitioned_bounds < ' tcx > (
15751572 this : & AstConv < ' tcx > ,
15761573 rscope : & RegionScope ,
15771574 span : Span ,
1578- principal_trait_ref : Option < ty:: PolyTraitRef < ' tcx > > , // None for boxed closures
1575+ principal_trait_ref : ty:: PolyTraitRef < ' tcx > ,
15791576 mut projection_bounds : Vec < ty:: PolyProjectionPredicate < ' tcx > > , // Empty for boxed closures
15801577 partitioned_bounds : PartitionedBounds )
15811578 -> ty:: ExistentialBounds < ' tcx >
@@ -1588,16 +1585,15 @@ pub fn conv_existential_bounds_from_partitioned_bounds<'tcx>(
15881585 if !trait_bounds. is_empty ( ) {
15891586 let b = & trait_bounds[ 0 ] ;
15901587 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" ) ;
15931589 }
15941590
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) ;
16011597
16021598 ty:: sort_bounds_list ( & mut projection_bounds) ;
16031599
@@ -1608,17 +1604,21 @@ pub fn conv_existential_bounds_from_partitioned_bounds<'tcx>(
16081604 }
16091605}
16101606
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
16121608/// (if any) we can use to summarize this type. The basic idea is that we will use the bound the
16131609/// user provided, if they provided one, and otherwise search the supertypes of trait bounds for
16141610/// 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
16211619{
1620+ let tcx = this. tcx ( ) ;
1621+
16221622 debug ! ( "compute_opt_region_bound(explicit_region_bounds={:?}, \
16231623 principal_trait_ref={}, builtin_bounds={})",
16241624 explicit_region_bounds,
@@ -1633,24 +1633,32 @@ fn compute_opt_region_bound<'tcx>(tcx: &ty::ctxt<'tcx>,
16331633 if explicit_region_bounds. len ( ) != 0 {
16341634 // Explicitly specified region bound. Use that.
16351635 let r = explicit_region_bounds[ 0 ] ;
1636- return Some ( ast_region_to_region ( tcx, r) ) ;
1636+ return ast_region_to_region ( tcx, r) ;
16371637 }
16381638
16391639 // No explicit region bound specified. Therefore, examine trait
16401640 // bounds and see if we can derive region bounds from those.
16411641 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) ;
16431643
16441644 // If there are no derived region bounds, then report back that we
16451645 // can find no region bound.
16461646 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+ }
16481656 }
16491657
16501658 // If any of the derived region bounds are 'static, that is always
16511659 // the best choice.
16521660 if derived_region_bounds. iter ( ) . any ( |r| ty:: ReStatic == * r) {
1653- return Some ( ty:: ReStatic ) ;
1661+ return ty:: ReStatic ;
16541662 }
16551663
16561664 // 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>,
16591667 let r = derived_region_bounds[ 0 ] ;
16601668 if derived_region_bounds[ 1 ..] . iter ( ) . any ( |r1| r != * r1) {
16611669 span_err ! ( tcx. sess, span, E0227 ,
1662- "ambiguous lifetime bound, \
1663- explicit lifetime bound required") ;
1670+ "ambiguous lifetime bound, explicit lifetime bound required" ) ;
16641671 }
1665- return Some ( r ) ;
1672+ return r ;
16661673}
16671674
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 >
16791680{
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)
16941700}
16951701
16961702pub struct PartitionedBounds < ' a > {
0 commit comments