Skip to content

Commit f5c6a23

Browse files
committed
Various simplifications and renamings based on the fact that old-school closures are gone and type parameters can now have multiple region bounds (and hence use a different path). Should have no effect on the external behavior of the compiler.
1 parent 931a3c4 commit f5c6a23

File tree

5 files changed

+94
-113
lines changed

5 files changed

+94
-113
lines changed

src/librustc/middle/ty.rs

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5896,42 +5896,13 @@ pub fn each_bound_trait_and_supertraits<'tcx, F>(tcx: &ctxt<'tcx>,
58965896
return true;
58975897
}
58985898

5899-
pub fn object_region_bounds<'tcx>(
5900-
tcx: &ctxt<'tcx>,
5901-
opt_principal: Option<&PolyTraitRef<'tcx>>, // None for closures
5902-
others: BuiltinBounds)
5903-
-> Vec<ty::Region>
5904-
{
5905-
// Since we don't actually *know* the self type for an object,
5906-
// this "open(err)" serves as a kind of dummy standin -- basically
5907-
// a skolemized type.
5908-
let open_ty = ty::mk_infer(tcx, FreshTy(0));
5909-
5910-
let opt_trait_ref = opt_principal.map_or(Vec::new(), |principal| {
5911-
// Note that we preserve the overall binding levels here.
5912-
assert!(!open_ty.has_escaping_regions());
5913-
let substs = tcx.mk_substs(principal.0.substs.with_self_ty(open_ty));
5914-
vec!(ty::Binder(Rc::new(ty::TraitRef::new(principal.0.def_id, substs))))
5915-
});
5916-
5917-
let param_bounds = ty::ParamBounds {
5918-
region_bounds: Vec::new(),
5919-
builtin_bounds: others,
5920-
trait_bounds: opt_trait_ref,
5921-
projection_bounds: Vec::new(), // not relevant to computing region bounds
5922-
};
5923-
5924-
let predicates = ty::predicates(tcx, open_ty, &param_bounds);
5925-
ty::required_region_bounds(tcx, open_ty, predicates)
5926-
}
5927-
59285899
/// Given a set of predicates that apply to an object type, returns
59295900
/// the region bounds that the (erased) `Self` type must
59305901
/// outlive. Precisely *because* the `Self` type is erased, the
59315902
/// parameter `erased_self_ty` must be supplied to indicate what type
59325903
/// has been used to represent `Self` in the predicates
59335904
/// themselves. This should really be a unique type; `FreshTy(0)` is a
5934-
/// popular choice (see `object_region_bounds` above).
5905+
/// popular choice.
59355906
///
59365907
/// Requires that trait definitions have been processed so that we can
59375908
/// elaborate predicates and walk supertraits.

src/librustc_typeck/astconv.rs

Lines changed: 70 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ use middle::resolve_lifetime as rl;
5555
use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
5656
use middle::traits;
5757
use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty};
58-
use rscope::{self, UnelidableRscope, RegionScope, SpecificRscope,
58+
use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope,
5959
ShiftedRscope, BindingRscope};
6060
use TypeAndSubsts;
6161
use 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

15741571
pub 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

16961702
pub struct PartitionedBounds<'a> {

src/librustc_typeck/check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1890,7 +1890,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18901890
}
18911891

18921892
impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
1893-
fn default_region_bound(&self, span: Span) -> Option<ty::Region> {
1893+
fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
18941894
Some(self.infcx().next_region_var(infer::MiscVariable(span)))
18951895
}
18961896

src/librustc_typeck/check/regionmanip.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
pub use self::WfConstraint::*;
1414

15+
use astconv::object_region_bounds;
1516
use middle::infer::GenericKind;
1617
use middle::subst::{ParamSpace, Subst, Substs};
1718
use middle::ty::{self, Ty};
@@ -95,7 +96,7 @@ impl<'a, 'tcx> Wf<'a, 'tcx> {
9596

9697
ty::ty_trait(ref t) => {
9798
let required_region_bounds =
98-
ty::object_region_bounds(self.tcx, Some(&t.principal), t.bounds.builtin_bounds);
99+
object_region_bounds(self.tcx, &t.principal, t.bounds.builtin_bounds);
99100
self.accumulate_from_object_ty(ty, t.bounds.region_bound, required_region_bounds)
100101
}
101102

src/librustc_typeck/rscope.rs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ pub trait RegionScope {
3232
count: uint)
3333
-> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>>;
3434

35-
fn default_region_bound(&self, span: Span) -> Option<ty::Region>;
35+
/// If an object omits any explicit lifetime bound, and none can
36+
/// be derived from the object traits, what should we use? If
37+
/// `None` is returned, an explicit annotation is required.
38+
fn object_lifetime_default(&self, span: Span) -> Option<ty::Region>;
3639
}
3740

3841
// A scope in which all regions must be explicitly named. This is used
@@ -41,7 +44,7 @@ pub trait RegionScope {
4144
pub struct ExplicitRscope;
4245

4346
impl RegionScope for ExplicitRscope {
44-
fn default_region_bound(&self, _span: Span) -> Option<ty::Region> {
47+
fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
4548
None
4649
}
4750

@@ -63,7 +66,7 @@ impl UnelidableRscope {
6366
}
6467

6568
impl RegionScope for UnelidableRscope {
66-
fn default_region_bound(&self, _span: Span) -> Option<ty::Region> {
69+
fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
6770
None
6871
}
6972

@@ -76,21 +79,22 @@ impl RegionScope for UnelidableRscope {
7679
}
7780
}
7881

79-
// A scope in which any omitted region defaults to `default`. This is
80-
// used after the `->` in function signatures, but also for backwards
81-
// compatibility with object types. The latter use may go away.
82-
pub struct SpecificRscope {
83-
default: ty::Region
82+
// A scope in which omitted anonymous region defaults to
83+
// `default`. This is used after the `->` in function signatures. The
84+
// latter use may go away. Note that object-lifetime defaults work a
85+
// bit differently, as specified in RFC #599.
86+
pub struct ElidableRscope {
87+
default: ty::Region,
8488
}
8589

86-
impl SpecificRscope {
87-
pub fn new(r: ty::Region) -> SpecificRscope {
88-
SpecificRscope { default: r }
90+
impl ElidableRscope {
91+
pub fn new(r: ty::Region) -> ElidableRscope {
92+
ElidableRscope { default: r }
8993
}
9094
}
9195

92-
impl RegionScope for SpecificRscope {
93-
fn default_region_bound(&self, _span: Span) -> Option<ty::Region> {
96+
impl RegionScope for ElidableRscope {
97+
fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
9498
Some(self.default)
9599
}
96100

@@ -124,7 +128,7 @@ impl BindingRscope {
124128
}
125129

126130
impl RegionScope for BindingRscope {
127-
fn default_region_bound(&self, _span: Span) -> Option<ty::Region>
131+
fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region>
128132
{
129133
Some(self.next_region())
130134
}
@@ -151,9 +155,8 @@ impl<'r> ShiftedRscope<'r> {
151155
}
152156

153157
impl<'r> RegionScope for ShiftedRscope<'r> {
154-
fn default_region_bound(&self, span: Span) -> Option<ty::Region>
155-
{
156-
self.base_scope.default_region_bound(span)
158+
fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
159+
self.base_scope.object_lifetime_default(span)
157160
.map(|r| ty_fold::shift_region(r, 1))
158161
}
159162

0 commit comments

Comments
 (0)