Skip to content

Commit

Permalink
auto merge of #16453 : nikomatsakis/rust/type-bounds-3, r=pcwalton
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Aug 28, 2014
2 parents 9898b0d + 4b63291 commit b82f4a6
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 2 deletions.
3 changes: 2 additions & 1 deletion lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ pub fn main() {
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![feature(issue_5723_bootstrap)]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://doc.rust-lang.org/master/")]
Expand Down Expand Up @@ -499,7 +500,7 @@ pub trait GraphWalk<'a, N, E> {

/// Renders directed graph `g` into the writer `w` in DOT syntax.
/// (Main entry point for the library.)
pub fn render<'a, N, E, G:Labeller<'a,N,E>+GraphWalk<'a,N,E>, W:Writer>(
pub fn render<'a, N:'a, E:'a, G:Labeller<'a,N,E>+GraphWalk<'a,N,E>, W:Writer>(
g: &'a G,
w: &mut W) -> io::IoResult<()>
{
Expand Down
10 changes: 9 additions & 1 deletion maybe_owned_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ use std::slice;
/// Some clients will have a pre-allocated vector ready to hand off in
/// a slice; others will want to create the set on the fly and hand
/// off ownership, via `Growable`.
#[cfg(not(stage0))]
pub enum MaybeOwnedVector<'a,T:'a> {
Growable(Vec<T>),
Borrowed(&'a [T]),
}

/// Stage0 only.
#[cfg(stage0)]
pub enum MaybeOwnedVector<'a,T> {
Growable(Vec<T>),
Borrowed(&'a [T]),
Expand All @@ -45,7 +53,7 @@ pub trait IntoMaybeOwnedVector<'a,T> {
fn into_maybe_owned(self) -> MaybeOwnedVector<'a,T>;
}

impl<'a,T> IntoMaybeOwnedVector<'a,T> for Vec<T> {
impl<'a,T:'a> IntoMaybeOwnedVector<'a,T> for Vec<T> {
#[inline]
fn into_maybe_owned(self) -> MaybeOwnedVector<'a,T> { Growable(self) }
}
Expand Down

0 comments on commit b82f4a6

Please sign in to comment.