Skip to content

Commit ae23beb

Browse files
committed
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.
2 parents 900de0f + bada191 commit ae23beb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+405
-429
lines changed

Makefile.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ ifdef SAVE_TEMPS
111111
CFG_RUSTC_FLAGS += --save-temps
112112
endif
113113
ifdef ASM_COMMENTS
114-
CFG_RUSTC_FLAGS += -z asm-comments
114+
CFG_RUSTC_FLAGS += -Z asm-comments
115115
endif
116116
ifdef TIME_PASSES
117117
CFG_RUSTC_FLAGS += -Z time-passes

doc/rust.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2826,7 +2826,7 @@ Within the body of an item that has type parameter declarations, the names of it
28262826
~~~~~~~
28272827
fn map<A: Copy, B: Copy>(f: &fn(A) -> B, xs: &[A]) -> ~[B] {
28282828
if xs.len() == 0 { return ~[]; }
2829-
let first: B = f(xs[0]);
2829+
let first: B = f(copy xs[0]);
28302830
let rest: ~[B] = map(f, xs.slice(1, xs.len()));
28312831
return ~[first] + rest;
28322832
}

doc/tutorial.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,12 +1941,14 @@ fn head_bad<T>(v: &[T]) -> T {
19411941
~~~~
19421942

19431943
However, we can tell the compiler that the `head` function is only for
1944-
copyable types: that is, those that have the `Copy` trait.
1944+
copyable types: that is, those that have the `Copy` trait. In that
1945+
case, we can explicitly create a second copy of the value we are
1946+
returning using the `copy` keyword:
19451947

19461948
~~~~
19471949
// This does
19481950
fn head<T: Copy>(v: &[T]) -> T {
1949-
v[0]
1951+
copy v[0]
19501952
}
19511953
~~~~
19521954

@@ -2137,7 +2139,7 @@ as in this version of `print_all` that copies elements.
21372139
fn print_all<T: Printable + Copy>(printable_things: ~[T]) {
21382140
let mut i = 0;
21392141
while i < printable_things.len() {
2140-
let copy_of_thing = printable_things[i];
2142+
let copy_of_thing = copy printable_things[i];
21412143
copy_of_thing.print();
21422144
i += 1;
21432145
}

src/libextra/c_vec.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ pub unsafe fn c_vec_with_dtor<T>(base: *mut T, len: uint, dtor: @fn())
122122
*/
123123
pub fn get<T:Copy>(t: CVec<T>, ofs: uint) -> T {
124124
assert!(ofs < len(t));
125-
return unsafe { *ptr::mut_offset(t.base, ofs) };
125+
return unsafe { copy *ptr::mut_offset(t.base, ofs) };
126126
}
127127

128128
/**

src/libextra/deque.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -264,31 +264,31 @@ mod tests {
264264
fn test_parameterized<T:Copy + Eq>(a: T, b: T, c: T, d: T) {
265265
let mut deq = Deque::new();
266266
assert_eq!(deq.len(), 0);
267-
deq.add_front(a);
268-
deq.add_front(b);
269-
deq.add_back(c);
267+
deq.add_front(copy a);
268+
deq.add_front(copy b);
269+
deq.add_back(copy c);
270270
assert_eq!(deq.len(), 3);
271-
deq.add_back(d);
271+
deq.add_back(copy d);
272272
assert_eq!(deq.len(), 4);
273-
assert_eq!(*deq.peek_front(), b);
274-
assert_eq!(*deq.peek_back(), d);
275-
assert_eq!(deq.pop_front(), b);
276-
assert_eq!(deq.pop_back(), d);
277-
assert_eq!(deq.pop_back(), c);
278-
assert_eq!(deq.pop_back(), a);
273+
assert_eq!(copy *deq.peek_front(), copy b);
274+
assert_eq!(copy *deq.peek_back(), copy d);
275+
assert_eq!(deq.pop_front(), copy b);
276+
assert_eq!(deq.pop_back(), copy d);
277+
assert_eq!(deq.pop_back(), copy c);
278+
assert_eq!(deq.pop_back(), copy a);
279279
assert_eq!(deq.len(), 0);
280-
deq.add_back(c);
280+
deq.add_back(copy c);
281281
assert_eq!(deq.len(), 1);
282-
deq.add_front(b);
282+
deq.add_front(copy b);
283283
assert_eq!(deq.len(), 2);
284-
deq.add_back(d);
284+
deq.add_back(copy d);
285285
assert_eq!(deq.len(), 3);
286-
deq.add_front(a);
286+
deq.add_front(copy a);
287287
assert_eq!(deq.len(), 4);
288-
assert_eq!(*deq.get(0), a);
289-
assert_eq!(*deq.get(1), b);
290-
assert_eq!(*deq.get(2), c);
291-
assert_eq!(*deq.get(3), d);
288+
assert_eq!(copy *deq.get(0), copy a);
289+
assert_eq!(copy *deq.get(1), copy b);
290+
assert_eq!(copy *deq.get(2), copy c);
291+
assert_eq!(copy *deq.get(3), copy d);
292292
}
293293

294294
#[deriving(Eq)]

src/libextra/dlist.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ pub fn from_elem<T>(data: T) -> @mut DList<T> {
111111
/// Creates a new dlist from a vector of elements, maintaining the same order
112112
pub fn from_vec<T:Copy>(vec: &[T]) -> @mut DList<T> {
113113
do vec.iter().fold(DList()) |list,data| {
114-
list.push(*data); // Iterating left-to-right -- add newly to the tail.
114+
// Iterating left-to-right -- add newly to the tail.
115+
list.push(copy *data);
115116
list
116117
}
117118
}
@@ -460,35 +461,35 @@ impl<T> DList<T> {
460461
impl<T:Copy> DList<T> {
461462
/// Remove data from the head of the list. O(1).
462463
pub fn pop(@mut self) -> Option<T> {
463-
self.pop_n().map(|nobe| nobe.data)
464+
self.pop_n().map(|nobe| copy nobe.data)
464465
}
465466

466467
/// Remove data from the tail of the list. O(1).
467468
pub fn pop_tail(@mut self) -> Option<T> {
468-
self.pop_tail_n().map(|nobe| nobe.data)
469+
self.pop_tail_n().map(|nobe| copy nobe.data)
469470
}
470471

471472
/// Get data at the list's head. O(1).
472473
pub fn peek(@mut self) -> Option<T> {
473-
self.peek_n().map(|nobe| nobe.data)
474+
self.peek_n().map(|nobe| copy nobe.data)
474475
}
475476

476477
/// Get data at the list's tail. O(1).
477478
pub fn peek_tail(@mut self) -> Option<T> {
478-
self.peek_tail_n().map (|nobe| nobe.data)
479+
self.peek_tail_n().map (|nobe| copy nobe.data)
479480
}
480481

481482
/// Get data at the list's head, failing if empty. O(1).
482-
pub fn head(@mut self) -> T { self.head_n().data }
483+
pub fn head(@mut self) -> T { copy self.head_n().data }
483484

484485
/// Get data at the list's tail, failing if empty. O(1).
485-
pub fn tail(@mut self) -> T { self.tail_n().data }
486+
pub fn tail(@mut self) -> T { copy self.tail_n().data }
486487

487488
/// Get the elements of the list as a vector. O(n).
488489
pub fn to_vec(@mut self) -> ~[T] {
489490
let mut v = vec::with_capacity(self.size);
490491
for old_iter::eachi(&self) |index,data| {
491-
v[index] = *data;
492+
v[index] = copy *data;
492493
}
493494
v
494495
}

src/libextra/future.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ priv enum FutureState<A> {
5757
impl<A:Copy> Future<A> {
5858
pub fn get(&mut self) -> A {
5959
//! Get the value of the future.
60-
*(self.get_ref())
60+
copy *(self.get_ref())
6161
}
6262
}
6363

src/libextra/list.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub enum MutList<T> {
2727

2828
/// Create a list from a vector
2929
pub fn from_vec<T:Copy>(v: &[T]) -> @List<T> {
30-
v.rev_iter().fold(@Nil::<T>, |t, h| @Cons(*h, t))
30+
v.rev_iter().fold(@Nil::<T>, |t, h| @Cons(copy *h, t))
3131
}
3232

3333
/**
@@ -61,7 +61,7 @@ pub fn find<T:Copy>(ls: @List<T>, f: &fn(&T) -> bool) -> Option<T> {
6161
loop {
6262
ls = match *ls {
6363
Cons(ref hd, tl) => {
64-
if f(hd) { return Some(*hd); }
64+
if f(hd) { return Some(copy *hd); }
6565
tl
6666
}
6767
Nil => return None

src/libextra/smallintmap.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ impl<V:Copy> SmallIntMap<V> {
179179
ff: &fn(uint, V, V) -> V) -> bool {
180180
let new_val = match self.find(&key) {
181181
None => val,
182-
Some(orig) => ff(key, *orig, val)
182+
Some(orig) => ff(key, copy *orig, val)
183183
};
184184
self.insert(key, new_val)
185185
}

src/libextra/sort.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub fn merge_sort<T:Copy>(v: &[T], le: Le<T>) -> ~[T] {
3737

3838
let v_len = end - begin;
3939
if v_len == 0 { return ~[]; }
40-
if v_len == 1 { return ~[v[begin]]; }
40+
if v_len == 1 { return ~[copy v[begin]]; }
4141

4242
let mid = v_len / 2 + begin;
4343
let a = (begin, mid);
@@ -53,9 +53,9 @@ pub fn merge_sort<T:Copy>(v: &[T], le: Le<T>) -> ~[T] {
5353
let mut b_ix = 0;
5454
while a_ix < a_len && b_ix < b_len {
5555
if le(&a[a_ix], &b[b_ix]) {
56-
rs.push(a[a_ix]);
56+
rs.push(copy a[a_ix]);
5757
a_ix += 1;
58-
} else { rs.push(b[b_ix]); b_ix += 1; }
58+
} else { rs.push(copy b[b_ix]); b_ix += 1; }
5959
}
6060
rs.push_all(vec::slice(a, a_ix, a_len));
6161
rs.push_all(vec::slice(b, b_ix, b_len));
@@ -106,7 +106,7 @@ pub fn quick_sort<T>(arr: &mut [T], compare_func: Le<T>) {
106106

107107
fn qsort3<T:Copy + Ord + Eq>(arr: &mut [T], left: int, right: int) {
108108
if right <= left { return; }
109-
let v: T = arr[right];
109+
let v: T = copy arr[right];
110110
let mut i: int = left - 1;
111111
let mut j: int = right;
112112
let mut p: int = i;
@@ -233,7 +233,7 @@ fn binarysort<T:Copy + Ord>(array: &mut [T], start: uint) {
233233
if start == 0 { start += 1; }
234234

235235
while start < size {
236-
let pivot = array[start];
236+
let pivot = copy array[start];
237237
let mut left = 0;
238238
let mut right = start;
239239
assert!(left <= right);
@@ -470,7 +470,7 @@ impl<T:Copy + Ord> MergeState<T> {
470470

471471
let mut tmp = ~[];
472472
for uint::range(base1, base1+len1) |i| {
473-
tmp.push(array[i]);
473+
tmp.push(copy array[i]);
474474
}
475475

476476
let mut c1 = 0;
@@ -580,7 +580,7 @@ impl<T:Copy + Ord> MergeState<T> {
580580

581581
let mut tmp = ~[];
582582
for uint::range(base2, base2+len2) |i| {
583-
tmp.push(array[i]);
583+
tmp.push(copy array[i]);
584584
}
585585

586586
let mut c1 = base1 + len1 - 1;
@@ -732,7 +732,7 @@ fn copy_vec<T:Copy>(dest: &mut [T],
732732
assert!(s1+from.len() <= dest.len());
733733

734734
for from.eachi |i, v| {
735-
dest[s1+i] = *v;
735+
dest[s1+i] = copy *v;
736736
}
737737
}
738738

@@ -1045,7 +1045,7 @@ mod big_tests {
10451045
fn multiplyVec<T:Copy>(arr: &[T], num: uint) -> ~[T] {
10461046
let size = arr.len();
10471047
let res = do vec::from_fn(num) |i| {
1048-
arr[i % size]
1048+
copy arr[i % size]
10491049
};
10501050
res
10511051
}

src/librustc/metadata/encoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1184,7 +1184,7 @@ fn create_index<T:Copy + Hash + IterBytes>(index: ~[entry<T>]) ->
11841184
for uint::range(0u, 256u) |_i| { buckets.push(@mut ~[]); };
11851185
for index.each |elt| {
11861186
let h = elt.val.hash() as uint;
1187-
buckets[h % 256].push(*elt);
1187+
buckets[h % 256].push(copy *elt);
11881188
}
11891189

11901190
let mut buckets_frozen = ~[];

src/librustc/middle/borrowck/gather_loans/gather_moves.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ fn check_is_legal_to_move_from(bccx: @BorrowckCtxt,
105105
mc::cat_implicit_self(*) |
106106
mc::cat_copied_upvar(*) |
107107
mc::cat_deref(_, _, mc::region_ptr(*)) |
108-
mc::cat_deref(_, _, mc::gc_ptr(*)) => {
108+
mc::cat_deref(_, _, mc::gc_ptr(*)) |
109+
mc::cat_deref(_, _, mc::unsafe_ptr(*)) => {
109110
bccx.span_err(
110111
cmt0.span,
111112
fmt!("cannot move out of %s",
@@ -129,8 +130,7 @@ fn check_is_legal_to_move_from(bccx: @BorrowckCtxt,
129130
mc::cat_rvalue(*) |
130131
mc::cat_local(*) |
131132
mc::cat_arg(*) |
132-
mc::cat_self(*) |
133-
mc::cat_deref(_, _, mc::unsafe_ptr(*)) => {
133+
mc::cat_self(*) => {
134134
true
135135
}
136136

src/librustc/middle/trans/debuginfo.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ fn cached_metadata<T:Copy>(cache: metadata_cache,
200200
let items = cache.get(&mdtag);
201201
for items.each |item| {
202202
let md: T = md_from_metadata::<T>(*item);
203-
if eq_fn(md) {
204-
return option::Some(md);
203+
if eq_fn(copy md) {
204+
return option::Some(copy md);
205205
}
206206
}
207207
}

src/librustc/middle/ty.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2273,7 +2273,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
22732273
for type_param_def.bounds.builtin_bounds.each |bound| {
22742274
debug!("tc = %s, bound = %?", tc.to_str(), bound);
22752275
tc = tc - match bound {
2276-
BoundCopy => TypeContents::nonimplicitly_copyable(cx),
2276+
BoundCopy => TypeContents::noncopyable(cx),
22772277
BoundStatic => TypeContents::nonstatic(cx),
22782278
BoundOwned => TypeContents::nonowned(cx),
22792279
BoundConst => TypeContents::nonconst(cx),
@@ -3694,16 +3694,16 @@ fn lookup_locally_or_in_crate_store<V:Copy>(
36943694
*/
36953695

36963696
match map.find(&def_id) {
3697-
Some(&v) => { return v; }
3697+
Some(&ref v) => { return copy *v; }
36983698
None => { }
36993699
}
37003700

37013701
if def_id.crate == ast::local_crate {
37023702
fail!("No def'n found for %? in tcx.%s", def_id, descr);
37033703
}
37043704
let v = load_external();
3705-
map.insert(def_id, v);
3706-
return v;
3705+
map.insert(def_id, copy v);
3706+
return copy v;
37073707
}
37083708

37093709
pub fn trait_method(cx: ctxt, trait_did: ast::def_id, idx: uint) -> @Method {

0 commit comments

Comments
 (0)