Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lifetime binders #5565

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -1116,7 +1116,7 @@ static bit2: uint = 1 << 1;
static bits: [uint, ..2] = [bit1, bit2];
static string: &'static str = "bitstring";

struct BitsNStrings {
struct BitsNStrings<'self> {
mybits: [uint, ..2],
mystring: &'self str
}
Expand Down
20 changes: 10 additions & 10 deletions doc/tutorial-borrowed-ptr.md
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ For example, we could write a subroutine like this:

~~~
struct Point {x: float, y: float}
fn get_x(p: &'r Point) -> &'r float { &p.x }
fn get_x<'r>(p: &'r Point) -> &'r float { &p.x }
~~~

Here, the function `get_x()` returns a pointer into the structure it
Expand Down Expand Up @@ -571,8 +571,8 @@ function:
# Rectangle(Point, Size) // upper-left, dimensions
# }
# fn compute_area(shape: &Shape) -> float { 0f }
fn select<T>(shape: &'r Shape, threshold: float,
a: &'r T, b: &'r T) -> &'r T {
fn select<'r, T>(shape: &'r Shape, threshold: float,
a: &'r T, b: &'r T) -> &'r T {
if compute_area(shape) > threshold {a} else {b}
}
~~~
Expand All @@ -591,12 +591,12 @@ example:
# Rectangle(Point, Size) // upper-left, dimensions
# }
# fn compute_area(shape: &Shape) -> float { 0f }
# fn select<T>(shape: &Shape, threshold: float,
# a: &'r T, b: &'r T) -> &'r T {
# fn select<'r, T>(shape: &Shape, threshold: float,
# a: &'r T, b: &'r T) -> &'r T {
# if compute_area(shape) > threshold {a} else {b}
# }
// -+ r
fn select_based_on_unit_circle<T>( // |-+ B
fn select_based_on_unit_circle<'r, T>( // |-+ B
threshold: float, a: &'r T, b: &'r T) -> &'r T { // | |
// | |
let shape = Circle(Point {x: 0., y: 0.}, 1.); // | |
Expand Down Expand Up @@ -628,8 +628,8 @@ returned. Here is how the new `select()` might look:
# Rectangle(Point, Size) // upper-left, dimensions
# }
# fn compute_area(shape: &Shape) -> float { 0f }
fn select<T>(shape: &'tmp Shape, threshold: float,
a: &'r T, b: &'r T) -> &'r T {
fn select<'r, 'tmp, T>(shape: &'tmp Shape, threshold: float,
a: &'r T, b: &'r T) -> &'r T {
if compute_area(shape) > threshold {a} else {b}
}
~~~
Expand All @@ -647,8 +647,8 @@ concise to just omit the named lifetime for `shape` altogether:
# Rectangle(Point, Size) // upper-left, dimensions
# }
# fn compute_area(shape: &Shape) -> float { 0f }
fn select<T>(shape: &Shape, threshold: float,
a: &'r T, b: &'r T) -> &'r T {
fn select<'r, T>(shape: &Shape, threshold: float,
a: &'r T, b: &'r T) -> &'r T {
if compute_area(shape) > threshold {a} else {b}
}
~~~
Expand Down
22 changes: 11 additions & 11 deletions src/libcore/at_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub mod rustrt {

/// Returns the number of elements the vector can hold without reallocating
#[inline(always)]
pub fn capacity<T>(v: @[const T]) -> uint {
pub fn capacity<T>(v: @[T]) -> uint {
unsafe {
let repr: **raw::VecRepr =
::cast::reinterpret_cast(&addr_of(&v));
Expand All @@ -60,7 +60,7 @@ pub fn capacity<T>(v: @[const T]) -> uint {
*/
#[inline(always)]
pub fn build_sized<A>(size: uint, builder: &fn(push: &fn(v: A))) -> @[A] {
let mut vec: @[const A] = @[];
let mut vec: @[A] = @[];
unsafe { raw::reserve(&mut vec, size); }
builder(|+x| unsafe { raw::push(&mut vec, x) });
return unsafe { transmute(vec) };
Expand Down Expand Up @@ -102,7 +102,7 @@ pub fn build_sized_opt<A>(size: Option<uint>,

// Appending
#[inline(always)]
pub fn append<T:Copy>(lhs: @[T], rhs: &[const T]) -> @[T] {
pub fn append<T:Copy>(lhs: @[T], rhs: &const [T]) -> @[T] {
do build_sized(lhs.len() + rhs.len()) |push| {
for vec::each(lhs) |x| { push(*x); }
for uint::range(0, rhs.len()) |i| { push(rhs[i]); }
Expand Down Expand Up @@ -174,9 +174,9 @@ pub mod traits {
use kinds::Copy;
use ops::Add;

impl<T:Copy> Add<&'self [const T],@[T]> for @[T] {
impl<'self,T:Copy> Add<&'self const [T],@[T]> for @[T] {
#[inline(always)]
fn add(&self, rhs: & &'self [const T]) -> @[T] {
fn add(&self, rhs: & &'self const [T]) -> @[T] {
append(*self, (*rhs))
}
}
Expand Down Expand Up @@ -207,13 +207,13 @@ pub mod raw {
* the vector is actually the specified size.
*/
#[inline(always)]
pub unsafe fn set_len<T>(v: @[const T], new_len: uint) {
pub unsafe fn set_len<T>(v: @[T], new_len: uint) {
let repr: **VecRepr = ::cast::reinterpret_cast(&addr_of(&v));
(**repr).unboxed.fill = new_len * sys::size_of::<T>();
}

#[inline(always)]
pub unsafe fn push<T>(v: &mut @[const T], initval: T) {
pub unsafe fn push<T>(v: &mut @[T], initval: T) {
let repr: **VecRepr = ::cast::reinterpret_cast(&v);
let fill = (**repr).unboxed.fill;
if (**repr).unboxed.alloc > fill {
Expand All @@ -225,7 +225,7 @@ pub mod raw {
}

#[inline(always)] // really pretty please
pub unsafe fn push_fast<T>(v: &mut @[const T], initval: T) {
pub unsafe fn push_fast<T>(v: &mut @[T], initval: T) {
let repr: **VecRepr = ::cast::reinterpret_cast(&v);
let fill = (**repr).unboxed.fill;
(**repr).unboxed.fill += sys::size_of::<T>();
Expand All @@ -234,7 +234,7 @@ pub mod raw {
move_val_init(&mut(*p), initval);
}

pub unsafe fn push_slow<T>(v: &mut @[const T], initval: T) {
pub unsafe fn push_slow<T>(v: &mut @[T], initval: T) {
reserve_at_least(&mut *v, v.len() + 1u);
push_fast(v, initval);
}
Expand All @@ -250,7 +250,7 @@ pub mod raw {
* * v - A vector
* * n - The number of elements to reserve space for
*/
pub unsafe fn reserve<T>(v: &mut @[const T], n: uint) {
pub unsafe fn reserve<T>(v: &mut @[T], n: uint) {
// Only make the (slow) call into the runtime if we have to
if capacity(*v) < n {
let ptr: **VecRepr = transmute(v);
Expand All @@ -274,7 +274,7 @@ pub mod raw {
* * v - A vector
* * n - The number of elements to reserve space for
*/
pub unsafe fn reserve_at_least<T>(v: &mut @[const T], n: uint) {
pub unsafe fn reserve_at_least<T>(v: &mut @[T], n: uint) {
reserve(v, uint::next_power_of_two(n));
}

Expand Down
14 changes: 8 additions & 6 deletions src/libcore/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,19 @@ pub unsafe fn transmute<L, G>(thing: L) -> G {

/// Coerce an immutable reference to be mutable.
#[inline(always)]
pub unsafe fn transmute_mut<T>(ptr: &'a T) -> &'a mut T { transmute(ptr) }
pub unsafe fn transmute_mut<'a,T>(ptr: &'a T) -> &'a mut T { transmute(ptr) }

/// Coerce a mutable reference to be immutable.
#[inline(always)]
pub unsafe fn transmute_immut<T>(ptr: &'a mut T) -> &'a T {
pub unsafe fn transmute_immut<'a,T>(ptr: &'a mut T) -> &'a T {
transmute(ptr)
}

/// Coerce a borrowed pointer to have an arbitrary associated region.
#[inline(always)]
pub unsafe fn transmute_region<T>(ptr: &'a T) -> &'b T { transmute(ptr) }
pub unsafe fn transmute_region<'a,'b,T>(ptr: &'a T) -> &'b T {
transmute(ptr)
}

/// Coerce an immutable reference to be mutable.
#[inline(always)]
Expand All @@ -87,19 +89,19 @@ pub unsafe fn transmute_immut_unsafe<T>(ptr: *const T) -> *T {

/// Coerce a borrowed mutable pointer to have an arbitrary associated region.
#[inline(always)]
pub unsafe fn transmute_mut_region<T>(ptr: &'a mut T) -> &'b mut T {
pub unsafe fn transmute_mut_region<'a,'b,T>(ptr: &'a mut T) -> &'b mut T {
transmute(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline(always)]
pub unsafe fn copy_lifetime<S,T>(_ptr: &'a S, ptr: &T) -> &'a T {
pub unsafe fn copy_lifetime<'a,S,T>(_ptr: &'a S, ptr: &T) -> &'a T {
transmute_region(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline(always)]
pub unsafe fn copy_lifetime_vec<S,T>(_ptr: &'a [S], ptr: &T) -> &'a T {
pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T {
transmute_region(ptr)
}

Expand Down
14 changes: 7 additions & 7 deletions src/libcore/cleanup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ use cast::transmute;
* NB: These must match the representation in the C++ runtime.
*/

type DropGlue = &'self fn(**TypeDesc, *c_void);
type FreeGlue = &'self fn(**TypeDesc, *c_void);
type DropGlue<'self> = &'self fn(**TypeDesc, *c_void);
type FreeGlue<'self> = &'self fn(**TypeDesc, *c_void);

type TaskID = uintptr_t;

Expand All @@ -38,12 +38,12 @@ struct MemoryRegion { priv opaque: () }
#[cfg(target_arch="x86")]
#[cfg(target_arch="arm")]
struct Registers {
data: [u32 * 16]
data: [u32, ..16]
}

#[cfg(target_arch="mips")]
struct Registers {
data: [u32 * 32]
data: [u32, ..32]
}

#[cfg(target_arch="x86")]
Expand All @@ -52,12 +52,12 @@ struct Registers {
struct Context {
regs: Registers,
next: *Context,
pad: [u32 * 3]
pad: [u32, ..3]
}

#[cfg(target_arch="x86_64")]
struct Registers {
data: [u64 * 22]
data: [u64, ..22]
}

#[cfg(target_arch="x86_64")]
Expand All @@ -80,7 +80,7 @@ struct Task {
// Public fields
refcount: intptr_t, // 0
id: TaskID, // 4
pad: [u32 * 2], // 8
pad: [u32, ..2], // 8
ctx: Context, // 16
stack_segment: *StackSegment, // 96
runtime_sp: uintptr_t, // 100
Expand Down
12 changes: 6 additions & 6 deletions src/libcore/condition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ pub struct Handler<T, U> {
prev: Option<@Handler<T, U>>,
}

pub struct Condition<T, U> {
pub struct Condition<'self, T, U> {
name: &'static str,
key: task::local_data::LocalDataKey<'self, Handler<T, U>>
}

pub impl<T, U> Condition<'self, T, U> {
pub impl<'self, T, U> Condition<'self, T, U> {
fn trap(&self, h: &'self fn(T) -> U) -> Trap<'self, T, U> {
unsafe {
let p : *RustClosure = ::cast::transmute(&h);
Expand Down Expand Up @@ -66,12 +66,12 @@ pub impl<T, U> Condition<'self, T, U> {
}
}

struct Trap<T, U> {
struct Trap<'self, T, U> {
cond: &'self Condition<'self, T, U>,
handler: @Handler<T, U>
}

pub impl<T, U> Trap<'self, T, U> {
pub impl<'self, T, U> Trap<'self, T, U> {
fn in<V>(&self, inner: &'self fn() -> V) -> V {
unsafe {
let _g = Guard { cond: self.cond };
Expand All @@ -82,12 +82,12 @@ pub impl<T, U> Trap<'self, T, U> {
}
}

struct Guard<T, U> {
struct Guard<'self, T, U> {
cond: &'self Condition<'self, T, U>
}

#[unsafe_destructor]
impl<T, U> Drop for Guard<'self, T, U> {
impl<'self, T, U> Drop for Guard<'self, T, U> {
fn finalize(&self) {
unsafe {
debug!("Guard: popping handler from TLS");
Expand Down
4 changes: 2 additions & 2 deletions src/libcore/flate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ static lz_fast : c_int = 0x1; // LZ with only one probe
static lz_norm : c_int = 0x80; // LZ with 128 probes, "normal"
static lz_best : c_int = 0xfff; // LZ with 4095 probes, "best"

pub fn deflate_bytes(bytes: &[const u8]) -> ~[u8] {
pub fn deflate_bytes(bytes: &const [u8]) -> ~[u8] {
do vec::as_const_buf(bytes) |b, len| {
unsafe {
let mut outsz : size_t = 0;
Expand All @@ -64,7 +64,7 @@ pub fn deflate_bytes(bytes: &[const u8]) -> ~[u8] {
}
}

pub fn inflate_bytes(bytes: &[const u8]) -> ~[u8] {
pub fn inflate_bytes(bytes: &const [u8]) -> ~[u8] {
do vec::as_const_buf(bytes) |b, len| {
unsafe {
let mut outsz : size_t = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ unsafe fn is_safe_point(pc: *Word) -> Option<SafePoint> {
return None;
}

type Visitor = &'self fn(root: **Word, tydesc: *Word) -> bool;
type Visitor<'self> = &'self fn(root: **Word, tydesc: *Word) -> bool;

// Walks the list of roots for the given safe point, and calls visitor
// on each root.
Expand Down
12 changes: 6 additions & 6 deletions src/libcore/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ impl<A:Hash> HashUtil for A {

/// Streaming hash-functions should implement this.
pub trait Streaming {
fn input(&self, (&[const u8]));
fn input(&self, (&const [u8]));
// These can be refactored some when we have default methods.
fn result_bytes(&self) -> ~[u8];
fn result_str(&self) -> ~str;
Expand Down Expand Up @@ -162,7 +162,7 @@ struct SipState {
mut v1: u64,
mut v2: u64,
mut v3: u64,
mut tail: [u8 * 8], // unprocessed bytes
mut tail: [u8, ..8], // unprocessed bytes
mut ntail: uint, // how many bytes in tail are valid
}

Expand Down Expand Up @@ -221,7 +221,7 @@ impl io::Writer for SipState {

// Methods for io::writer
#[inline(always)]
fn write(&self, msg: &[const u8]) {
fn write(&self, msg: &const [u8]) {

let length = msg.len();
self.length += length;
Expand Down Expand Up @@ -299,7 +299,7 @@ impl io::Writer for SipState {
impl Streaming for SipState {

#[inline(always)]
fn input(&self, buf: &[const u8]) {
fn input(&self, buf: &const [u8]) {
self.write(buf);
}

Expand Down Expand Up @@ -369,7 +369,7 @@ impl Streaming for SipState {

#[test]
pub fn test_siphash() {
let vecs : [[u8 * 8] * 64] = [
let vecs : [[u8, ..8], ..64] = [
[ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, ],
[ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, ],
[ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, ],
Expand Down Expand Up @@ -443,7 +443,7 @@ pub fn test_siphash() {
let stream_inc = &State(k0,k1);
let stream_full = &State(k0,k1);

fn to_hex_str(r: &[u8 * 8]) -> ~str {
fn to_hex_str(r: &[u8, ..8]) -> ~str {
let mut s = ~"";
for vec::each(*r) |b| {
s += uint::to_str_radix(*b as uint, 16u);
Expand Down
Loading