Skip to content

Commit b516532

Browse files
committed
auto merge of #16453 : nikomatsakis/rust/type-bounds-3, r=pcwalton
Implements rust-lang/rfcs#192. In particular: 1. type parameters can have lifetime bounds and objects can close over borrowed values, presuming that they have suitable bounds. 2. objects must have a bound, though it may be derived from the trait itself or from a `Send` bound. 3. all types must be well-formed. 4. type parameters and lifetime parameters may themselves have lifetimes as bounds. Something like `T:'a` means "the type T outlives 'a`" and something like `'a:'b`" means "'a outlives 'b". Outlives here means "all borrowed data has a lifetime at least as long". This is a [breaking-change]. The most common things you have to fix after this change are: 1. Introduce lifetime bounds onto type parameters if your type (directly or indirectly) contains a reference. Thus a struct like `struct Ref<'a, T> { x: &'a T }` would be changed to `struct Ref<'a, T:'a> { x: &'a T }`. 2. Introduce lifetime bounds onto lifetime parameters if your type contains a double reference. Thus a type like `struct RefWrapper<'a, 'b> { r: &'a Ref<'b, int> }` (where `Ref` is defined as before) would need to be changed to `struct RefWrapper<'a, 'b:'a> { ... }`. 2. Explicitly give object lifetimes in structure definitions. Most commonly, this means changing something like `Box<Reader>` to `Box<Reader+'static>`, so as to indicate that this is a reader without any borrowed data. (Note: you may wish to just change to `Box<Reader+Send>` while you're at it; it's a more restrictive type, technically, but means you can send the reader between threads.) The intuition for points 1 and 2 is that a reference must never outlive its referent (the thing it points at). Therefore, if you have a type `&'a T`, we must know that `T` (whatever it is) outlives `'a`. And so on. Closes #5723.
2 parents 0d3bd77 + 1b487a8 commit b516532

File tree

271 files changed

+6746
-3096
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

271 files changed

+6746
-3096
lines changed

src/liballoc/boxed.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,9 @@ pub trait BoxAny {
105105
}
106106

107107
#[stable]
108-
impl BoxAny for Box<Any> {
108+
impl BoxAny for Box<Any+'static> {
109109
#[inline]
110-
fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
110+
fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any+'static>> {
111111
if self.is::<T>() {
112112
unsafe {
113113
// Get the raw representation of the trait object
@@ -132,7 +132,7 @@ impl<T: fmt::Show> fmt::Show for Box<T> {
132132
}
133133
}
134134

135-
impl fmt::Show for Box<Any> {
135+
impl fmt::Show for Box<Any+'static> {
136136
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
137137
f.pad("Box<Any>")
138138
}

src/libcollections/dlist.rs

+22-3
Original file line numberDiff line numberDiff line change
@@ -49,27 +49,46 @@ struct Node<T> {
4949
value: T,
5050
}
5151

52-
/// An iterator over references to the items of a `DList`.
52+
/// Note: stage0-specific version that lacks bound on A.
53+
#[cfg(stage0)]
5354
pub struct Items<'a, T> {
5455
head: &'a Link<T>,
5556
tail: Rawlink<Node<T>>,
5657
nelem: uint,
5758
}
5859

60+
/// An iterator over references to the items of a `DList`.
61+
#[cfg(not(stage0))]
62+
pub struct Items<'a, T:'a> {
63+
head: &'a Link<T>,
64+
tail: Rawlink<Node<T>>,
65+
nelem: uint,
66+
}
67+
5968
// FIXME #11820: the &'a Option<> of the Link stops clone working.
6069
impl<'a, T> Clone for Items<'a, T> {
6170
fn clone(&self) -> Items<'a, T> { *self }
6271
}
6372

64-
/// An iterator over mutable references to the items of a `DList`.
73+
/// Note: stage0-specific version that lacks bound on A.
74+
#[cfg(stage0)]
6575
pub struct MutItems<'a, T> {
6676
list: &'a mut DList<T>,
6777
head: Rawlink<Node<T>>,
6878
tail: Rawlink<Node<T>>,
6979
nelem: uint,
7080
}
7181

72-
/// A consuming iterator over the items of a `DList`.
82+
/// An iterator over mutable references to the items of a `DList`.
83+
#[cfg(not(stage0))]
84+
pub struct MutItems<'a, T:'a> {
85+
list: &'a mut DList<T>,
86+
head: Rawlink<Node<T>>,
87+
tail: Rawlink<Node<T>>,
88+
nelem: uint,
89+
}
90+
91+
/// An iterator over mutable references to the items of a `DList`.
7392
#[deriving(Clone)]
7493
pub struct MoveItems<T> {
7594
list: DList<T>

src/libcollections/priority_queue.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -515,11 +515,18 @@ impl<T: Ord> PriorityQueue<T> {
515515
}
516516
}
517517

518-
/// `PriorityQueue` iterator.
518+
/// Note: stage0-specific version that lacks bound on A.
519+
#[cfg(stage0)]
519520
pub struct Items <'a, T> {
520521
iter: slice::Items<'a, T>,
521522
}
522523

524+
/// `PriorityQueue` iterator.
525+
#[cfg(not(stage0))]
526+
pub struct Items <'a, T:'a> {
527+
iter: slice::Items<'a, T>,
528+
}
529+
523530
impl<'a, T> Iterator<&'a T> for Items<'a, T> {
524531
#[inline]
525532
fn next(&mut self) -> Option<(&'a T)> { self.iter.next() }

src/libcollections/ringbuf.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -293,14 +293,24 @@ impl<T> RingBuf<T> {
293293
}
294294
}
295295

296-
/// `RingBuf` iterator.
296+
/// Note: stage0-specific version that lacks bound on A.
297+
#[cfg(stage0)]
297298
pub struct Items<'a, T> {
298299
lo: uint,
299300
index: uint,
300301
rindex: uint,
301302
elts: &'a [Option<T>],
302303
}
303304

305+
/// `RingBuf` iterator.
306+
#[cfg(not(stage0))]
307+
pub struct Items<'a, T:'a> {
308+
lo: uint,
309+
index: uint,
310+
rindex: uint,
311+
elts: &'a [Option<T>],
312+
}
313+
304314
impl<'a, T> Iterator<&'a T> for Items<'a, T> {
305315
#[inline]
306316
fn next(&mut self) -> Option<&'a T> {
@@ -348,13 +358,22 @@ impl<'a, T> RandomAccessIterator<&'a T> for Items<'a, T> {
348358
}
349359
}
350360

351-
/// `RingBuf` mutable iterator.
361+
/// Note: stage0-specific version that lacks bound on A.
362+
#[cfg(stage0)]
352363
pub struct MutItems<'a, T> {
353364
remaining1: &'a mut [Option<T>],
354365
remaining2: &'a mut [Option<T>],
355366
nelts: uint,
356367
}
357368

369+
/// `RingBuf` mutable iterator.
370+
#[cfg(not(stage0))]
371+
pub struct MutItems<'a, T:'a> {
372+
remaining1: &'a mut [Option<T>],
373+
remaining2: &'a mut [Option<T>],
374+
nelts: uint,
375+
}
376+
358377
impl<'a, T> Iterator<&'a mut T> for MutItems<'a, T> {
359378
#[inline]
360379
#[allow(deprecated)] // mut_shift_ref

src/libcollections/smallintmap.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -489,19 +489,37 @@ macro_rules! double_ended_iterator {
489489
}
490490
}
491491

492-
/// Forward iterator over a map.
492+
/// Note: stage0-specific version that lacks bound on A.
493+
#[cfg(stage0)]
493494
pub struct Entries<'a, T> {
494495
front: uint,
495496
back: uint,
496497
iter: slice::Items<'a, Option<T>>
497498
}
498499

500+
/// Forward iterator over a map.
501+
#[cfg(not(stage0))]
502+
pub struct Entries<'a, T:'a> {
503+
front: uint,
504+
back: uint,
505+
iter: slice::Items<'a, Option<T>>
506+
}
507+
499508
iterator!(impl Entries -> (uint, &'a T), get_ref)
500509
double_ended_iterator!(impl Entries -> (uint, &'a T), get_ref)
501510

511+
/// Note: stage0-specific version that lacks bound on A.
512+
#[cfg(stage0)]
513+
pub struct MutEntries<'a, T> {
514+
front: uint,
515+
back: uint,
516+
iter: slice::MutItems<'a, Option<T>>
517+
}
518+
502519
/// Forward iterator over the key-value pairs of a map, with the
503520
/// values being mutable.
504-
pub struct MutEntries<'a, T> {
521+
#[cfg(not(stage0))]
522+
pub struct MutEntries<'a, T:'a> {
505523
front: uint,
506524
back: uint,
507525
iter: slice::MutItems<'a, Option<T>>

src/libcollections/treemap.rs

+114-16
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,8 @@ impl<K: Ord, V> TreeMap<K, V> {
668668
}
669669
}
670670

671-
/// A lazy forward iterator over a map.
671+
/// Note: stage0-specific version that lacks bound on A.
672+
#[cfg(stage0)]
672673
pub struct Entries<'a, K, V> {
673674
stack: Vec<&'a TreeNode<K, V>>,
674675
// See the comment on MutEntries; this is just to allow
@@ -679,13 +680,32 @@ pub struct Entries<'a, K, V> {
679680
remaining_max: uint
680681
}
681682

682-
/// Lazy backward iterator over a map.
683+
/// Lazy forward iterator over a map
684+
#[cfg(not(stage0))]
685+
pub struct Entries<'a, K:'a, V:'a> {
686+
stack: Vec<&'a TreeNode<K, V>>,
687+
// See the comment on MutEntries; this is just to allow
688+
// code-sharing (for this immutable-values iterator it *could* very
689+
// well be Option<&'a TreeNode<K,V>>).
690+
node: *const TreeNode<K, V>,
691+
remaining_min: uint,
692+
remaining_max: uint
693+
}
694+
695+
/// Note: stage0-specific version that lacks bound on A.
696+
#[cfg(stage0)]
683697
pub struct RevEntries<'a, K, V> {
684698
iter: Entries<'a, K, V>,
685699
}
686700

687-
/// A lazy forward iterator over a map that allows for the mutation of
688-
/// the values.
701+
/// Lazy backward iterator over a map
702+
#[cfg(not(stage0))]
703+
pub struct RevEntries<'a, K:'a, V:'a> {
704+
iter: Entries<'a, K, V>,
705+
}
706+
707+
/// Note: stage0-specific version that lacks bound on A.
708+
#[cfg(stage0)]
689709
pub struct MutEntries<'a, K, V> {
690710
stack: Vec<&'a mut TreeNode<K, V>>,
691711
// Unfortunately, we require some unsafe-ness to get around the
@@ -712,11 +732,46 @@ pub struct MutEntries<'a, K, V> {
712732
remaining_max: uint
713733
}
714734

715-
/// Lazy backward iterator over a map.
735+
/// Lazy forward iterator over a map that allows for the mutation of
736+
/// the values.
737+
#[cfg(not(stage0))]
738+
pub struct MutEntries<'a, K:'a, V:'a> {
739+
stack: Vec<&'a mut TreeNode<K, V>>,
740+
// Unfortunately, we require some unsafe-ness to get around the
741+
// fact that we would be storing a reference *into* one of the
742+
// nodes in the stack.
743+
//
744+
// As far as the compiler knows, this would let us invalidate the
745+
// reference by assigning a new value to this node's position in
746+
// its parent, which would cause this current one to be
747+
// deallocated so this reference would be invalid. (i.e. the
748+
// compilers complaints are 100% correct.)
749+
//
750+
// However, as far as you humans reading this code know (or are
751+
// about to know, if you haven't read far enough down yet), we are
752+
// only reading from the TreeNode.{left,right} fields. the only
753+
// thing that is ever mutated is the .value field (although any
754+
// actual mutation that happens is done externally, by the
755+
// iterator consumer). So, don't be so concerned, rustc, we've got
756+
// it under control.
757+
//
758+
// (This field can legitimately be null.)
759+
node: *mut TreeNode<K, V>,
760+
remaining_min: uint,
761+
remaining_max: uint
762+
}
763+
764+
/// Note: stage0-specific version that lacks bound on A.
765+
#[cfg(stage0)]
716766
pub struct RevMutEntries<'a, K, V> {
717767
iter: MutEntries<'a, K, V>,
718768
}
719769

770+
/// Lazy backward iterator over a map
771+
#[cfg(not(stage0))]
772+
pub struct RevMutEntries<'a, K:'a, V:'a> {
773+
iter: MutEntries<'a, K, V>,
774+
}
720775

721776
/// TreeMap keys iterator.
722777
pub type Keys<'a, K, V> =
@@ -885,9 +940,7 @@ fn mut_deref<K, V>(x: &mut Option<Box<TreeNode<K, V>>>)
885940
}
886941
}
887942

888-
889-
890-
/// A lazy forward iterator over a map that consumes the map while iterating.
943+
/// Lazy forward iterator over a map that consumes the map while iterating
891944
pub struct MoveEntries<K, V> {
892945
stack: Vec<TreeNode<K, V>>,
893946
remaining: uint
@@ -1322,45 +1375,90 @@ impl<T: Ord> TreeSet<T> {
13221375
}
13231376
}
13241377

1325-
/// A lazy forward iterator over a set.
1378+
/// Note: stage0-specific version that lacks bound on A.
1379+
#[cfg(stage0)]
13261380
pub struct SetItems<'a, T> {
13271381
iter: Entries<'a, T, ()>
13281382
}
13291383

1330-
/// Lazy backward iterator over a set.
1384+
/// A lazy forward iterator over a set.
1385+
#[cfg(not(stage0))]
1386+
pub struct SetItems<'a, T:'a> {
1387+
iter: Entries<'a, T, ()>
1388+
}
1389+
1390+
/// Note: stage0-specific version that lacks bound on A.
1391+
#[cfg(stage0)]
13311392
pub struct RevSetItems<'a, T> {
13321393
iter: RevEntries<'a, T, ()>
13331394
}
13341395

1396+
/// A lazy backward iterator over a set.
1397+
#[cfg(not(stage0))]
1398+
pub struct RevSetItems<'a, T:'a> {
1399+
iter: RevEntries<'a, T, ()>
1400+
}
1401+
13351402
/// A lazy forward iterator over a set that consumes the set while iterating.
13361403
pub type MoveSetItems<T> = iter::Map<'static, (T, ()), T, MoveEntries<T, ()>>;
13371404

1338-
/// A lazy iterator producing elements in the set difference (in-order).
1405+
/// Note: stage0-specific version that lacks bound on A.
1406+
#[cfg(stage0)]
13391407
pub struct DifferenceItems<'a, T> {
13401408
a: Peekable<&'a T, SetItems<'a, T>>,
13411409
b: Peekable<&'a T, SetItems<'a, T>>,
13421410
}
13431411

1344-
/// A lazy iterator producing elements in the set symmetric difference (in-order).
1412+
/// A lazy iterator producing elements in the set difference (in-order).
1413+
#[cfg(not(stage0))]
1414+
pub struct DifferenceItems<'a, T:'a> {
1415+
a: Peekable<&'a T, SetItems<'a, T>>,
1416+
b: Peekable<&'a T, SetItems<'a, T>>,
1417+
}
1418+
1419+
/// Note: stage0-specific version that lacks bound on A.
1420+
#[cfg(stage0)]
13451421
pub struct SymDifferenceItems<'a, T> {
13461422
a: Peekable<&'a T, SetItems<'a, T>>,
13471423
b: Peekable<&'a T, SetItems<'a, T>>,
13481424
}
13491425

1350-
/// A lazy iterator producing elements in the set intersection (in-order).
1426+
/// A lazy iterator producing elements in the set symmetric difference (in-order).
1427+
#[cfg(not(stage0))]
1428+
pub struct SymDifferenceItems<'a, T:'a> {
1429+
a: Peekable<&'a T, SetItems<'a, T>>,
1430+
b: Peekable<&'a T, SetItems<'a, T>>,
1431+
}
1432+
1433+
/// Note: stage0-specific version that lacks bound on A.
1434+
#[cfg(stage0)]
13511435
pub struct IntersectionItems<'a, T> {
13521436
a: Peekable<&'a T, SetItems<'a, T>>,
13531437
b: Peekable<&'a T, SetItems<'a, T>>,
13541438
}
13551439

1356-
/// A lazy iterator producing elements in the set union (in-order).
1440+
/// A lazy iterator producing elements in the set intersection (in-order).
1441+
#[cfg(not(stage0))]
1442+
pub struct IntersectionItems<'a, T:'a> {
1443+
a: Peekable<&'a T, SetItems<'a, T>>,
1444+
b: Peekable<&'a T, SetItems<'a, T>>,
1445+
}
1446+
1447+
/// Note: stage0-specific version that lacks bound on A.
1448+
#[cfg(stage0)]
13571449
pub struct UnionItems<'a, T> {
13581450
a: Peekable<&'a T, SetItems<'a, T>>,
13591451
b: Peekable<&'a T, SetItems<'a, T>>,
13601452
}
13611453

1362-
/// Compare `x` and `y`, but return `short` if x is None and `long` if y is
1363-
/// `None`.
1454+
/// A lazy iterator producing elements in the set union (in-order).
1455+
#[cfg(not(stage0))]
1456+
pub struct UnionItems<'a, T:'a> {
1457+
a: Peekable<&'a T, SetItems<'a, T>>,
1458+
b: Peekable<&'a T, SetItems<'a, T>>,
1459+
}
1460+
1461+
/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None
13641462
fn cmp_opt<T: Ord>(x: Option<&T>, y: Option<&T>,
13651463
short: Ordering, long: Ordering) -> Ordering {
13661464
match (x, y) {

0 commit comments

Comments
 (0)