Skip to content

Ref bindings explicit copy in generics #7167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ ifdef SAVE_TEMPS
CFG_RUSTC_FLAGS += --save-temps
endif
ifdef ASM_COMMENTS
CFG_RUSTC_FLAGS += -z asm-comments
CFG_RUSTC_FLAGS += -Z asm-comments
endif
ifdef TIME_PASSES
CFG_RUSTC_FLAGS += -Z time-passes
Expand Down
2 changes: 1 addition & 1 deletion doc/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -2826,7 +2826,7 @@ Within the body of an item that has type parameter declarations, the names of it
~~~~~~~
fn map<A: Copy, B: Copy>(f: &fn(A) -> B, xs: &[A]) -> ~[B] {
if xs.len() == 0 { return ~[]; }
let first: B = f(xs[0]);
let first: B = f(copy xs[0]);
let rest: ~[B] = map(f, xs.slice(1, xs.len()));
return ~[first] + rest;
}
Expand Down
8 changes: 5 additions & 3 deletions doc/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -1941,12 +1941,14 @@ fn head_bad<T>(v: &[T]) -> T {
~~~~

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

~~~~
// This does
fn head<T: Copy>(v: &[T]) -> T {
v[0]
copy v[0]
}
~~~~

Expand Down Expand Up @@ -2137,7 +2139,7 @@ as in this version of `print_all` that copies elements.
fn print_all<T: Printable + Copy>(printable_things: ~[T]) {
let mut i = 0;
while i < printable_things.len() {
let copy_of_thing = printable_things[i];
let copy_of_thing = copy printable_things[i];
copy_of_thing.print();
i += 1;
}
Expand Down
2 changes: 1 addition & 1 deletion src/libextra/c_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ pub unsafe fn c_vec_with_dtor<T>(base: *mut T, len: uint, dtor: @fn())
*/
pub fn get<T:Copy>(t: CVec<T>, ofs: uint) -> T {
assert!(ofs < len(t));
return unsafe { *ptr::mut_offset(t.base, ofs) };
return unsafe { copy *ptr::mut_offset(t.base, ofs) };
}

/**
Expand Down
36 changes: 18 additions & 18 deletions src/libextra/deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,31 +264,31 @@ mod tests {
fn test_parameterized<T:Copy + Eq>(a: T, b: T, c: T, d: T) {
let mut deq = Deque::new();
assert_eq!(deq.len(), 0);
deq.add_front(a);
deq.add_front(b);
deq.add_back(c);
deq.add_front(copy a);
deq.add_front(copy b);
deq.add_back(copy c);
assert_eq!(deq.len(), 3);
deq.add_back(d);
deq.add_back(copy d);
assert_eq!(deq.len(), 4);
assert_eq!(*deq.peek_front(), b);
assert_eq!(*deq.peek_back(), d);
assert_eq!(deq.pop_front(), b);
assert_eq!(deq.pop_back(), d);
assert_eq!(deq.pop_back(), c);
assert_eq!(deq.pop_back(), a);
assert_eq!(copy *deq.peek_front(), copy b);
assert_eq!(copy *deq.peek_back(), copy d);
assert_eq!(deq.pop_front(), copy b);
assert_eq!(deq.pop_back(), copy d);
assert_eq!(deq.pop_back(), copy c);
assert_eq!(deq.pop_back(), copy a);
assert_eq!(deq.len(), 0);
deq.add_back(c);
deq.add_back(copy c);
assert_eq!(deq.len(), 1);
deq.add_front(b);
deq.add_front(copy b);
assert_eq!(deq.len(), 2);
deq.add_back(d);
deq.add_back(copy d);
assert_eq!(deq.len(), 3);
deq.add_front(a);
deq.add_front(copy a);
assert_eq!(deq.len(), 4);
assert_eq!(*deq.get(0), a);
assert_eq!(*deq.get(1), b);
assert_eq!(*deq.get(2), c);
assert_eq!(*deq.get(3), d);
assert_eq!(copy *deq.get(0), copy a);
assert_eq!(copy *deq.get(1), copy b);
assert_eq!(copy *deq.get(2), copy c);
assert_eq!(copy *deq.get(3), copy d);
}

#[deriving(Eq)]
Expand Down
17 changes: 9 additions & 8 deletions src/libextra/dlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ pub fn from_elem<T>(data: T) -> @mut DList<T> {
/// Creates a new dlist from a vector of elements, maintaining the same order
pub fn from_vec<T:Copy>(vec: &[T]) -> @mut DList<T> {
do vec.iter().fold(DList()) |list,data| {
list.push(*data); // Iterating left-to-right -- add newly to the tail.
// Iterating left-to-right -- add newly to the tail.
list.push(copy *data);
list
}
}
Expand Down Expand Up @@ -460,35 +461,35 @@ impl<T> DList<T> {
impl<T:Copy> DList<T> {
/// Remove data from the head of the list. O(1).
pub fn pop(@mut self) -> Option<T> {
self.pop_n().map(|nobe| nobe.data)
self.pop_n().map(|nobe| copy nobe.data)
}

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

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

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

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

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

/// Get the elements of the list as a vector. O(n).
pub fn to_vec(@mut self) -> ~[T] {
let mut v = vec::with_capacity(self.size);
for old_iter::eachi(&self) |index,data| {
v[index] = *data;
v[index] = copy *data;
}
v
}
Expand Down
2 changes: 1 addition & 1 deletion src/libextra/future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ priv enum FutureState<A> {
impl<A:Copy> Future<A> {
pub fn get(&mut self) -> A {
//! Get the value of the future.
*(self.get_ref())
copy *(self.get_ref())
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/libextra/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub enum MutList<T> {

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

/**
Expand Down Expand Up @@ -61,7 +61,7 @@ pub fn find<T:Copy>(ls: @List<T>, f: &fn(&T) -> bool) -> Option<T> {
loop {
ls = match *ls {
Cons(ref hd, tl) => {
if f(hd) { return Some(*hd); }
if f(hd) { return Some(copy *hd); }
tl
}
Nil => return None
Expand Down
2 changes: 1 addition & 1 deletion src/libextra/smallintmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ impl<V:Copy> SmallIntMap<V> {
ff: &fn(uint, V, V) -> V) -> bool {
let new_val = match self.find(&key) {
None => val,
Some(orig) => ff(key, *orig, val)
Some(orig) => ff(key, copy *orig, val)
};
self.insert(key, new_val)
}
Expand Down
18 changes: 9 additions & 9 deletions src/libextra/sort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub fn merge_sort<T:Copy>(v: &[T], le: Le<T>) -> ~[T] {

let v_len = end - begin;
if v_len == 0 { return ~[]; }
if v_len == 1 { return ~[v[begin]]; }
if v_len == 1 { return ~[copy v[begin]]; }

let mid = v_len / 2 + begin;
let a = (begin, mid);
Expand All @@ -53,9 +53,9 @@ pub fn merge_sort<T:Copy>(v: &[T], le: Le<T>) -> ~[T] {
let mut b_ix = 0;
while a_ix < a_len && b_ix < b_len {
if le(&a[a_ix], &b[b_ix]) {
rs.push(a[a_ix]);
rs.push(copy a[a_ix]);
a_ix += 1;
} else { rs.push(b[b_ix]); b_ix += 1; }
} else { rs.push(copy b[b_ix]); b_ix += 1; }
}
rs.push_all(vec::slice(a, a_ix, a_len));
rs.push_all(vec::slice(b, b_ix, b_len));
Expand Down Expand Up @@ -106,7 +106,7 @@ pub fn quick_sort<T>(arr: &mut [T], compare_func: Le<T>) {

fn qsort3<T:Copy + Ord + Eq>(arr: &mut [T], left: int, right: int) {
if right <= left { return; }
let v: T = arr[right];
let v: T = copy arr[right];
let mut i: int = left - 1;
let mut j: int = right;
let mut p: int = i;
Expand Down Expand Up @@ -233,7 +233,7 @@ fn binarysort<T:Copy + Ord>(array: &mut [T], start: uint) {
if start == 0 { start += 1; }

while start < size {
let pivot = array[start];
let pivot = copy array[start];
let mut left = 0;
let mut right = start;
assert!(left <= right);
Expand Down Expand Up @@ -470,7 +470,7 @@ impl<T:Copy + Ord> MergeState<T> {

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

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

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

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

for from.eachi |i, v| {
dest[s1+i] = *v;
dest[s1+i] = copy *v;
}
}

Expand Down Expand Up @@ -1045,7 +1045,7 @@ mod big_tests {
fn multiplyVec<T:Copy>(arr: &[T], num: uint) -> ~[T] {
let size = arr.len();
let res = do vec::from_fn(num) |i| {
arr[i % size]
copy arr[i % size]
};
res
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1184,7 +1184,7 @@ fn create_index<T:Copy + Hash + IterBytes>(index: ~[entry<T>]) ->
for uint::range(0u, 256u) |_i| { buckets.push(@mut ~[]); };
for index.each |elt| {
let h = elt.val.hash() as uint;
buckets[h % 256].push(*elt);
buckets[h % 256].push(copy *elt);
}

let mut buckets_frozen = ~[];
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/borrowck/gather_loans/gather_moves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ fn check_is_legal_to_move_from(bccx: @BorrowckCtxt,
mc::cat_implicit_self(*) |
mc::cat_copied_upvar(*) |
mc::cat_deref(_, _, mc::region_ptr(*)) |
mc::cat_deref(_, _, mc::gc_ptr(*)) => {
mc::cat_deref(_, _, mc::gc_ptr(*)) |
mc::cat_deref(_, _, mc::unsafe_ptr(*)) => {
bccx.span_err(
cmt0.span,
fmt!("cannot move out of %s",
Expand All @@ -129,8 +130,7 @@ fn check_is_legal_to_move_from(bccx: @BorrowckCtxt,
mc::cat_rvalue(*) |
mc::cat_local(*) |
mc::cat_arg(*) |
mc::cat_self(*) |
mc::cat_deref(_, _, mc::unsafe_ptr(*)) => {
mc::cat_self(*) => {
true
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/trans/debuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ fn cached_metadata<T:Copy>(cache: metadata_cache,
let items = cache.get(&mdtag);
for items.each |item| {
let md: T = md_from_metadata::<T>(*item);
if eq_fn(md) {
return option::Some(md);
if eq_fn(copy md) {
return option::Some(copy md);
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2273,7 +2273,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
for type_param_def.bounds.builtin_bounds.each |bound| {
debug!("tc = %s, bound = %?", tc.to_str(), bound);
tc = tc - match bound {
BoundCopy => TypeContents::nonimplicitly_copyable(cx),
BoundCopy => TypeContents::noncopyable(cx),
BoundStatic => TypeContents::nonstatic(cx),
BoundOwned => TypeContents::nonowned(cx),
BoundConst => TypeContents::nonconst(cx),
Expand Down Expand Up @@ -3694,16 +3694,16 @@ fn lookup_locally_or_in_crate_store<V:Copy>(
*/

match map.find(&def_id) {
Some(&v) => { return v; }
Some(&ref v) => { return copy *v; }
None => { }
}

if def_id.crate == ast::local_crate {
fail!("No def'n found for %? in tcx.%s", def_id, descr);
}
let v = load_external();
map.insert(def_id, v);
return v;
map.insert(def_id, copy v);
return copy v;
}

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