Skip to content

Say why non-implicitly-copyable things are that way #2634

Closed
@pcwalton

Description

@pcwalton

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions