librustc: Disallow "mut" from distributing over bindings.
This is the backwards-incompatible part of per-binding-site "mut".
This commit is contained in:
parent
1c0aa78481
commit
f9b54541ee
32 changed files with 190 additions and 50 deletions
14
doc/rust.md
14
doc/rust.md
|
@ -2862,13 +2862,13 @@ call to the method `make_string`.
|
||||||
Types in Rust are categorized into kinds, based on various properties of the components of the type.
|
Types in Rust are categorized into kinds, based on various properties of the components of the type.
|
||||||
The kinds are:
|
The kinds are:
|
||||||
|
|
||||||
`Const`
|
`Freeze`
|
||||||
: Types of this kind are deeply immutable;
|
: Types of this kind are deeply immutable;
|
||||||
they contain no mutable memory locations directly or indirectly via pointers.
|
they contain no mutable memory locations directly or indirectly via pointers.
|
||||||
`Owned`
|
`Send`
|
||||||
: Types of this kind can be safely sent between tasks.
|
: Types of this kind can be safely sent between tasks.
|
||||||
This kind includes scalars, owning pointers, owned closures, and
|
This kind includes scalars, owning pointers, owned closures, and
|
||||||
structural types containing only other owned types. All `Owned` types are `Static`.
|
structural types containing only other owned types. All `Send` types are `Static`.
|
||||||
`Static`
|
`Static`
|
||||||
: Types of this kind do not contain any borrowed pointers;
|
: Types of this kind do not contain any borrowed pointers;
|
||||||
this can be a useful guarantee for code that breaks borrowing assumptions using [`unsafe` operations](#unsafe-functions).
|
this can be a useful guarantee for code that breaks borrowing assumptions using [`unsafe` operations](#unsafe-functions).
|
||||||
|
@ -2882,7 +2882,7 @@ The kinds are:
|
||||||
trait provides a single method `finalize` that takes no parameters, and is run
|
trait provides a single method `finalize` that takes no parameters, and is run
|
||||||
when values of the type are dropped. Such a method is called a "destructor",
|
when values of the type are dropped. Such a method is called a "destructor",
|
||||||
and are always executed in "top-down" order: a value is completely destroyed
|
and are always executed in "top-down" order: a value is completely destroyed
|
||||||
before any of the values it owns run their destructors. Only `Owned` types
|
before any of the values it owns run their destructors. Only `Send` types
|
||||||
that do not implement `Copy` can implement `Drop`.
|
that do not implement `Copy` can implement `Drop`.
|
||||||
|
|
||||||
> **Note:** The `finalize` method may be renamed in future versions of Rust.
|
> **Note:** The `finalize` method may be renamed in future versions of Rust.
|
||||||
|
@ -2968,10 +2968,10 @@ frame they are allocated within.
|
||||||
A task owns all memory it can *safely* reach through local variables,
|
A task owns all memory it can *safely* reach through local variables,
|
||||||
as well as managed, owning and borrowed pointers.
|
as well as managed, owning and borrowed pointers.
|
||||||
|
|
||||||
When a task sends a value that has the `Owned` trait to another task,
|
When a task sends a value that has the `Send` trait to another task,
|
||||||
it loses ownership of the value sent and can no longer refer to it.
|
it loses ownership of the value sent and can no longer refer to it.
|
||||||
This is statically guaranteed by the combined use of "move semantics",
|
This is statically guaranteed by the combined use of "move semantics",
|
||||||
and the compiler-checked _meaning_ of the `Owned` trait:
|
and the compiler-checked _meaning_ of the `Send` trait:
|
||||||
it is only instantiated for (transitively) sendable kinds of data constructor and pointers,
|
it is only instantiated for (transitively) sendable kinds of data constructor and pointers,
|
||||||
never including managed or borrowed pointers.
|
never including managed or borrowed pointers.
|
||||||
|
|
||||||
|
@ -3116,7 +3116,7 @@ These include:
|
||||||
- read-only and read-write shared variables with various safe mutual exclusion patterns
|
- read-only and read-write shared variables with various safe mutual exclusion patterns
|
||||||
- simple locks and semaphores
|
- simple locks and semaphores
|
||||||
|
|
||||||
When such facilities carry values, the values are restricted to the [`Owned` type-kind](#type-kinds).
|
When such facilities carry values, the values are restricted to the [`Send` type-kind](#type-kinds).
|
||||||
Restricting communication interfaces to this kind ensures that no borrowed or managed pointers move between tasks.
|
Restricting communication interfaces to this kind ensures that no borrowed or managed pointers move between tasks.
|
||||||
Thus access to an entire data structure can be mediated through its owning "root" value;
|
Thus access to an entire data structure can be mediated through its owning "root" value;
|
||||||
no further locking or copying is required to avoid data races within the substructure of such a value.
|
no further locking or copying is required to avoid data races within the substructure of such a value.
|
||||||
|
|
|
@ -159,7 +159,7 @@ pub struct Unique<T> {
|
||||||
priv ptr: *mut T
|
priv ptr: *mut T
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Owned> Unique<T> {
|
impl<T: Send> Unique<T> {
|
||||||
pub fn new(value: T) -> Unique<T> {
|
pub fn new(value: T) -> Unique<T> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = malloc(std::sys::size_of::<T>() as size_t) as *mut T;
|
let ptr = malloc(std::sys::size_of::<T>() as size_t) as *mut T;
|
||||||
|
@ -182,7 +182,7 @@ impl<T: Owned> Unique<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe_destructor]
|
#[unsafe_destructor]
|
||||||
impl<T: Owned> Drop for Unique<T> {
|
impl<T: Send> Drop for Unique<T> {
|
||||||
fn drop(&self) {
|
fn drop(&self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let x = intrinsics::init(); // dummy value to swap in
|
let x = intrinsics::init(); // dummy value to swap in
|
||||||
|
|
|
@ -59,7 +59,8 @@ pub fn md4(msg: &[u8]) -> Quad {
|
||||||
while i < e {
|
while i < e {
|
||||||
let (aa, bb, cc, dd) = (a, b, c, d);
|
let (aa, bb, cc, dd) = (a, b, c, d);
|
||||||
|
|
||||||
let mut (j, base) = (0u, i);
|
let mut j = 0u;
|
||||||
|
let mut base = i;
|
||||||
while j < 16u {
|
while j < 16u {
|
||||||
x[j] = (msg[base] as u32) + (msg[base + 1u] as u32 << 8u32) +
|
x[j] = (msg[base] as u32) + (msg[base + 1u] as u32 << 8u32) +
|
||||||
(msg[base + 2u] as u32 << 16u32) +
|
(msg[base + 2u] as u32 << 16u32) +
|
||||||
|
|
|
@ -415,7 +415,9 @@ fn get_authority(rawurl: &str) ->
|
||||||
let mut port = None;
|
let mut port = None;
|
||||||
|
|
||||||
let mut colon_count = 0;
|
let mut colon_count = 0;
|
||||||
let mut (pos, begin, end) = (0, 2, len);
|
let mut pos = 0;
|
||||||
|
let mut begin = 2;
|
||||||
|
let mut end = len;
|
||||||
|
|
||||||
for rawurl.iter().enumerate().advance |(i,c)| {
|
for rawurl.iter().enumerate().advance |(i,c)| {
|
||||||
if i < 2 { loop; } // ignore the leading //
|
if i < 2 { loop; } // ignore the leading //
|
||||||
|
|
|
@ -380,7 +380,10 @@ impl Integer for BigUint {
|
||||||
let mut d = Zero::zero::<BigUint>();
|
let mut d = Zero::zero::<BigUint>();
|
||||||
let mut n = 1;
|
let mut n = 1;
|
||||||
while m >= b {
|
while m >= b {
|
||||||
let mut (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
|
let (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
|
||||||
|
let mut d0 = d0;
|
||||||
|
let mut d_unit = d_unit;
|
||||||
|
let mut b_unit = b_unit;
|
||||||
let mut prod = b * d0;
|
let mut prod = b * d0;
|
||||||
while prod > m {
|
while prod > m {
|
||||||
// FIXME(#6050): overloaded operators force moves with generic types
|
// FIXME(#6050): overloaded operators force moves with generic types
|
||||||
|
@ -442,7 +445,8 @@ impl Integer for BigUint {
|
||||||
|
|
||||||
fn gcd(&self, other: &BigUint) -> BigUint {
|
fn gcd(&self, other: &BigUint) -> BigUint {
|
||||||
// Use Euclid's algorithm
|
// Use Euclid's algorithm
|
||||||
let mut (m, n) = (copy *self, copy *other);
|
let mut m = copy *self;
|
||||||
|
let mut n = copy *other;
|
||||||
while !m.is_zero() {
|
while !m.is_zero() {
|
||||||
let temp = m;
|
let temp = m;
|
||||||
m = n % temp;
|
m = n % temp;
|
||||||
|
|
|
@ -123,7 +123,9 @@ pub fn recv_timeout<T:Copy + Send>(iotask: &IoTask,
|
||||||
msecs: uint,
|
msecs: uint,
|
||||||
wait_po: &Port<T>)
|
wait_po: &Port<T>)
|
||||||
-> Option<T> {
|
-> Option<T> {
|
||||||
let mut (timeout_po, timeout_ch) = stream::<()>();
|
let (timeout_po, timeout_ch) = stream::<()>();
|
||||||
|
let mut timeout_po = timeout_po;
|
||||||
|
let mut timeout_ch = timeout_ch;
|
||||||
delayed_send(iotask, msecs, &timeout_ch, ());
|
delayed_send(iotask, msecs, &timeout_ch, ());
|
||||||
|
|
||||||
// XXX: Workaround due to ports and channels not being &mut. They should
|
// XXX: Workaround due to ports and channels not being &mut. They should
|
||||||
|
|
|
@ -139,12 +139,14 @@ impl ABIInfo for ARM_ABIInfo {
|
||||||
attrs.push(attr);
|
attrs.push(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut (ret_ty, ret_attr) = if ret_def {
|
let (ret_ty, ret_attr) = if ret_def {
|
||||||
classify_ret_ty(rty)
|
classify_ret_ty(rty)
|
||||||
} else {
|
} else {
|
||||||
(LLVMType { cast: false, ty: Type::void() }, None)
|
(LLVMType { cast: false, ty: Type::void() }, None)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut ret_ty = ret_ty;
|
||||||
|
|
||||||
let sret = ret_attr.is_some();
|
let sret = ret_attr.is_some();
|
||||||
if sret {
|
if sret {
|
||||||
arg_tys.unshift(ret_ty);
|
arg_tys.unshift(ret_ty);
|
||||||
|
|
|
@ -178,12 +178,14 @@ impl ABIInfo for MIPS_ABIInfo {
|
||||||
atys: &[Type],
|
atys: &[Type],
|
||||||
rty: Type,
|
rty: Type,
|
||||||
ret_def: bool) -> FnType {
|
ret_def: bool) -> FnType {
|
||||||
let mut (ret_ty, ret_attr) = if ret_def {
|
let (ret_ty, ret_attr) = if ret_def {
|
||||||
classify_ret_ty(rty)
|
classify_ret_ty(rty)
|
||||||
} else {
|
} else {
|
||||||
(LLVMType { cast: false, ty: Type::void() }, None)
|
(LLVMType { cast: false, ty: Type::void() }, None)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut ret_ty = ret_ty;
|
||||||
|
|
||||||
let sret = ret_attr.is_some();
|
let sret = ret_attr.is_some();
|
||||||
let mut arg_tys = ~[];
|
let mut arg_tys = ~[];
|
||||||
let mut attrs = ~[];
|
let mut attrs = ~[];
|
||||||
|
|
|
@ -360,8 +360,9 @@ fn x86_64_tys(atys: &[Type],
|
||||||
arg_tys.push(ty);
|
arg_tys.push(ty);
|
||||||
attrs.push(attr);
|
attrs.push(attr);
|
||||||
}
|
}
|
||||||
let mut (ret_ty, ret_attr) = x86_64_ty(rty, |cls| cls.is_ret_bysret(),
|
let (ret_ty, ret_attr) = x86_64_ty(rty, |cls| cls.is_ret_bysret(),
|
||||||
StructRetAttribute);
|
StructRetAttribute);
|
||||||
|
let mut ret_ty = ret_ty;
|
||||||
let sret = ret_attr.is_some();
|
let sret = ret_attr.is_some();
|
||||||
if sret {
|
if sret {
|
||||||
arg_tys = vec::append(~[ret_ty], arg_tys);
|
arg_tys = vec::append(~[ret_ty], arg_tys);
|
||||||
|
|
|
@ -319,9 +319,10 @@ pub fn trans_fn_ref_with_vtables(
|
||||||
// Should be either intra-crate or inlined.
|
// Should be either intra-crate or inlined.
|
||||||
assert_eq!(def_id.crate, ast::local_crate);
|
assert_eq!(def_id.crate, ast::local_crate);
|
||||||
|
|
||||||
let mut (val, must_cast) =
|
let (val, must_cast) =
|
||||||
monomorphize::monomorphic_fn(ccx, def_id, &substs,
|
monomorphize::monomorphic_fn(ccx, def_id, &substs,
|
||||||
vtables, opt_impl_did, Some(ref_id));
|
vtables, opt_impl_did, Some(ref_id));
|
||||||
|
let mut val = val;
|
||||||
if must_cast && ref_id != 0 {
|
if must_cast && ref_id != 0 {
|
||||||
// Monotype of the REFERENCE to the function (type params
|
// Monotype of the REFERENCE to the function (type params
|
||||||
// are subst'd)
|
// are subst'd)
|
||||||
|
|
|
@ -907,9 +907,12 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
|
||||||
let scaled_ix = Mul(bcx, ix_val, vt.llunit_size);
|
let scaled_ix = Mul(bcx, ix_val, vt.llunit_size);
|
||||||
base::maybe_name_value(bcx.ccx(), scaled_ix, "scaled_ix");
|
base::maybe_name_value(bcx.ccx(), scaled_ix, "scaled_ix");
|
||||||
|
|
||||||
let mut (bcx, base, len) =
|
let (bcx, base, len) =
|
||||||
base_datum.get_vec_base_and_len(bcx, index_expr.span,
|
base_datum.get_vec_base_and_len(bcx, index_expr.span,
|
||||||
index_expr.id, 0);
|
index_expr.id, 0);
|
||||||
|
let mut bcx = bcx;
|
||||||
|
let mut base = base;
|
||||||
|
let mut len = len;
|
||||||
|
|
||||||
if ty::type_is_str(base_ty) {
|
if ty::type_is_str(base_ty) {
|
||||||
// acccount for null terminator in the case of string
|
// acccount for null terminator in the case of string
|
||||||
|
|
|
@ -771,7 +771,9 @@ impl<T:Reader> ReaderUtil for T {
|
||||||
fn read_le_uint_n(&self, nbytes: uint) -> u64 {
|
fn read_le_uint_n(&self, nbytes: uint) -> u64 {
|
||||||
assert!(nbytes > 0 && nbytes <= 8);
|
assert!(nbytes > 0 && nbytes <= 8);
|
||||||
|
|
||||||
let mut (val, pos, i) = (0u64, 0, nbytes);
|
let mut val = 0u64;
|
||||||
|
let mut pos = 0;
|
||||||
|
let mut i = nbytes;
|
||||||
while i > 0 {
|
while i > 0 {
|
||||||
val += (self.read_u8() as u64) << pos;
|
val += (self.read_u8() as u64) << pos;
|
||||||
pos += 8;
|
pos += 8;
|
||||||
|
@ -787,7 +789,8 @@ impl<T:Reader> ReaderUtil for T {
|
||||||
fn read_be_uint_n(&self, nbytes: uint) -> u64 {
|
fn read_be_uint_n(&self, nbytes: uint) -> u64 {
|
||||||
assert!(nbytes > 0 && nbytes <= 8);
|
assert!(nbytes > 0 && nbytes <= 8);
|
||||||
|
|
||||||
let mut (val, i) = (0u64, nbytes);
|
let mut val = 0u64;
|
||||||
|
let mut i = nbytes;
|
||||||
while i > 0 {
|
while i > 0 {
|
||||||
i -= 1;
|
i -= 1;
|
||||||
val += (self.read_u8() as u64) << i * 8;
|
val += (self.read_u8() as u64) << i * 8;
|
||||||
|
|
|
@ -400,7 +400,8 @@ impl Integer for $T {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn gcd(&self, other: &$T) -> $T {
|
fn gcd(&self, other: &$T) -> $T {
|
||||||
// Use Euclid's algorithm
|
// Use Euclid's algorithm
|
||||||
let mut (m, n) = (*self, *other);
|
let mut m = *self;
|
||||||
|
let mut n = *other;
|
||||||
while m != 0 {
|
while m != 0 {
|
||||||
let temp = m;
|
let temp = m;
|
||||||
m = n % temp;
|
m = n % temp;
|
||||||
|
|
|
@ -237,7 +237,8 @@ impl Integer for $T {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn gcd(&self, other: &$T) -> $T {
|
fn gcd(&self, other: &$T) -> $T {
|
||||||
// Use Euclid's algorithm
|
// Use Euclid's algorithm
|
||||||
let mut (m, n) = (*self, *other);
|
let mut m = *self;
|
||||||
|
let mut n = *other;
|
||||||
while m != 0 {
|
while m != 0 {
|
||||||
let temp = m;
|
let temp = m;
|
||||||
m = n % temp;
|
m = n % temp;
|
||||||
|
|
|
@ -720,7 +720,8 @@ impl IsaacRng {
|
||||||
fn isaac(&mut self) {
|
fn isaac(&mut self) {
|
||||||
self.c += 1;
|
self.c += 1;
|
||||||
// abbreviations
|
// abbreviations
|
||||||
let mut (a, b) = (self.a, self.b + self.c);
|
let mut a = self.a;
|
||||||
|
let mut b = self.b + self.c;
|
||||||
|
|
||||||
static midpoint: uint = RAND_SIZE as uint / 2;
|
static midpoint: uint = RAND_SIZE as uint / 2;
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,8 @@ impl Rand for StandardNormal {
|
||||||
// do-while, so the condition should be true on the first
|
// do-while, so the condition should be true on the first
|
||||||
// run, they get overwritten anyway (0 < 1, so these are
|
// run, they get overwritten anyway (0 < 1, so these are
|
||||||
// good).
|
// good).
|
||||||
let mut (x, y) = (1.0, 0.0);
|
let mut x = 1.0;
|
||||||
|
let mut y = 0.0;
|
||||||
|
|
||||||
// XXX infinities?
|
// XXX infinities?
|
||||||
while -2.0*y < x * x {
|
while -2.0*y < x * x {
|
||||||
|
|
|
@ -343,7 +343,9 @@ impl<T: Reader> ReaderByteConversions for T {
|
||||||
fn read_le_uint_n(&mut self, nbytes: uint) -> u64 {
|
fn read_le_uint_n(&mut self, nbytes: uint) -> u64 {
|
||||||
assert!(nbytes > 0 && nbytes <= 8);
|
assert!(nbytes > 0 && nbytes <= 8);
|
||||||
|
|
||||||
let mut (val, pos, i) = (0u64, 0, nbytes);
|
let mut val = 0u64;
|
||||||
|
let mut pos = 0;
|
||||||
|
let mut i = nbytes;
|
||||||
while i > 0 {
|
while i > 0 {
|
||||||
val += (self.read_u8() as u64) << pos;
|
val += (self.read_u8() as u64) << pos;
|
||||||
pos += 8;
|
pos += 8;
|
||||||
|
@ -359,7 +361,8 @@ impl<T: Reader> ReaderByteConversions for T {
|
||||||
fn read_be_uint_n(&mut self, nbytes: uint) -> u64 {
|
fn read_be_uint_n(&mut self, nbytes: uint) -> u64 {
|
||||||
assert!(nbytes > 0 && nbytes <= 8);
|
assert!(nbytes > 0 && nbytes <= 8);
|
||||||
|
|
||||||
let mut (val, i) = (0u64, nbytes);
|
let mut val = 0u64;
|
||||||
|
let mut i = nbytes;
|
||||||
while i > 0 {
|
while i > 0 {
|
||||||
i -= 1;
|
i -= 1;
|
||||||
val += (self.read_u8() as u64) << i * 8;
|
val += (self.read_u8() as u64) << i * 8;
|
||||||
|
|
|
@ -473,6 +473,31 @@ pub fn each_split_within<'a>(ss: &'a str,
|
||||||
return cont;
|
return cont;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace all occurrences of one string with another
|
||||||
|
*
|
||||||
|
* # Arguments
|
||||||
|
*
|
||||||
|
* * s - The string containing substrings to replace
|
||||||
|
* * from - The string to replace
|
||||||
|
* * to - The replacement string
|
||||||
|
*
|
||||||
|
* # Return value
|
||||||
|
*
|
||||||
|
* The original string with all occurances of `from` replaced with `to`
|
||||||
|
*/
|
||||||
|
pub fn replace(s: &str, from: &str, to: &str) -> ~str {
|
||||||
|
let mut result = ~"";
|
||||||
|
let mut last_end = 0;
|
||||||
|
for s.matches_index_iter(from).advance |(start, end)| {
|
||||||
|
result.push_str(unsafe{raw::slice_bytes(s, last_end, start)});
|
||||||
|
result.push_str(to);
|
||||||
|
last_end = end;
|
||||||
|
}
|
||||||
|
result.push_str(unsafe{raw::slice_bytes(s, last_end, s.len())});
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Section: Comparing strings
|
Section: Comparing strings
|
||||||
*/
|
*/
|
||||||
|
@ -631,6 +656,48 @@ pub fn with_capacity(capacity: uint) -> ~str {
|
||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As char_len but for a slice of a string
|
||||||
|
*
|
||||||
|
* # Arguments
|
||||||
|
*
|
||||||
|
* * s - A valid string
|
||||||
|
* * start - The position inside `s` where to start counting in bytes
|
||||||
|
* * end - The position where to stop counting
|
||||||
|
*
|
||||||
|
* # Return value
|
||||||
|
*
|
||||||
|
* The number of Unicode characters in `s` between the given indices.
|
||||||
|
*/
|
||||||
|
pub fn count_chars(s: &str, start: uint, end: uint) -> uint {
|
||||||
|
assert!(s.is_char_boundary(start));
|
||||||
|
assert!(s.is_char_boundary(end));
|
||||||
|
let mut i = start;
|
||||||
|
let mut len = 0u;
|
||||||
|
while i < end {
|
||||||
|
let next = s.char_range_at(i).next;
|
||||||
|
len += 1u;
|
||||||
|
i = next;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Counts the number of bytes taken by the first `n` chars in `s`
|
||||||
|
/// starting from `start`.
|
||||||
|
pub fn count_bytes<'b>(s: &'b str, start: uint, n: uint) -> uint {
|
||||||
|
assert!(is_char_boundary(s, start));
|
||||||
|
let mut end = start;
|
||||||
|
let mut cnt = n;
|
||||||
|
let l = s.len();
|
||||||
|
while cnt > 0u {
|
||||||
|
assert!(end < l);
|
||||||
|
let next = s.char_range_at(end).next;
|
||||||
|
cnt -= 1u;
|
||||||
|
end = next;
|
||||||
|
}
|
||||||
|
end - start
|
||||||
|
}
|
||||||
|
|
||||||
/// Given a first byte, determine how many bytes are in this UTF-8 character
|
/// Given a first byte, determine how many bytes are in this UTF-8 character
|
||||||
pub fn utf8_char_width(b: u8) -> uint {
|
pub fn utf8_char_width(b: u8) -> uint {
|
||||||
let byte: uint = b as uint;
|
let byte: uint = b as uint;
|
||||||
|
@ -737,7 +804,8 @@ pub mod raw {
|
||||||
|
|
||||||
/// Create a Rust string from a null-terminated *u8 buffer
|
/// Create a Rust string from a null-terminated *u8 buffer
|
||||||
pub unsafe fn from_buf(buf: *u8) -> ~str {
|
pub unsafe fn from_buf(buf: *u8) -> ~str {
|
||||||
let mut (curr, i) = (buf, 0u);
|
let mut curr = buf;
|
||||||
|
let mut i = 0u;
|
||||||
while *curr != 0u8 {
|
while *curr != 0u8 {
|
||||||
i += 1u;
|
i += 1u;
|
||||||
curr = ptr::offset(buf, i);
|
curr = ptr::offset(buf, i);
|
||||||
|
|
|
@ -636,7 +636,9 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) {
|
||||||
let child_data = Cell::new((notify_chan, child_arc, ancestors));
|
let child_data = Cell::new((notify_chan, child_arc, ancestors));
|
||||||
let result: ~fn() = || {
|
let result: ~fn() = || {
|
||||||
// Agh. Get move-mode items into the closure. FIXME (#2829)
|
// Agh. Get move-mode items into the closure. FIXME (#2829)
|
||||||
let mut (notify_chan, child_arc, ancestors) = child_data.take();
|
let (notify_chan, child_arc, ancestors) = child_data.take();
|
||||||
|
let mut child_arc = child_arc;
|
||||||
|
let mut ancestors = ancestors;
|
||||||
// Child task runs this code.
|
// Child task runs this code.
|
||||||
|
|
||||||
// Even if the below code fails to kick the child off, we must
|
// Even if the below code fails to kick the child off, we must
|
||||||
|
|
|
@ -53,8 +53,9 @@ impl<A:ToStr> ToStr for (A,) {
|
||||||
impl<A:ToStr+Hash+Eq, B:ToStr+Hash+Eq> ToStr for HashMap<A, B> {
|
impl<A:ToStr+Hash+Eq, B:ToStr+Hash+Eq> ToStr for HashMap<A, B> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_str(&self) -> ~str {
|
fn to_str(&self) -> ~str {
|
||||||
let mut (acc, first) = (~"{", true);
|
let mut acc = ~"{";
|
||||||
for self.iter().advance |(key, value)| {
|
let mut first = true;
|
||||||
|
for self.iter().advance |key, value| {
|
||||||
if first {
|
if first {
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
|
@ -73,7 +74,8 @@ impl<A:ToStr+Hash+Eq, B:ToStr+Hash+Eq> ToStr for HashMap<A, B> {
|
||||||
impl<A:ToStr+Hash+Eq> ToStr for HashSet<A> {
|
impl<A:ToStr+Hash+Eq> ToStr for HashSet<A> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_str(&self) -> ~str {
|
fn to_str(&self) -> ~str {
|
||||||
let mut (acc, first) = (~"{", true);
|
let mut acc = ~"{";
|
||||||
|
let mut first = true;
|
||||||
for self.iter().advance |element| {
|
for self.iter().advance |element| {
|
||||||
if first {
|
if first {
|
||||||
first = false;
|
first = false;
|
||||||
|
@ -121,7 +123,8 @@ impl<A:ToStr,B:ToStr,C:ToStr> ToStr for (A, B, C) {
|
||||||
impl<'self,A:ToStr> ToStr for &'self [A] {
|
impl<'self,A:ToStr> ToStr for &'self [A] {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_str(&self) -> ~str {
|
fn to_str(&self) -> ~str {
|
||||||
let mut (acc, first) = (~"[", true);
|
let mut acc = ~"[";
|
||||||
|
let mut first = true;
|
||||||
for self.iter().advance |elt| {
|
for self.iter().advance |elt| {
|
||||||
if first {
|
if first {
|
||||||
first = false;
|
first = false;
|
||||||
|
@ -139,7 +142,8 @@ impl<'self,A:ToStr> ToStr for &'self [A] {
|
||||||
impl<A:ToStr> ToStr for ~[A] {
|
impl<A:ToStr> ToStr for ~[A] {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_str(&self) -> ~str {
|
fn to_str(&self) -> ~str {
|
||||||
let mut (acc, first) = (~"[", true);
|
let mut acc = ~"[";
|
||||||
|
let mut first = true;
|
||||||
for self.iter().advance |elt| {
|
for self.iter().advance |elt| {
|
||||||
if first {
|
if first {
|
||||||
first = false;
|
first = false;
|
||||||
|
@ -157,7 +161,8 @@ impl<A:ToStr> ToStr for ~[A] {
|
||||||
impl<A:ToStr> ToStr for @[A] {
|
impl<A:ToStr> ToStr for @[A] {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_str(&self) -> ~str {
|
fn to_str(&self) -> ~str {
|
||||||
let mut (acc, first) = (~"[", true);
|
let mut acc = ~"[";
|
||||||
|
let mut first = true;
|
||||||
for self.iter().advance |elt| {
|
for self.iter().advance |elt| {
|
||||||
if first {
|
if first {
|
||||||
first = false;
|
first = false;
|
||||||
|
|
|
@ -348,7 +348,8 @@ pub fn consume_reverse<T>(mut v: ~[T], f: &fn(uint, v: T)) {
|
||||||
pub fn dedup<T:Eq>(v: &mut ~[T]) {
|
pub fn dedup<T:Eq>(v: &mut ~[T]) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if v.len() < 1 { return; }
|
if v.len() < 1 { return; }
|
||||||
let mut (last_written, next_to_read) = (0, 1);
|
let mut last_written = 0;
|
||||||
|
let mut next_to_read = 1;
|
||||||
do as_const_buf(*v) |p, ln| {
|
do as_const_buf(*v) |p, ln| {
|
||||||
// We have a mutable reference to v, so we can make arbitrary
|
// We have a mutable reference to v, so we can make arbitrary
|
||||||
// changes. (cf. push and pop)
|
// changes. (cf. push and pop)
|
||||||
|
@ -798,7 +799,8 @@ pub fn bsearch_elem<T:TotalOrd>(v: &[T], x: &T) -> Option<uint> {
|
||||||
* Convert a vector of pairs into a pair of vectors, by reference. As unzip().
|
* Convert a vector of pairs into a pair of vectors, by reference. As unzip().
|
||||||
*/
|
*/
|
||||||
pub fn unzip_slice<T:Copy,U:Copy>(v: &[(T, U)]) -> (~[T], ~[U]) {
|
pub fn unzip_slice<T:Copy,U:Copy>(v: &[(T, U)]) -> (~[T], ~[U]) {
|
||||||
let mut (ts, us) = (~[], ~[]);
|
let mut ts = ~[];
|
||||||
|
let mut us = ~[];
|
||||||
for v.iter().advance |p| {
|
for v.iter().advance |p| {
|
||||||
let (t, u) = copy *p;
|
let (t, u) = copy *p;
|
||||||
ts.push(t);
|
ts.push(t);
|
||||||
|
@ -816,7 +818,8 @@ pub fn unzip_slice<T:Copy,U:Copy>(v: &[(T, U)]) -> (~[T], ~[U]) {
|
||||||
* of the i-th tuple of the input vector.
|
* of the i-th tuple of the input vector.
|
||||||
*/
|
*/
|
||||||
pub fn unzip<T,U>(v: ~[(T, U)]) -> (~[T], ~[U]) {
|
pub fn unzip<T,U>(v: ~[(T, U)]) -> (~[T], ~[U]) {
|
||||||
let mut (ts, us) = (~[], ~[]);
|
let mut ts = ~[];
|
||||||
|
let mut us = ~[];
|
||||||
do consume(v) |_i, p| {
|
do consume(v) |_i, p| {
|
||||||
let (t, u) = p;
|
let (t, u) = p;
|
||||||
ts.push(t);
|
ts.push(t);
|
||||||
|
|
|
@ -619,6 +619,15 @@ pub enum Privacy {
|
||||||
Public
|
Public
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the given pattern consists solely of an identifier
|
||||||
|
/// and false otherwise.
|
||||||
|
pub fn pat_is_ident(pat: @ast::pat) -> bool {
|
||||||
|
match pat.node {
|
||||||
|
ast::pat_ident(*) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// HYGIENE FUNCTIONS
|
// HYGIENE FUNCTIONS
|
||||||
|
|
||||||
/// Construct an identifier with the given name and an empty context:
|
/// Construct an identifier with the given name and an empty context:
|
||||||
|
|
|
@ -62,6 +62,7 @@ pub enum ObsoleteSyntax {
|
||||||
ObsoleteFixedLengthVectorType,
|
ObsoleteFixedLengthVectorType,
|
||||||
ObsoleteNamedExternModule,
|
ObsoleteNamedExternModule,
|
||||||
ObsoleteMultipleLocalDecl,
|
ObsoleteMultipleLocalDecl,
|
||||||
|
ObsoleteMutWithMultipleBindings,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl to_bytes::IterBytes for ObsoleteSyntax {
|
impl to_bytes::IterBytes for ObsoleteSyntax {
|
||||||
|
@ -223,6 +224,11 @@ impl Parser {
|
||||||
"instead of e.g. `let a = 1, b = 2`, write \
|
"instead of e.g. `let a = 1, b = 2`, write \
|
||||||
`let (a, b) = (1, 2)`."
|
`let (a, b) = (1, 2)`."
|
||||||
),
|
),
|
||||||
|
ObsoleteMutWithMultipleBindings => (
|
||||||
|
"`mut` with multiple bindings",
|
||||||
|
"use multiple local declarations instead of e.g. `let mut \
|
||||||
|
(x, y) = ...`."
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.report(sp, kind, kind_str, desc);
|
self.report(sp, kind, kind_str, desc);
|
||||||
|
|
|
@ -83,7 +83,8 @@ use parse::obsolete::{ObsoleteLifetimeNotation, ObsoleteConstManagedPointer};
|
||||||
use parse::obsolete::{ObsoletePurity, ObsoleteStaticMethod};
|
use parse::obsolete::{ObsoletePurity, ObsoleteStaticMethod};
|
||||||
use parse::obsolete::{ObsoleteConstItem, ObsoleteFixedLengthVectorType};
|
use parse::obsolete::{ObsoleteConstItem, ObsoleteFixedLengthVectorType};
|
||||||
use parse::obsolete::{ObsoleteNamedExternModule, ObsoleteMultipleLocalDecl};
|
use parse::obsolete::{ObsoleteNamedExternModule, ObsoleteMultipleLocalDecl};
|
||||||
use parse::token::{can_begin_expr, get_ident_interner, ident_to_str, is_ident, is_ident_or_path};
|
use parse::obsolete::{ObsoleteMutWithMultipleBindings};
|
||||||
|
use parse::token::{can_begin_expr, get_ident_interner, is_ident, is_ident_or_path};
|
||||||
use parse::token::{is_plain_ident, INTERPOLATED, keywords, special_idents, token_to_binop};
|
use parse::token::{is_plain_ident, INTERPOLATED, keywords, special_idents, token_to_binop};
|
||||||
use parse::token;
|
use parse::token;
|
||||||
use parse::{new_sub_parser_from_file, next_node_id, ParseSess};
|
use parse::{new_sub_parser_from_file, next_node_id, ParseSess};
|
||||||
|
@ -821,6 +822,11 @@ impl Parser {
|
||||||
self.parse_arg_mode();
|
self.parse_arg_mode();
|
||||||
is_mutbl = self.eat_keyword(keywords::Mut);
|
is_mutbl = self.eat_keyword(keywords::Mut);
|
||||||
let pat = self.parse_pat();
|
let pat = self.parse_pat();
|
||||||
|
|
||||||
|
if is_mutbl && !ast_util::pat_is_ident(pat) {
|
||||||
|
self.obsolete(*self.span, ObsoleteMutWithMultipleBindings)
|
||||||
|
}
|
||||||
|
|
||||||
self.expect(&token::COLON);
|
self.expect(&token::COLON);
|
||||||
pat
|
pat
|
||||||
} else {
|
} else {
|
||||||
|
@ -2560,6 +2566,11 @@ impl Parser {
|
||||||
fn parse_local(&self, is_mutbl: bool) -> @local {
|
fn parse_local(&self, is_mutbl: bool) -> @local {
|
||||||
let lo = self.span.lo;
|
let lo = self.span.lo;
|
||||||
let pat = self.parse_pat();
|
let pat = self.parse_pat();
|
||||||
|
|
||||||
|
if is_mutbl && !ast_util::pat_is_ident(pat) {
|
||||||
|
self.obsolete(*self.span, ObsoleteMutWithMultipleBindings)
|
||||||
|
}
|
||||||
|
|
||||||
let mut ty = @Ty {
|
let mut ty = @Ty {
|
||||||
id: self.get_id(),
|
id: self.get_id(),
|
||||||
node: ty_infer,
|
node: ty_infer,
|
||||||
|
@ -4420,7 +4431,8 @@ impl Parser {
|
||||||
let mut attrs = vec::append(first_item_attrs,
|
let mut attrs = vec::append(first_item_attrs,
|
||||||
self.parse_outer_attributes());
|
self.parse_outer_attributes());
|
||||||
// First, parse view items.
|
// First, parse view items.
|
||||||
let mut (view_items, items) = (~[], ~[]);
|
let mut view_items = ~[];
|
||||||
|
let mut items = ~[];
|
||||||
let mut done = false;
|
let mut done = false;
|
||||||
// I think this code would probably read better as a single
|
// I think this code would probably read better as a single
|
||||||
// loop with a mutable three-state-variable (for extern mods,
|
// loop with a mutable three-state-variable (for extern mods,
|
||||||
|
|
|
@ -23,7 +23,10 @@ fn main() {
|
||||||
for range(0, h) |y| {
|
for range(0, h) |y| {
|
||||||
let y = y as f64;
|
let y = y as f64;
|
||||||
for range(0, w) |x| {
|
for range(0, w) |x| {
|
||||||
let mut (Zr, Zi, Tr, Ti) = (0f64, 0f64, 0f64, 0f64);
|
let mut Zr = 0f64;
|
||||||
|
let mut Zi = 0f64;
|
||||||
|
let mut Tr = 0f64;
|
||||||
|
let mut Ti = 0f64;
|
||||||
let Cr = 2.0 * (x as f64) / (w as f64) - 1.5;
|
let Cr = 2.0 * (x as f64) / (w as f64) - 1.5;
|
||||||
let Ci = 2.0 * (y as f64) / (h as f64) - 1.0;
|
let Ci = 2.0 * (y as f64) / (h as f64) - 1.0;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ struct Foo {
|
||||||
f: @mut int,
|
f: @mut int,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Foo { //~ ERROR cannot implement a destructor on a struct that is not Send
|
impl Drop for Foo { //~ ERROR cannot implement a destructor on a structure that does not satisfy Send
|
||||||
fn drop(&self) {
|
fn drop(&self) {
|
||||||
*self.f = 10;
|
*self.f = 10;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ fn foo(_x: @uint) {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = @3u;
|
let x = @3u;
|
||||||
let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Owned`
|
let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Send`
|
||||||
let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Owned`
|
let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Send`
|
||||||
let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Owned`
|
let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Send`
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ fn main() {
|
||||||
let x = Cell::new(foo(Port(@())));
|
let x = Cell::new(foo(Port(@())));
|
||||||
|
|
||||||
do task::spawn {
|
do task::spawn {
|
||||||
let y = x.take(); //~ ERROR does not fulfill `Owned`
|
let y = x.take(); //~ ERROR does not fulfill `Send`
|
||||||
error!(y);
|
error!(y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#[non_owned]
|
#[non_sendable]
|
||||||
enum Foo { A }
|
enum Foo { A }
|
||||||
|
|
||||||
fn bar<T: Send>(_: T) {}
|
fn bar<T: Send>(_: T) {}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#[non_owned]
|
#[non_sendable]
|
||||||
struct Foo { a: int }
|
struct Foo { a: int }
|
||||||
|
|
||||||
fn bar<T: Send>(_: T) {}
|
fn bar<T: Send>(_: T) {}
|
||||||
|
|
|
@ -13,7 +13,9 @@ struct A { a: int }
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let u = X {x: 10, y: @A {a: 20}};
|
let u = X {x: 10, y: @A {a: 20}};
|
||||||
let mut X {x: x, y: @A {a: a}} = u;
|
let X {x: x, y: @A {a: a}} = u;
|
||||||
|
let mut x = x;
|
||||||
|
let mut a = a;
|
||||||
x = 100;
|
x = 100;
|
||||||
a = 100;
|
a = 100;
|
||||||
assert_eq!(x, 100);
|
assert_eq!(x, 100);
|
||||||
|
|
|
@ -22,7 +22,9 @@ proto! oneshot (
|
||||||
)
|
)
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let mut (p, c) = oneshot::init();
|
let (p, c) = oneshot::init();
|
||||||
|
let mut p = p;
|
||||||
|
let mut c = c;
|
||||||
|
|
||||||
assert!(!pipes::peek(&mut p));
|
assert!(!pipes::peek(&mut p));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue