Closed
Description
Updated Bug Report
We do not provide enough user feedback explaining why a type is non-copyable. The error messages just say "error: copying a value of non-copyable type Type
"
Things have gotten a bit better since this bug was filed, in part because our story has changed somewhat (we no longer implicitly copy vectors/strings; we no longer have @fn
), but we still do not have great user feedback, particularly with respect to explaining how a type ended up being put into the "non-copyable" bucket.
Sample Code Enumerating Non-copyable Cases
// Issue 2634
// Better explanations for why non-implicitly copyable things are that way.
use NC = std::util::NonCopyable;
use NonCopyExamples::*;
mod NonCopyExamples {
use NC = std::util::NonCopyable;
enum Void {}
pub struct S { a: int, nc: NC }
pub struct T { a: int, own: ~int }
pub struct U<'self> { a: int, mu: &'self mut int }
pub struct V { a: int }
impl Drop for V { fn drop(&mut self) { } }
pub struct W<'self> { a: int, fun: &'self fn () }
pub struct X { a: int, oyvey: Option<Void> } // (strcat: maybe bug)
}
static mut global_u : int = 3;
fn fun() { println("Hello World"); }
fn construct() -> (S,T,U,V,W,X) {
let s = S{ a: 1, nc: NC };
let t = T{ a: 2, own: ~2 };
let u = unsafe { U{ a: 3, mu: &mut global_u } };
let v = V{ a: 4 };
let w = W{ a: 5, fun: fun };
let x = X{ a: 6, oyvey: None };
(s,t,u,v,w,x)
}
fn g<A>(a: A) { println!("{:?}", a); }
#[cfg(not(no_funcall_twice))]
fn funcall_twice() {
use NonCopyExamples::*;
let (s,t,u,v,w,x) = construct();
g(s); g(s);
g(t); g(t);
g(u); g(u);
g(v); g(v);
g(w); g(w);
g(x); g(x);
}
#[cfg(no_funcall_twice)] fn funcall_twice() { }
#[cfg(not(no_assign))]
fn assign() {
use NonCopyExamples::*;
let (s,t,u,v,w,x) = construct();
let s_1 = s; let s_2 = s;
let t_1 = t; let t_2 = t;
let u_1 = u; let u_2 = u;
let v_1 = v; let v_2 = v;
let w_1 = w; let w_2 = w;
let x_1 = x; let x_2 = x;
}
#[cfg(no_assign)] fn assign() { }
#[cfg(not(no_repeat))]
fn repeat() {
use NonCopyExamples::*;
let (s,t,u,v,w,x) = construct();
let ss = [s, ..2];
let tt = [t, ..2];
let uu = [u, ..2];
let vv = [v, ..2];
let ww = [w, ..2];
let xx = [x, ..2];
}
#[cfg(no_repeat)] fn repeat() { }
fn main() {
funcall_twice();
assign();
repeat();
}
Original Bug Report follows
I think the error messages would be clearer if they were along these lines:
foo.rs:10: warning: copying a value of type '~str' requires memory allocation
foo.rs:10: note: suggest use of 'move' to avoid this copy
foo.rs:20: warning: copying a value of type `BlockContext` duplicates mutable fields
foo.rs:20: note: use 'copy' if the copy is desired
foo.rs:30: warning: call to 'f' might copy values of type '~str', incurring memory allocation
foo.rs:30: note: see 'copy' interface bound here
foo.rs:40: warning: call to 'g' might copy values of type '~BlockContext', incurring memory allocation and duplicating mutable fields
foo.rs:40: note: see 'copy' interface bound here