Skip to content

Commit 2278f95

Browse files
committed
rollup merge of #17310 : nikomatsakis/type-bounds-generalize-to-multiple-object-bounds
2 parents df34b08 + e86c87a commit 2278f95

File tree

11 files changed

+81
-18
lines changed

11 files changed

+81
-18
lines changed

src/librustc/metadata/tydecode.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -680,14 +680,14 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds {
680680
let builtin_bounds = parse_builtin_bounds(st, |x,y| conv(x,y));
681681

682682
let mut param_bounds = ty::ParamBounds {
683-
opt_region_bound: None,
683+
region_bounds: Vec::new(),
684684
builtin_bounds: builtin_bounds,
685685
trait_bounds: Vec::new()
686686
};
687687
loop {
688688
match next(st) {
689689
'R' => {
690-
param_bounds.opt_region_bound = Some(parse_region(st, |x, y| conv (x, y)));
690+
param_bounds.region_bounds.push(parse_region(st, |x, y| conv (x, y)));
691691
}
692692
'I' => {
693693
param_bounds.trait_bounds.push(Rc::new(parse_trait_ref(st, |x,y| conv(x,y))));

src/librustc/metadata/tyencode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ pub fn enc_existential_bounds(w: &mut SeekableMemWriter, cx: &ctxt, bs: &ty::Exi
366366
pub fn enc_bounds(w: &mut SeekableMemWriter, cx: &ctxt, bs: &ty::ParamBounds) {
367367
enc_builtin_bounds(w, cx, &bs.builtin_bounds);
368368

369-
for &r in bs.opt_region_bound.iter() {
369+
for &r in bs.region_bounds.iter() {
370370
mywrite!(w, "R");
371371
enc_region(w, cx, r);
372372
}

src/librustc/middle/ty.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,15 +1008,16 @@ pub enum type_err {
10081008
/// as well as the existential type parameter in an object type.
10091009
#[deriving(PartialEq, Eq, Hash, Clone, Show)]
10101010
pub struct ParamBounds {
1011-
pub opt_region_bound: Option<ty::Region>,
1011+
pub region_bounds: Vec<ty::Region>,
10121012
pub builtin_bounds: BuiltinBounds,
10131013
pub trait_bounds: Vec<Rc<TraitRef>>
10141014
}
10151015

10161016
/// Bounds suitable for an existentially quantified type parameter
10171017
/// such as those that appear in object types or closure types. The
10181018
/// major difference between this case and `ParamBounds` is that
1019-
/// general purpose trait bounds are omitted.
1019+
/// general purpose trait bounds are omitted and there must be
1020+
/// *exactly one* region.
10201021
#[deriving(PartialEq, Eq, Hash, Clone, Show)]
10211022
pub struct ExistentialBounds {
10221023
pub region_bound: ty::Region,
@@ -4865,7 +4866,7 @@ pub fn required_region_bounds(tcx: &ctxt,
48654866
trait_bounds,
48664867
|trait_ref| {
48674868
let bounds = ty::bounds_for_trait_ref(tcx, &*trait_ref);
4868-
push_region_bounds(bounds.opt_region_bound.as_slice(),
4869+
push_region_bounds(bounds.region_bounds.as_slice(),
48694870
bounds.builtin_bounds,
48704871
&mut all_bounds);
48714872
debug!("from {}: bounds={} all_bounds={}",

src/librustc/middle/ty_fold.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ impl TypeFoldable for ty::ExistentialBounds {
287287
impl TypeFoldable for ty::ParamBounds {
288288
fn fold_with<'tcx, F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::ParamBounds {
289289
ty::ParamBounds {
290-
opt_region_bound: self.opt_region_bound.fold_with(folder),
290+
region_bounds: self.region_bounds.fold_with(folder),
291291
builtin_bounds: self.builtin_bounds.fold_with(folder),
292292
trait_bounds: self.trait_bounds.fold_with(folder),
293293
}

src/librustc/middle/typeck/check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2005,7 +2005,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20052005
let region_bounds =
20062006
ty::required_region_bounds(
20072007
self.tcx(),
2008-
param_bound.opt_region_bound.as_slice(),
2008+
param_bound.region_bounds.as_slice(),
20092009
param_bound.builtin_bounds,
20102010
param_bound.trait_bounds.as_slice());
20112011
for &r in region_bounds.iter() {

src/librustc/middle/typeck/check/regionck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1880,7 +1880,7 @@ fn param_must_outlive(rcx: &Rcx,
18801880
let param_bound = param_env.bounds.get(param_ty.space, param_ty.idx);
18811881
param_bounds =
18821882
ty::required_region_bounds(rcx.tcx(),
1883-
param_bound.opt_region_bound.as_slice(),
1883+
param_bound.region_bounds.as_slice(),
18841884
param_bound.builtin_bounds,
18851885
param_bound.trait_bounds.as_slice());
18861886

src/librustc/middle/typeck/check/regionmanip.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ impl<'a, 'tcx> Wf<'a, 'tcx> {
327327

328328
// Inspect bounds on this type parameter for any
329329
// region bounds.
330-
for &r in type_param_def.bounds.opt_region_bound.iter() {
330+
for &r in type_param_def.bounds.region_bounds.iter() {
331331
self.stack.push((r, Some(ty)));
332332
self.accumulate_from_ty(type_param_ty);
333333
self.stack.pop().unwrap();

src/librustc/middle/typeck/collect.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,7 +1044,7 @@ fn ty_generics_for_trait(ccx: &CrateCtxt,
10441044
ident: special_idents::type_self,
10451045
def_id: local_def(param_id),
10461046
bounds: ty::ParamBounds {
1047-
opt_region_bound: None,
1047+
region_bounds: vec!(),
10481048
builtin_bounds: ty::empty_builtin_bounds(),
10491049
trait_bounds: vec!(self_trait_ref),
10501050
},
@@ -1280,12 +1280,12 @@ fn conv_param_bounds(ccx: &CrateCtxt,
12801280
.map(|b| instantiate_trait_ref(ccx, b, param_ty.to_ty(ccx.tcx)))
12811281
.chain(unboxed_fn_ty_bounds)
12821282
.collect();
1283-
let opt_region_bound =
1284-
astconv::compute_opt_region_bound(
1285-
ccx.tcx, span, builtin_bounds, region_bounds.as_slice(),
1286-
trait_bounds.as_slice());
1283+
let region_bounds: Vec<ty::Region> =
1284+
region_bounds.move_iter()
1285+
.map(|r| ast_region_to_region(ccx.tcx, r))
1286+
.collect();
12871287
ty::ParamBounds {
1288-
opt_region_bound: opt_region_bound,
1288+
region_bounds: region_bounds,
12891289
builtin_bounds: builtin_bounds,
12901290
trait_bounds: trait_bounds,
12911291
}

src/test/compile-fail/region-bounds-on-objects-and-type-parameters.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ fn test<
3535
'a,
3636
'b,
3737
A:IsStatic,
38-
B:Is<'a>+Is2<'b>, //~ ERROR ambiguous lifetime bound
38+
B:Is<'a>+Is2<'b>, // OK in a parameter, but not an object type.
3939
C:'b+Is<'a>+Is2<'b>,
4040
D:Is<'a>+Is2<'static>,
41-
E:'a+'b //~ ERROR only a single explicit lifetime bound is permitted
41+
E:'a+'b // OK in a parameter, but not an object type.
4242
>() { }
4343

4444
fn main() { }
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Various tests where we over type parameters with multiple lifetime
12+
// bounds.
13+
14+
trait SomeTrait { fn get(&self) -> int; }
15+
16+
fn make_object_good1<'a,'b,A:SomeTrait+'a+'b>(v: A) -> Box<SomeTrait+'a> {
17+
// A outlives 'a AND 'b...
18+
box v as Box<SomeTrait+'a> // ...hence this type is safe.
19+
}
20+
21+
fn make_object_good2<'a,'b,A:SomeTrait+'a+'b>(v: A) -> Box<SomeTrait+'b> {
22+
// A outlives 'a AND 'b...
23+
box v as Box<SomeTrait+'b> // ...hence this type is safe.
24+
}
25+
26+
fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<SomeTrait+'c> {
27+
// A outlives 'a AND 'b...but not 'c.
28+
box v as Box<SomeTrait+'a> //~ ERROR mismatched types
29+
}
30+
31+
fn main() {
32+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// A test where we (successfully) close over a reference into
12+
// an object.
13+
14+
trait SomeTrait { fn get(&self) -> int; }
15+
16+
impl<'a> SomeTrait for &'a int {
17+
fn get(&self) -> int {
18+
**self
19+
}
20+
}
21+
22+
fn make_object<'a,A:SomeTrait+'a>(v: A) -> Box<SomeTrait+'a> {
23+
box v as Box<SomeTrait+'a>
24+
}
25+
26+
fn main() {
27+
let i: int = 22;
28+
let obj = make_object(&i);
29+
assert_eq!(22, obj.get());
30+
}

0 commit comments

Comments
 (0)