Skip to content

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

Closed

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

Activity

  1. bblum commented on Aug 25, 2012

    @bblum
    Contributor

    I partially did this to solve #2942. Now reporting these things is as simple as writing some(("noncopyable reason","copyable reason")) when calling check_copy and friends in kind.rs.

  2. nikomatsakis commented on May 13, 2013

    @nikomatsakis
    Contributor

    Error messages could still stand to be improved as of right now.

  3. thestinger commented on Jul 6, 2013

    @thestinger
    Contributor

    This is still relevant because there are at least two reasons for types moving instead of copying, a destructor or &mut T. Some types of closures are non-copyable too.

  4. pnkfelix commented on Sep 26, 2013

    @pnkfelix
    Contributor

    Bug triage, email from 2013 sep 16.

    As prep work for this bug, I attempted to write a program demonstrating the cross-product of:

    1. what makes a type non-copyable, and
    2. what expressions force a value to be copied (and thus cause these error messages to arise from rustc).

    I've added what I've accumulated so far to the bug description.

  5. pnkfelix commented on Sep 26, 2013

    @pnkfelix
    Contributor

    see also #9098 as a semi-related issue (at least, if our mental with respect to implicit copy-ability changes, then these error messages will probably change accordingly).

  6. alexcrichton commented on Mar 10, 2014

    @alexcrichton
    Member

    We will likely start requiring an opt-in to builtin bounds (see http://smallcultfollowing.com/babysteps/blog/2014/02/28/rust-rfc-opt-in-builtin-traits/), in which case this issue may become moot

  7. nikomatsakis commented on Mar 10, 2014

    @nikomatsakis
    Contributor

    Partial dup of #12201

  8. steveklabnik commented on Jan 16, 2015

    @steveklabnik
    Contributor

    Copy is now opt in, so as @alexcrichton says, this is moot.

  9. added a commit that references this issue on Nov 6, 2022
  10. added a commit that references this issue on Jan 6, 2023
  11. added a commit that references this issue on Jun 4, 2024
  12. added a commit that references this issue on Nov 10, 2025
  13. added a commit that references this issue on Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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