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
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.
|
||||
The kinds are:
|
||||
|
||||
`Const`
|
||||
`Freeze`
|
||||
: Types of this kind are deeply immutable;
|
||||
they contain no mutable memory locations directly or indirectly via pointers.
|
||||
`Owned`
|
||||
`Send`
|
||||
: Types of this kind can be safely sent between tasks.
|
||||
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`
|
||||
: 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).
|
||||
@ -2882,7 +2882,7 @@ The kinds are:
|
||||
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",
|
||||
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`.
|
||||
|
||||
> **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,
|
||||
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.
|
||||
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,
|
||||
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
|
||||
- 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.
|
||||
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.
|
||||
|
@ -159,7 +159,7 @@ pub struct Unique<T> {
|
||||
priv ptr: *mut T
|
||||
}
|
||||
|
||||
impl<T: Owned> Unique<T> {
|
||||
impl<T: Send> Unique<T> {
|
||||
pub fn new(value: T) -> Unique<T> {
|
||||
unsafe {
|
||||
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]
|
||||
impl<T: Owned> Drop for Unique<T> {
|
||||
impl<T: Send> Drop for Unique<T> {
|
||||
fn drop(&self) {
|
||||
unsafe {
|
||||
let x = intrinsics::init(); // dummy value to swap in
|
||||
|
@ -59,7 +59,8 @@ fn rot(r: int, x: u32) -> u32 {
|
||||
while i < e {
|
||||
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 {
|
||||
x[j] = (msg[base] as u32) + (msg[base + 1u] as u32 << 8u32) +
|
||||
(msg[base + 2u] as u32 << 16u32) +
|
||||
|
@ -415,7 +415,9 @@ enum State {
|
||||
let mut port = None;
|
||||
|
||||
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)| {
|
||||
if i < 2 { loop; } // ignore the leading //
|
||||
|
@ -380,7 +380,10 @@ fn div_mod_floor_inner(a: BigUint, b: BigUint) -> (BigUint, BigUint) {
|
||||
let mut d = Zero::zero::<BigUint>();
|
||||
let mut n = 1;
|
||||
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;
|
||||
while prod > m {
|
||||
// FIXME(#6050): overloaded operators force moves with generic types
|
||||
@ -442,7 +445,8 @@ fn div_estimate(a: &BigUint, b: &BigUint, n: uint)
|
||||
|
||||
fn gcd(&self, other: &BigUint) -> BigUint {
|
||||
// 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() {
|
||||
let temp = m;
|
||||
m = n % temp;
|
||||
|
@ -123,7 +123,9 @@ pub fn recv_timeout<T:Copy + Send>(iotask: &IoTask,
|
||||
msecs: uint,
|
||||
wait_po: &Port<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, ());
|
||||
|
||||
// XXX: Workaround due to ports and channels not being &mut. They should
|
||||
|
@ -139,12 +139,14 @@ fn compute_info(&self,
|
||||
attrs.push(attr);
|
||||
}
|
||||
|
||||
let mut (ret_ty, ret_attr) = if ret_def {
|
||||
let (ret_ty, ret_attr) = if ret_def {
|
||||
classify_ret_ty(rty)
|
||||
} else {
|
||||
(LLVMType { cast: false, ty: Type::void() }, None)
|
||||
};
|
||||
|
||||
let mut ret_ty = ret_ty;
|
||||
|
||||
let sret = ret_attr.is_some();
|
||||
if sret {
|
||||
arg_tys.unshift(ret_ty);
|
||||
|
@ -178,12 +178,14 @@ fn compute_info(&self,
|
||||
atys: &[Type],
|
||||
rty: Type,
|
||||
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)
|
||||
} else {
|
||||
(LLVMType { cast: false, ty: Type::void() }, None)
|
||||
};
|
||||
|
||||
let mut ret_ty = ret_ty;
|
||||
|
||||
let sret = ret_attr.is_some();
|
||||
let mut arg_tys = ~[];
|
||||
let mut attrs = ~[];
|
||||
|
@ -360,8 +360,9 @@ fn x86_64_ty(ty: Type,
|
||||
arg_tys.push(ty);
|
||||
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);
|
||||
let mut ret_ty = ret_ty;
|
||||
let sret = ret_attr.is_some();
|
||||
if sret {
|
||||
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.
|
||||
assert_eq!(def_id.crate, ast::local_crate);
|
||||
|
||||
let mut (val, must_cast) =
|
||||
let (val, must_cast) =
|
||||
monomorphize::monomorphic_fn(ccx, def_id, &substs,
|
||||
vtables, opt_impl_did, Some(ref_id));
|
||||
let mut val = val;
|
||||
if must_cast && ref_id != 0 {
|
||||
// Monotype of the REFERENCE to the function (type params
|
||||
// are subst'd)
|
||||
|
@ -907,9 +907,12 @@ fn trans_index(bcx: block,
|
||||
let scaled_ix = Mul(bcx, ix_val, vt.llunit_size);
|
||||
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,
|
||||
index_expr.id, 0);
|
||||
let mut bcx = bcx;
|
||||
let mut base = base;
|
||||
let mut len = len;
|
||||
|
||||
if ty::type_is_str(base_ty) {
|
||||
// acccount for null terminator in the case of string
|
||||
|
@ -771,7 +771,9 @@ fn read_lines(&self) -> ~[~str] {
|
||||
fn read_le_uint_n(&self, nbytes: uint) -> u64 {
|
||||
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 {
|
||||
val += (self.read_u8() as u64) << pos;
|
||||
pos += 8;
|
||||
@ -787,7 +789,8 @@ fn read_le_int_n(&self, nbytes: uint) -> i64 {
|
||||
fn read_be_uint_n(&self, nbytes: uint) -> u64 {
|
||||
assert!(nbytes > 0 && nbytes <= 8);
|
||||
|
||||
let mut (val, i) = (0u64, nbytes);
|
||||
let mut val = 0u64;
|
||||
let mut i = nbytes;
|
||||
while i > 0 {
|
||||
i -= 1;
|
||||
val += (self.read_u8() as u64) << i * 8;
|
||||
|
@ -400,7 +400,8 @@ fn div_rem(&self, other: &$T) -> ($T,$T) {
|
||||
#[inline]
|
||||
fn gcd(&self, other: &$T) -> $T {
|
||||
// Use Euclid's algorithm
|
||||
let mut (m, n) = (*self, *other);
|
||||
let mut m = *self;
|
||||
let mut n = *other;
|
||||
while m != 0 {
|
||||
let temp = m;
|
||||
m = n % temp;
|
||||
|
@ -237,7 +237,8 @@ fn div_mod_floor(&self, other: &$T) -> ($T,$T) {
|
||||
#[inline]
|
||||
fn gcd(&self, other: &$T) -> $T {
|
||||
// Use Euclid's algorithm
|
||||
let mut (m, n) = (*self, *other);
|
||||
let mut m = *self;
|
||||
let mut n = *other;
|
||||
while m != 0 {
|
||||
let temp = m;
|
||||
m = n % temp;
|
||||
|
@ -720,7 +720,8 @@ macro_rules! memloop (
|
||||
fn isaac(&mut self) {
|
||||
self.c += 1;
|
||||
// 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;
|
||||
|
||||
|
@ -89,7 +89,8 @@ fn zero_case<R:Rng>(rng: &mut R, u: f64) -> f64 {
|
||||
// do-while, so the condition should be true on the first
|
||||
// run, they get overwritten anyway (0 < 1, so these are
|
||||
// good).
|
||||
let mut (x, y) = (1.0, 0.0);
|
||||
let mut x = 1.0;
|
||||
let mut y = 0.0;
|
||||
|
||||
// XXX infinities?
|
||||
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 {
|
||||
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 {
|
||||
val += (self.read_u8() as u64) << pos;
|
||||
pos += 8;
|
||||
@ -359,7 +361,8 @@ fn read_le_int_n(&mut self, nbytes: uint) -> i64 {
|
||||
fn read_be_uint_n(&mut self, nbytes: uint) -> u64 {
|
||||
assert!(nbytes > 0 && nbytes <= 8);
|
||||
|
||||
let mut (val, i) = (0u64, nbytes);
|
||||
let mut val = 0u64;
|
||||
let mut i = nbytes;
|
||||
while i > 0 {
|
||||
i -= 1;
|
||||
val += (self.read_u8() as u64) << i * 8;
|
||||
|
@ -473,6 +473,31 @@ enum LengthLimit {
|
||||
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
|
||||
*/
|
||||
@ -631,6 +656,48 @@ pub fn with_capacity(capacity: uint) -> ~str {
|
||||
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
|
||||
pub fn utf8_char_width(b: u8) -> uint {
|
||||
let byte: uint = b as uint;
|
||||
@ -737,7 +804,8 @@ pub mod raw {
|
||||
|
||||
/// Create a Rust string from a null-terminated *u8 buffer
|
||||
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 {
|
||||
i += 1u;
|
||||
curr = ptr::offset(buf, i);
|
||||
|
@ -636,7 +636,9 @@ fn make_child_wrapper(child: *rust_task, child_arc: TaskGroupArc,
|
||||
let child_data = Cell::new((notify_chan, child_arc, ancestors));
|
||||
let result: ~fn() = || {
|
||||
// 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.
|
||||
|
||||
// Even if the below code fails to kick the child off, we must
|
||||
|
@ -53,8 +53,9 @@ fn to_str(&self) -> ~str {
|
||||
impl<A:ToStr+Hash+Eq, B:ToStr+Hash+Eq> ToStr for HashMap<A, B> {
|
||||
#[inline]
|
||||
fn to_str(&self) -> ~str {
|
||||
let mut (acc, first) = (~"{", true);
|
||||
for self.iter().advance |(key, value)| {
|
||||
let mut acc = ~"{";
|
||||
let mut first = true;
|
||||
for self.iter().advance |key, value| {
|
||||
if first {
|
||||
first = false;
|
||||
}
|
||||
@ -73,7 +74,8 @@ fn to_str(&self) -> ~str {
|
||||
impl<A:ToStr+Hash+Eq> ToStr for HashSet<A> {
|
||||
#[inline]
|
||||
fn to_str(&self) -> ~str {
|
||||
let mut (acc, first) = (~"{", true);
|
||||
let mut acc = ~"{";
|
||||
let mut first = true;
|
||||
for self.iter().advance |element| {
|
||||
if first {
|
||||
first = false;
|
||||
@ -121,7 +123,8 @@ fn to_str(&self) -> ~str {
|
||||
impl<'self,A:ToStr> ToStr for &'self [A] {
|
||||
#[inline]
|
||||
fn to_str(&self) -> ~str {
|
||||
let mut (acc, first) = (~"[", true);
|
||||
let mut acc = ~"[";
|
||||
let mut first = true;
|
||||
for self.iter().advance |elt| {
|
||||
if first {
|
||||
first = false;
|
||||
@ -139,7 +142,8 @@ fn to_str(&self) -> ~str {
|
||||
impl<A:ToStr> ToStr for ~[A] {
|
||||
#[inline]
|
||||
fn to_str(&self) -> ~str {
|
||||
let mut (acc, first) = (~"[", true);
|
||||
let mut acc = ~"[";
|
||||
let mut first = true;
|
||||
for self.iter().advance |elt| {
|
||||
if first {
|
||||
first = false;
|
||||
@ -157,7 +161,8 @@ fn to_str(&self) -> ~str {
|
||||
impl<A:ToStr> ToStr for @[A] {
|
||||
#[inline]
|
||||
fn to_str(&self) -> ~str {
|
||||
let mut (acc, first) = (~"[", true);
|
||||
let mut acc = ~"[";
|
||||
let mut first = true;
|
||||
for self.iter().advance |elt| {
|
||||
if first {
|
||||
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]) {
|
||||
unsafe {
|
||||
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| {
|
||||
// We have a mutable reference to v, so we can make arbitrary
|
||||
// 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().
|
||||
*/
|
||||
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| {
|
||||
let (t, u) = copy *p;
|
||||
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.
|
||||
*/
|
||||
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| {
|
||||
let (t, u) = p;
|
||||
ts.push(t);
|
||||
|
@ -619,6 +619,15 @@ pub enum Privacy {
|
||||
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
|
||||
|
||||
/// Construct an identifier with the given name and an empty context:
|
||||
|
@ -62,6 +62,7 @@ pub enum ObsoleteSyntax {
|
||||
ObsoleteFixedLengthVectorType,
|
||||
ObsoleteNamedExternModule,
|
||||
ObsoleteMultipleLocalDecl,
|
||||
ObsoleteMutWithMultipleBindings,
|
||||
}
|
||||
|
||||
impl to_bytes::IterBytes for ObsoleteSyntax {
|
||||
@ -223,6 +224,11 @@ pub fn obsolete(&self, sp: span, kind: ObsoleteSyntax) {
|
||||
"instead of e.g. `let a = 1, b = 2`, write \
|
||||
`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);
|
||||
|
@ -83,7 +83,8 @@
|
||||
use parse::obsolete::{ObsoletePurity, ObsoleteStaticMethod};
|
||||
use parse::obsolete::{ObsoleteConstItem, ObsoleteFixedLengthVectorType};
|
||||
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;
|
||||
use parse::{new_sub_parser_from_file, next_node_id, ParseSess};
|
||||
@ -821,6 +822,11 @@ pub fn parse_arg_general(&self, require_name: bool) -> arg {
|
||||
self.parse_arg_mode();
|
||||
is_mutbl = self.eat_keyword(keywords::Mut);
|
||||
let pat = self.parse_pat();
|
||||
|
||||
if is_mutbl && !ast_util::pat_is_ident(pat) {
|
||||
self.obsolete(*self.span, ObsoleteMutWithMultipleBindings)
|
||||
}
|
||||
|
||||
self.expect(&token::COLON);
|
||||
pat
|
||||
} else {
|
||||
@ -2560,6 +2566,11 @@ fn parse_pat_ident(&self,
|
||||
fn parse_local(&self, is_mutbl: bool) -> @local {
|
||||
let lo = self.span.lo;
|
||||
let pat = self.parse_pat();
|
||||
|
||||
if is_mutbl && !ast_util::pat_is_ident(pat) {
|
||||
self.obsolete(*self.span, ObsoleteMutWithMultipleBindings)
|
||||
}
|
||||
|
||||
let mut ty = @Ty {
|
||||
id: self.get_id(),
|
||||
node: ty_infer,
|
||||
@ -4420,7 +4431,8 @@ fn parse_items_and_view_items(&self,
|
||||
let mut attrs = vec::append(first_item_attrs,
|
||||
self.parse_outer_attributes());
|
||||
// First, parse view items.
|
||||
let mut (view_items, items) = (~[], ~[]);
|
||||
let mut view_items = ~[];
|
||||
let mut items = ~[];
|
||||
let mut done = false;
|
||||
// I think this code would probably read better as a single
|
||||
// loop with a mutable three-state-variable (for extern mods,
|
||||
|
@ -23,7 +23,10 @@ fn main() {
|
||||
for range(0, h) |y| {
|
||||
let y = y as f64;
|
||||
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 Ci = 2.0 * (y as f64) / (h as f64) - 1.0;
|
||||
|
||||
|
@ -2,7 +2,7 @@ struct Foo {
|
||||
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) {
|
||||
*self.f = 10;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ fn foo(_x: @uint) {}
|
||||
|
||||
fn main() {
|
||||
let x = @3u;
|
||||
let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Owned`
|
||||
let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Owned`
|
||||
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 `Send`
|
||||
let _: ~fn() = || foo(x); //~ ERROR does not fulfill `Send`
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ fn foo(x: Port<()>) -> foo {
|
||||
let x = Cell::new(foo(Port(@())));
|
||||
|
||||
do task::spawn {
|
||||
let y = x.take(); //~ ERROR does not fulfill `Owned`
|
||||
let y = x.take(); //~ ERROR does not fulfill `Send`
|
||||
error!(y);
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[non_owned]
|
||||
#[non_sendable]
|
||||
enum Foo { A }
|
||||
|
||||
fn bar<T: Send>(_: T) {}
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[non_owned]
|
||||
#[non_sendable]
|
||||
struct Foo { a: int }
|
||||
|
||||
fn bar<T: Send>(_: T) {}
|
||||
|
@ -13,7 +13,9 @@ struct A { a: int }
|
||||
|
||||
pub fn main() {
|
||||
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;
|
||||
a = 100;
|
||||
assert_eq!(x, 100);
|
||||
|
@ -22,7 +22,9 @@
|
||||
)
|
||||
|
||||
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));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user