diff options
| author | bors <bors@rust-lang.org> | 2013-06-16 09:54:59 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-06-16 09:54:59 -0700 |
| commit | ae23beb52f637b8c8640706ee8c6d2d4a5796bc8 (patch) | |
| tree | 86c72c3bb92054b0ba9aff59cbe9c0391eb88c99 /src/libstd | |
| parent | 900de0ffaded223c0ed75188226e499e332416be (diff) | |
| parent | bada191309d43d481d265bb1ff9c3a14e827babf (diff) | |
| download | rust-ae23beb52f637b8c8640706ee8c6d2d4a5796bc8.tar.gz rust-ae23beb52f637b8c8640706ee8c6d2d4a5796bc8.zip | |
auto merge of #7167 : nikomatsakis/rust/ref-bindings-explicit-copy-in-generics, r=brson
Two changes: 1. Make type parameters move by default, even if they have a Copy bound. After all, they could be bound to `~T` or `~[]`. Also, this is a necessary step towards removing `copy` keyword and replacing with clone. 2. Make it illegal to move from `*T`. This is dangerous in a "moves-by-default" scenario, because it's very easy to move when working with a `*T` pointer. Also, it requires zeroing memory, which we hope to do away with someday.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/at_vec.rs | 6 | ||||
| -rw-r--r-- | src/libstd/either.rs | 4 | ||||
| -rw-r--r-- | src/libstd/io.rs | 2 | ||||
| -rw-r--r-- | src/libstd/num/num.rs | 6 | ||||
| -rw-r--r-- | src/libstd/num/strconv.rs | 28 | ||||
| -rw-r--r-- | src/libstd/old_iter.rs | 12 | ||||
| -rw-r--r-- | src/libstd/option.rs | 12 | ||||
| -rw-r--r-- | src/libstd/pipes.rs | 13 | ||||
| -rw-r--r-- | src/libstd/rand.rs | 6 | ||||
| -rw-r--r-- | src/libstd/task/spawn.rs | 17 | ||||
| -rw-r--r-- | src/libstd/tuple.rs | 6 | ||||
| -rw-r--r-- | src/libstd/vec.rs | 34 |
12 files changed, 67 insertions, 79 deletions
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index a118e445fe2..56646eb4bfb 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -107,8 +107,8 @@ pub fn build_sized_opt<A>(size: Option<uint>, #[inline(always)] pub fn append<T:Copy>(lhs: @[T], rhs: &const [T]) -> @[T] { do build_sized(lhs.len() + rhs.len()) |push| { - for lhs.each |x| { push(*x); } - for uint::range(0, rhs.len()) |i| { push(rhs[i]); } + for lhs.each |x| { push(copy *x); } + for uint::range(0, rhs.len()) |i| { push(copy rhs[i]); } } } @@ -168,7 +168,7 @@ pub fn to_managed_consume<T>(v: ~[T]) -> @[T] { * elements of a slice. */ pub fn to_managed<T:Copy>(v: &[T]) -> @[T] { - from_fn(v.len(), |i| v[i]) + from_fn(v.len(), |i| copy v[i]) } #[cfg(not(test))] diff --git a/src/libstd/either.rs b/src/libstd/either.rs index fac0866f17e..e0451b2c65d 100644 --- a/src/libstd/either.rs +++ b/src/libstd/either.rs @@ -47,7 +47,7 @@ pub fn lefts<T:Copy,U>(eithers: &[Either<T, U>]) -> ~[T] { do vec::build_sized(eithers.len()) |push| { for eithers.each |elt| { match *elt { - Left(ref l) => { push(*l); } + Left(ref l) => { push(copy *l); } _ => { /* fallthrough */ } } } @@ -59,7 +59,7 @@ pub fn rights<T, U: Copy>(eithers: &[Either<T, U>]) -> ~[U] { do vec::build_sized(eithers.len()) |push| { for eithers.each |elt| { match *elt { - Right(ref r) => { push(*r); } + Right(ref r) => { push(copy *r); } _ => { /* fallthrough */ } } } diff --git a/src/libstd/io.rs b/src/libstd/io.rs index d3faa75e3b0..3e771c4ddde 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -1779,7 +1779,7 @@ pub mod fsync { None => (), Some(level) => { // fail hard if not succesful - assert!(((self.arg.fsync_fn)(self.arg.val, level) + assert!(((self.arg.fsync_fn)(copy self.arg.val, level) != -1)); } } diff --git a/src/libstd/num/num.rs b/src/libstd/num/num.rs index 4681e4f4f53..e7315624368 100644 --- a/src/libstd/num/num.rs +++ b/src/libstd/num/num.rs @@ -410,10 +410,10 @@ pub fn pow_with_uint<T:NumCast+One+Zero+Copy+Div<T,T>+Mul<T,T>>(radix: uint, pow let mut multiplier = cast(radix); while (my_pow > 0u) { if my_pow % 2u == 1u { - total *= multiplier; + total = total * multiplier; } - my_pow /= 2u; - multiplier *= multiplier; + my_pow = my_pow / 2u; + multiplier = multiplier * multiplier; } total } diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index 3905d82cd0f..75c4fa98a2b 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -229,7 +229,7 @@ pub fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Copy+ }; // Decrease the deccumulator one digit at a time - deccum /= radix_gen; + deccum = deccum / radix_gen; deccum = deccum.round_to_zero(); buf.push(char::from_digit(current_digit.to_int() as uint, radix) @@ -282,7 +282,7 @@ pub fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Copy+ ) ) { // Shift first fractional digit into the integer part - deccum *= radix_gen; + deccum = deccum * radix_gen; // Calculate the absolute value of each digit. // See note in first loop. @@ -499,8 +499,8 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+ // Initialize accumulator with signed zero for floating point parsing to // work - let mut accum = if accum_positive { _0 } else { -_1 * _0}; - let mut last_accum = accum; // Necessary to detect overflow + let mut accum = if accum_positive { copy _0 } else { -_1 * _0}; + let mut last_accum = copy accum; // Necessary to detect overflow let mut i = start; let mut exp_found = false; @@ -511,13 +511,13 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+ match char::to_digit(c, radix) { Some(digit) => { // shift accum one digit left - accum *= radix_gen; + accum = accum * copy radix_gen; // add/subtract current digit depending on sign if accum_positive { - accum += cast(digit as int); + accum = accum + cast(digit as int); } else { - accum -= cast(digit as int); + accum = accum - cast(digit as int); } // Detect overflow by comparing to last value, except @@ -526,7 +526,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+ if accum_positive && accum <= last_accum { return None; } if !accum_positive && accum >= last_accum { return None; } } - last_accum = accum; + last_accum = copy accum; } None => match c { '_' if ignore_underscores => {} @@ -548,7 +548,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+ // Parse fractional part of number // Skip if already reached start of exponent if !exp_found { - let mut power = _1; + let mut power = copy _1; while i < len { let c = buf[i] as char; @@ -556,21 +556,21 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+ match char::to_digit(c, radix) { Some(digit) => { // Decrease power one order of magnitude - power /= radix_gen; + power = power / radix_gen; let digit_t: T = cast(digit); // add/subtract current digit depending on sign if accum_positive { - accum += digit_t * power; + accum = accum + digit_t * power; } else { - accum -= digit_t * power; + accum = accum - digit_t * power; } // Detect overflow by comparing to last value if accum_positive && accum < last_accum { return None; } if !accum_positive && accum > last_accum { return None; } - last_accum = accum; + last_accum = copy accum; } None => match c { '_' if ignore_underscores => {} @@ -596,7 +596,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+ } } - let mut multiplier = _1; + let mut multiplier = copy _1; if exp_found { let c = buf[i] as char; diff --git a/src/libstd/old_iter.rs b/src/libstd/old_iter.rs index 347b4774422..96bcf4e9107 100644 --- a/src/libstd/old_iter.rs +++ b/src/libstd/old_iter.rs @@ -115,7 +115,7 @@ pub fn filter_to_vec<A:Copy,IA:BaseIter<A>>(this: &IA, -> ~[A] { do vec::build_sized_opt(this.size_hint()) |push| { for this.each |a| { - if prd(a) { push(*a); } + if prd(a) { push(copy *a); } } } } @@ -191,7 +191,7 @@ pub fn position<A,IA:BaseIter<A>>(this: &IA, f: &fn(&A) -> bool) pub fn find<A:Copy,IA:BaseIter<A>>(this: &IA, f: &fn(&A) -> bool) -> Option<A> { for this.each |i| { - if f(i) { return Some(*i) } + if f(i) { return Some(copy *i) } } return None; } @@ -270,7 +270,7 @@ pub fn from_fn<T,BT: Buildable<T>>(n_elts: uint, op: InitOp<T>) -> BT { pub fn from_elem<T:Copy,BT:Buildable<T>>(n_elts: uint, t: T) -> BT { do Buildable::build_sized(n_elts) |push| { let mut i: uint = 0; - while i < n_elts { push(t); i += 1; } + while i < n_elts { push(copy t); i += 1; } } } @@ -281,8 +281,8 @@ pub fn append<T:Copy,IT:BaseIter<T>,BT:Buildable<T>>(lhs: &IT, rhs: &IT) let size_opt = lhs.size_hint().chain_ref( |sz1| rhs.size_hint().map(|sz2| *sz1+*sz2)); do build_sized_opt(size_opt) |push| { - for lhs.each |x| { push(*x); } - for rhs.each |x| { push(*x); } + for lhs.each |x| { push(copy *x); } + for rhs.each |x| { push(copy *x); } } } @@ -291,6 +291,6 @@ pub fn append<T:Copy,IT:BaseIter<T>,BT:Buildable<T>>(lhs: &IT, rhs: &IT) #[inline(always)] pub fn copy_seq<T:Copy,IT:BaseIter<T>,BT:Buildable<T>>(v: &IT) -> BT { do build_sized_opt(v.size_hint()) |push| { - for v.each |x| { push(*x); } + for v.each |x| { push(copy *x); } } } diff --git a/src/libstd/option.rs b/src/libstd/option.rs index 76272706445..30394cb21af 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -88,14 +88,14 @@ impl<T:Ord> Ord for Option<T> { } } -impl<T: Copy + Add<T,T>> Add<Option<T>, Option<T>> for Option<T> { +impl<T: Copy+Add<T,T>> Add<Option<T>, Option<T>> for Option<T> { #[inline(always)] fn add(&self, other: &Option<T>) -> Option<T> { - match (*self, *other) { - (None, None) => None, - (_, None) => *self, - (None, _) => *other, - (Some(ref lhs), Some(ref rhs)) => Some(*lhs + *rhs) + match (&*self, &*other) { + (&None, &None) => None, + (_, &None) => copy *self, + (&None, _) => copy *other, + (&Some(ref lhs), &Some(ref rhs)) => Some(*lhs + *rhs) } } } diff --git a/src/libstd/pipes.rs b/src/libstd/pipes.rs index 012ad0ed80d..3448401e0b1 100644 --- a/src/libstd/pipes.rs +++ b/src/libstd/pipes.rs @@ -85,7 +85,8 @@ bounded and unbounded protocols allows for less code duplication. #[allow(missing_doc)]; use container::Container; -use cast::{forget, transmute, transmute_copy}; +use cast::{forget, transmute, transmute_copy, transmute_mut}; +use cast; use either::{Either, Left, Right}; use iterator::IteratorUtil; use kinds::Owned; @@ -102,10 +103,6 @@ use util::replace; static SPIN_COUNT: uint = 0; -macro_rules! move_it ( - { $x:expr } => ( unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } ) -) - #[deriving(Eq)] enum State { Empty, @@ -316,9 +313,11 @@ impl<T> Drop for BufferResource<T> { fn finalize(&self) { unsafe { // FIXME(#4330) Need self by value to get mutability. - let this: &mut BufferResource<T> = transmute(self); + let this: &mut BufferResource<T> = transmute_mut(self); + + let null_buffer: ~Buffer<T> = transmute(ptr::null::<Buffer<T>>()); + let mut b = replace(&mut this.buffer, null_buffer); - let mut b = move_it!(this.buffer); //let p = ptr::to_unsafe_ptr(*b); //error!("drop %?", p); let old_count = intrinsics::atomic_xsub_rel( diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs index 7946f7e4f13..2d73ed0c6a1 100644 --- a/src/libstd/rand.rs +++ b/src/libstd/rand.rs @@ -526,7 +526,7 @@ impl<R: Rng> RngUtil for R { if values.is_empty() { None } else { - Some(values[self.gen_uint_range(0u, values.len())]) + Some(copy values[self.gen_uint_range(0u, values.len())]) } } /** @@ -555,7 +555,7 @@ impl<R: Rng> RngUtil for R { for v.each |item| { so_far += item.weight; if so_far > chosen { - return Some(item.item); + return Some(copy item.item); } } util::unreachable(); @@ -569,7 +569,7 @@ impl<R: Rng> RngUtil for R { let mut r = ~[]; for v.each |item| { for uint::range(0u, item.weight) |_i| { - r.push(item.item); + r.push(copy item.item); } } r diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 30ad4ee2a89..fa1790d79cb 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -98,10 +98,6 @@ use iterator::{IteratorUtil}; #[cfg(test)] use comm; #[cfg(test)] use task; -macro_rules! move_it ( - { $x:expr } => ( unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } ) -) - type TaskSet = HashSet<*rust_task>; fn new_taskset() -> TaskSet { @@ -638,23 +634,16 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) { notify_chan: Option<Chan<TaskResult>>, f: ~fn()) -> ~fn() { - let child_data = Cell::new((child_arc, ancestors)); + 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 (child_arc, ancestors) = child_data.take(); + let mut (notify_chan, child_arc, ancestors) = child_data.take(); // Child task runs this code. // Even if the below code fails to kick the child off, we must // send Something on the notify channel. - //let mut notifier = None;//notify_chan.map(|c| AutoNotify(c)); - let notifier = match notify_chan { - Some(ref notify_chan_value) => { - let moved_ncv = move_it!(*notify_chan_value); - Some(AutoNotify(moved_ncv)) - } - _ => None - }; + let notifier = notify_chan.map_consume(|c| AutoNotify(c)); if enlist_many(child, &child_arc, &mut ancestors) { let group = @@mut TCB(child, diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs index b80f152a5b1..c120883be5a 100644 --- a/src/libstd/tuple.rs +++ b/src/libstd/tuple.rs @@ -32,7 +32,7 @@ impl<T:Copy,U:Copy> CopyableTuple<T, U> for (T, U) { #[inline(always)] fn first(&self) -> T { match *self { - (t, _) => t, + (ref t, _) => copy *t, } } @@ -40,14 +40,14 @@ impl<T:Copy,U:Copy> CopyableTuple<T, U> for (T, U) { #[inline(always)] fn second(&self) -> U { match *self { - (_, u) => u, + (_, ref u) => copy *u, } } /// Return the results of swapping the two elements of self #[inline(always)] fn swap(&self) -> (U, T) { - match *self { + match copy *self { (t, u) => (u, t), } } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 1a236a49a32..3f7bf897be2 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -167,7 +167,7 @@ pub fn from_elem<T:Copy>(n_elts: uint, t: T) -> ~[T] { /// Creates a new unique vector with the same contents as the slice pub fn to_owned<T:Copy>(t: &[T]) -> ~[T] { - from_fn(t.len(), |i| t[i]) + from_fn(t.len(), |i| copy t[i]) } /// Creates a new vector with a capacity of `capacity` @@ -441,9 +441,9 @@ pub fn partitioned<T:Copy>(v: &[T], f: &fn(&T) -> bool) -> (~[T], ~[T]) { for each(v) |elt| { if f(elt) { - lefts.push(*elt); + lefts.push(copy *elt); } else { - rights.push(*elt); + rights.push(copy *elt); } } @@ -798,7 +798,7 @@ pub fn grow<T:Copy>(v: &mut ~[T], n: uint, initval: &T) { let mut i: uint = 0u; while i < n { - v.push(*initval); + v.push(copy *initval); i += 1u; } } @@ -970,7 +970,7 @@ pub fn filter<T>(v: ~[T], f: &fn(t: &T) -> bool) -> ~[T] { pub fn filtered<T:Copy>(v: &[T], f: &fn(t: &T) -> bool) -> ~[T] { let mut result = ~[]; for each(v) |elem| { - if f(elem) { result.push(*elem); } + if f(elem) { result.push(copy *elem); } } result } @@ -1026,7 +1026,7 @@ impl<'self, T:Copy> VectorVector<T> for &'self [~[T]] { let mut r = ~[]; let mut first = true; for self.each |&inner| { - if first { first = false; } else { r.push(*sep); } + if first { first = false; } else { r.push(copy *sep); } r.push_all(inner); } r @@ -1044,7 +1044,7 @@ impl<'self, T:Copy> VectorVector<T> for &'self [&'self [T]] { let mut r = ~[]; let mut first = true; for self.each |&inner| { - if first { first = false; } else { r.push(*sep); } + if first { first = false; } else { r.push(copy *sep); } r.push_all(inner); } r @@ -1077,7 +1077,7 @@ pub fn find<T:Copy>(v: &[T], f: &fn(t: &T) -> bool) -> Option<T> { */ pub fn find_between<T:Copy>(v: &[T], start: uint, end: uint, f: &fn(t: &T) -> bool) -> Option<T> { - position_between(v, start, end, f).map(|i| v[*i]) + position_between(v, start, end, f).map(|i| copy v[*i]) } /** @@ -1103,7 +1103,7 @@ pub fn rfind_between<T:Copy>(v: &[T], end: uint, f: &fn(t: &T) -> bool) -> Option<T> { - rposition_between(v, start, end, f).map(|i| v[*i]) + rposition_between(v, start, end, f).map(|i| copy v[*i]) } /// Find the first index containing a matching value @@ -1227,7 +1227,7 @@ pub fn bsearch_elem<T:TotalOrd>(v: &[T], x: &T) -> Option<uint> { pub fn unzip_slice<T:Copy,U:Copy>(v: &[(T, U)]) -> (~[T], ~[U]) { let mut (ts, us) = (~[], ~[]); for each(v) |p| { - let (t, u) = *p; + let (t, u) = copy *p; ts.push(t); us.push(u); } @@ -1262,7 +1262,7 @@ pub fn zip_slice<T:Copy,U:Copy>(v: &const [T], u: &const [U]) let mut i = 0u; assert_eq!(sz, u.len()); while i < sz { - zipped.push((v[i], u[i])); + zipped.push((copy v[i], copy u[i])); i += 1u; } zipped @@ -1359,8 +1359,8 @@ pub fn reversed<T:Copy>(v: &const [T]) -> ~[T] { let mut rs: ~[T] = ~[]; let mut i = v.len(); if i == 0 { return (rs); } else { i -= 1; } - while i != 0 { rs.push(v[i]); i -= 1; } - rs.push(v[0]); + while i != 0 { rs.push(copy v[i]); i -= 1; } + rs.push(copy v[0]); rs } @@ -1479,7 +1479,7 @@ pub fn eachi<'r,T>(v: &'r [T], f: &fn(uint, v: &'r T) -> bool) -> bool { */ pub fn each_permutation<T:Copy>(values: &[T], fun: &fn(perm : &[T]) -> bool) -> bool { let length = values.len(); - let mut permutation = vec::from_fn(length, |i| values[i]); + let mut permutation = vec::from_fn(length, |i| copy values[i]); if length <= 1 { fun(permutation); return true; @@ -1506,7 +1506,7 @@ pub fn each_permutation<T:Copy>(values: &[T], fun: &fn(perm : &[T]) -> bool) -> reverse_part(indices, k+1, length); // fixup permutation based on indices for uint::range(k, length) |i| { - permutation[i] = values[indices[i]]; + permutation[i] = copy values[indices[i]]; } } } @@ -2031,7 +2031,7 @@ impl<'self,T:Copy> ImmutableCopyableVector<T> for &'self [T] { /// Returns the element at the given index, without doing bounds checking. #[inline(always)] unsafe fn unsafe_get(&self, index: uint) -> T { - *self.unsafe_ref(index) + copy *self.unsafe_ref(index) } } @@ -2350,7 +2350,7 @@ pub mod raw { */ #[inline(always)] pub unsafe fn get<T:Copy>(v: &const [T], i: uint) -> T { - as_const_buf(v, |p, _len| *ptr::const_offset(p, i)) + as_const_buf(v, |p, _len| copy *ptr::const_offset(p, i)) } /** |
