Skip to content

Commit f9b5454

Browse files
pcwaltonemberian
authored andcommitted
librustc: Disallow "mut" from distributing over bindings.
This is the backwards-incompatible part of per-binding-site "mut".
1 parent 1c0aa78 commit f9b5454

32 files changed

+190
-50
lines changed

doc/rust.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2862,13 +2862,13 @@ call to the method `make_string`.
28622862
Types in Rust are categorized into kinds, based on various properties of the components of the type.
28632863
The kinds are:
28642864

2865-
`Const`
2865+
`Freeze`
28662866
: Types of this kind are deeply immutable;
28672867
they contain no mutable memory locations directly or indirectly via pointers.
2868-
`Owned`
2868+
`Send`
28692869
: Types of this kind can be safely sent between tasks.
28702870
This kind includes scalars, owning pointers, owned closures, and
2871-
structural types containing only other owned types. All `Owned` types are `Static`.
2871+
structural types containing only other owned types. All `Send` types are `Static`.
28722872
`Static`
28732873
: Types of this kind do not contain any borrowed pointers;
28742874
this can be a useful guarantee for code that breaks borrowing assumptions using [`unsafe` operations](#unsafe-functions).
@@ -2882,7 +2882,7 @@ The kinds are:
28822882
trait provides a single method `finalize` that takes no parameters, and is run
28832883
when values of the type are dropped. Such a method is called a "destructor",
28842884
and are always executed in "top-down" order: a value is completely destroyed
2885-
before any of the values it owns run their destructors. Only `Owned` types
2885+
before any of the values it owns run their destructors. Only `Send` types
28862886
that do not implement `Copy` can implement `Drop`.
28872887

28882888
> **Note:** The `finalize` method may be renamed in future versions of Rust.
@@ -2968,10 +2968,10 @@ frame they are allocated within.
29682968
A task owns all memory it can *safely* reach through local variables,
29692969
as well as managed, owning and borrowed pointers.
29702970

2971-
When a task sends a value that has the `Owned` trait to another task,
2971+
When a task sends a value that has the `Send` trait to another task,
29722972
it loses ownership of the value sent and can no longer refer to it.
29732973
This is statically guaranteed by the combined use of "move semantics",
2974-
and the compiler-checked _meaning_ of the `Owned` trait:
2974+
and the compiler-checked _meaning_ of the `Send` trait:
29752975
it is only instantiated for (transitively) sendable kinds of data constructor and pointers,
29762976
never including managed or borrowed pointers.
29772977

@@ -3116,7 +3116,7 @@ These include:
31163116
- read-only and read-write shared variables with various safe mutual exclusion patterns
31173117
- simple locks and semaphores
31183118

3119-
When such facilities carry values, the values are restricted to the [`Owned` type-kind](#type-kinds).
3119+
When such facilities carry values, the values are restricted to the [`Send` type-kind](#type-kinds).
31203120
Restricting communication interfaces to this kind ensures that no borrowed or managed pointers move between tasks.
31213121
Thus access to an entire data structure can be mediated through its owning "root" value;
31223122
no further locking or copying is required to avoid data races within the substructure of such a value.

doc/tutorial-ffi.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ pub struct Unique<T> {
159159
priv ptr: *mut T
160160
}
161161
162-
impl<T: Owned> Unique<T> {
162+
impl<T: Send> Unique<T> {
163163
pub fn new(value: T) -> Unique<T> {
164164
unsafe {
165165
let ptr = malloc(std::sys::size_of::<T>() as size_t) as *mut T;
@@ -182,7 +182,7 @@ impl<T: Owned> Unique<T> {
182182
}
183183
184184
#[unsafe_destructor]
185-
impl<T: Owned> Drop for Unique<T> {
185+
impl<T: Send> Drop for Unique<T> {
186186
fn drop(&self) {
187187
unsafe {
188188
let x = intrinsics::init(); // dummy value to swap in

src/libextra/md4.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ pub fn md4(msg: &[u8]) -> Quad {
5959
while i < e {
6060
let (aa, bb, cc, dd) = (a, b, c, d);
6161

62-
let mut (j, base) = (0u, i);
62+
let mut j = 0u;
63+
let mut base = i;
6364
while j < 16u {
6465
x[j] = (msg[base] as u32) + (msg[base + 1u] as u32 << 8u32) +
6566
(msg[base + 2u] as u32 << 16u32) +

src/libextra/net_url.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,9 @@ fn get_authority(rawurl: &str) ->
415415
let mut port = None;
416416

417417
let mut colon_count = 0;
418-
let mut (pos, begin, end) = (0, 2, len);
418+
let mut pos = 0;
419+
let mut begin = 2;
420+
let mut end = len;
419421

420422
for rawurl.iter().enumerate().advance |(i,c)| {
421423
if i < 2 { loop; } // ignore the leading //

src/libextra/num/bigint.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,10 @@ impl Integer for BigUint {
380380
let mut d = Zero::zero::<BigUint>();
381381
let mut n = 1;
382382
while m >= b {
383-
let mut (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
383+
let (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
384+
let mut d0 = d0;
385+
let mut d_unit = d_unit;
386+
let mut b_unit = b_unit;
384387
let mut prod = b * d0;
385388
while prod > m {
386389
// FIXME(#6050): overloaded operators force moves with generic types
@@ -442,7 +445,8 @@ impl Integer for BigUint {
442445

443446
fn gcd(&self, other: &BigUint) -> BigUint {
444447
// Use Euclid's algorithm
445-
let mut (m, n) = (copy *self, copy *other);
448+
let mut m = copy *self;
449+
let mut n = copy *other;
446450
while !m.is_zero() {
447451
let temp = m;
448452
m = n % temp;

src/libextra/timer.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ pub fn recv_timeout<T:Copy + Send>(iotask: &IoTask,
123123
msecs: uint,
124124
wait_po: &Port<T>)
125125
-> Option<T> {
126-
let mut (timeout_po, timeout_ch) = stream::<()>();
126+
let (timeout_po, timeout_ch) = stream::<()>();
127+
let mut timeout_po = timeout_po;
128+
let mut timeout_ch = timeout_ch;
127129
delayed_send(iotask, msecs, &timeout_ch, ());
128130

129131
// XXX: Workaround due to ports and channels not being &mut. They should

src/librustc/middle/trans/cabi_arm.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,14 @@ impl ABIInfo for ARM_ABIInfo {
139139
attrs.push(attr);
140140
}
141141

142-
let mut (ret_ty, ret_attr) = if ret_def {
142+
let (ret_ty, ret_attr) = if ret_def {
143143
classify_ret_ty(rty)
144144
} else {
145145
(LLVMType { cast: false, ty: Type::void() }, None)
146146
};
147147

148+
let mut ret_ty = ret_ty;
149+
148150
let sret = ret_attr.is_some();
149151
if sret {
150152
arg_tys.unshift(ret_ty);

src/librustc/middle/trans/cabi_mips.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,14 @@ impl ABIInfo for MIPS_ABIInfo {
178178
atys: &[Type],
179179
rty: Type,
180180
ret_def: bool) -> FnType {
181-
let mut (ret_ty, ret_attr) = if ret_def {
181+
let (ret_ty, ret_attr) = if ret_def {
182182
classify_ret_ty(rty)
183183
} else {
184184
(LLVMType { cast: false, ty: Type::void() }, None)
185185
};
186186

187+
let mut ret_ty = ret_ty;
188+
187189
let sret = ret_attr.is_some();
188190
let mut arg_tys = ~[];
189191
let mut attrs = ~[];

src/librustc/middle/trans/cabi_x86_64.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,9 @@ fn x86_64_tys(atys: &[Type],
360360
arg_tys.push(ty);
361361
attrs.push(attr);
362362
}
363-
let mut (ret_ty, ret_attr) = x86_64_ty(rty, |cls| cls.is_ret_bysret(),
363+
let (ret_ty, ret_attr) = x86_64_ty(rty, |cls| cls.is_ret_bysret(),
364364
StructRetAttribute);
365+
let mut ret_ty = ret_ty;
365366
let sret = ret_attr.is_some();
366367
if sret {
367368
arg_tys = vec::append(~[ret_ty], arg_tys);

src/librustc/middle/trans/callee.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,10 @@ pub fn trans_fn_ref_with_vtables(
319319
// Should be either intra-crate or inlined.
320320
assert_eq!(def_id.crate, ast::local_crate);
321321

322-
let mut (val, must_cast) =
322+
let (val, must_cast) =
323323
monomorphize::monomorphic_fn(ccx, def_id, &substs,
324324
vtables, opt_impl_did, Some(ref_id));
325+
let mut val = val;
325326
if must_cast && ref_id != 0 {
326327
// Monotype of the REFERENCE to the function (type params
327328
// are subst'd)

src/librustc/middle/trans/expr.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -907,9 +907,12 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
907907
let scaled_ix = Mul(bcx, ix_val, vt.llunit_size);
908908
base::maybe_name_value(bcx.ccx(), scaled_ix, "scaled_ix");
909909

910-
let mut (bcx, base, len) =
910+
let (bcx, base, len) =
911911
base_datum.get_vec_base_and_len(bcx, index_expr.span,
912912
index_expr.id, 0);
913+
let mut bcx = bcx;
914+
let mut base = base;
915+
let mut len = len;
913916

914917
if ty::type_is_str(base_ty) {
915918
// acccount for null terminator in the case of string

src/libstd/io.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,9 @@ impl<T:Reader> ReaderUtil for T {
771771
fn read_le_uint_n(&self, nbytes: uint) -> u64 {
772772
assert!(nbytes > 0 && nbytes <= 8);
773773

774-
let mut (val, pos, i) = (0u64, 0, nbytes);
774+
let mut val = 0u64;
775+
let mut pos = 0;
776+
let mut i = nbytes;
775777
while i > 0 {
776778
val += (self.read_u8() as u64) << pos;
777779
pos += 8;
@@ -787,7 +789,8 @@ impl<T:Reader> ReaderUtil for T {
787789
fn read_be_uint_n(&self, nbytes: uint) -> u64 {
788790
assert!(nbytes > 0 && nbytes <= 8);
789791

790-
let mut (val, i) = (0u64, nbytes);
792+
let mut val = 0u64;
793+
let mut i = nbytes;
791794
while i > 0 {
792795
i -= 1;
793796
val += (self.read_u8() as u64) << i * 8;

src/libstd/num/int_macros.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,8 @@ impl Integer for $T {
400400
#[inline]
401401
fn gcd(&self, other: &$T) -> $T {
402402
// Use Euclid's algorithm
403-
let mut (m, n) = (*self, *other);
403+
let mut m = *self;
404+
let mut n = *other;
404405
while m != 0 {
405406
let temp = m;
406407
m = n % temp;

src/libstd/num/uint_macros.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,8 @@ impl Integer for $T {
237237
#[inline]
238238
fn gcd(&self, other: &$T) -> $T {
239239
// Use Euclid's algorithm
240-
let mut (m, n) = (*self, *other);
240+
let mut m = *self;
241+
let mut n = *other;
241242
while m != 0 {
242243
let temp = m;
243244
m = n % temp;

src/libstd/rand.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,8 @@ impl IsaacRng {
720720
fn isaac(&mut self) {
721721
self.c += 1;
722722
// abbreviations
723-
let mut (a, b) = (self.a, self.b + self.c);
723+
let mut a = self.a;
724+
let mut b = self.b + self.c;
724725

725726
static midpoint: uint = RAND_SIZE as uint / 2;
726727

src/libstd/rand/distributions.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ impl Rand for StandardNormal {
8989
// do-while, so the condition should be true on the first
9090
// run, they get overwritten anyway (0 < 1, so these are
9191
// good).
92-
let mut (x, y) = (1.0, 0.0);
92+
let mut x = 1.0;
93+
let mut y = 0.0;
9394

9495
// XXX infinities?
9596
while -2.0*y < x * x {

src/libstd/rt/io/extensions.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,9 @@ impl<T: Reader> ReaderByteConversions for T {
343343
fn read_le_uint_n(&mut self, nbytes: uint) -> u64 {
344344
assert!(nbytes > 0 && nbytes <= 8);
345345

346-
let mut (val, pos, i) = (0u64, 0, nbytes);
346+
let mut val = 0u64;
347+
let mut pos = 0;
348+
let mut i = nbytes;
347349
while i > 0 {
348350
val += (self.read_u8() as u64) << pos;
349351
pos += 8;
@@ -359,7 +361,8 @@ impl<T: Reader> ReaderByteConversions for T {
359361
fn read_be_uint_n(&mut self, nbytes: uint) -> u64 {
360362
assert!(nbytes > 0 && nbytes <= 8);
361363

362-
let mut (val, i) = (0u64, nbytes);
364+
let mut val = 0u64;
365+
let mut i = nbytes;
363366
while i > 0 {
364367
i -= 1;
365368
val += (self.read_u8() as u64) << i * 8;

src/libstd/str.rs

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,31 @@ pub fn each_split_within<'a>(ss: &'a str,
473473
return cont;
474474
}
475475

476+
/**
477+
* Replace all occurrences of one string with another
478+
*
479+
* # Arguments
480+
*
481+
* * s - The string containing substrings to replace
482+
* * from - The string to replace
483+
* * to - The replacement string
484+
*
485+
* # Return value
486+
*
487+
* The original string with all occurances of `from` replaced with `to`
488+
*/
489+
pub fn replace(s: &str, from: &str, to: &str) -> ~str {
490+
let mut result = ~"";
491+
let mut last_end = 0;
492+
for s.matches_index_iter(from).advance |(start, end)| {
493+
result.push_str(unsafe{raw::slice_bytes(s, last_end, start)});
494+
result.push_str(to);
495+
last_end = end;
496+
}
497+
result.push_str(unsafe{raw::slice_bytes(s, last_end, s.len())});
498+
result
499+
}
500+
476501
/*
477502
Section: Comparing strings
478503
*/
@@ -631,6 +656,48 @@ pub fn with_capacity(capacity: uint) -> ~str {
631656
buf
632657
}
633658

659+
/**
660+
* As char_len but for a slice of a string
661+
*
662+
* # Arguments
663+
*
664+
* * s - A valid string
665+
* * start - The position inside `s` where to start counting in bytes
666+
* * end - The position where to stop counting
667+
*
668+
* # Return value
669+
*
670+
* The number of Unicode characters in `s` between the given indices.
671+
*/
672+
pub fn count_chars(s: &str, start: uint, end: uint) -> uint {
673+
assert!(s.is_char_boundary(start));
674+
assert!(s.is_char_boundary(end));
675+
let mut i = start;
676+
let mut len = 0u;
677+
while i < end {
678+
let next = s.char_range_at(i).next;
679+
len += 1u;
680+
i = next;
681+
}
682+
return len;
683+
}
684+
685+
/// Counts the number of bytes taken by the first `n` chars in `s`
686+
/// starting from `start`.
687+
pub fn count_bytes<'b>(s: &'b str, start: uint, n: uint) -> uint {
688+
assert!(is_char_boundary(s, start));
689+
let mut end = start;
690+
let mut cnt = n;
691+
let l = s.len();
692+
while cnt > 0u {
693+
assert!(end < l);
694+
let next = s.char_range_at(end).next;
695+
cnt -= 1u;
696+
end = next;
697+
}
698+
end - start
699+
}
700+
634701
/// Given a first byte, determine how many bytes are in this UTF-8 character
635702
pub fn utf8_char_width(b: u8) -> uint {
636703
let byte: uint = b as uint;
@@ -737,7 +804,8 @@ pub mod raw {
737804

738805
/// Create a Rust string from a null-terminated *u8 buffer
739806
pub unsafe fn from_buf(buf: *u8) -> ~str {
740-
let mut (curr, i) = (buf, 0u);
807+
let mut curr = buf;
808+
let mut i = 0u;
741809
while *curr != 0u8 {
742810
i += 1u;
743811
curr = ptr::offset(buf, i);

src/libstd/task/spawn.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,9 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) {
636636
let child_data = Cell::new((notify_chan, child_arc, ancestors));
637637
let result: ~fn() = || {
638638
// Agh. Get move-mode items into the closure. FIXME (#2829)
639-
let mut (notify_chan, child_arc, ancestors) = child_data.take();
639+
let (notify_chan, child_arc, ancestors) = child_data.take();
640+
let mut child_arc = child_arc;
641+
let mut ancestors = ancestors;
640642
// Child task runs this code.
641643

642644
// Even if the below code fails to kick the child off, we must

0 commit comments

Comments
 (0)