Skip to content
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

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

Closed
pcwalton opened this issue Jun 16, 2012 · 8 comments
Closed

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

pcwalton opened this issue Jun 16, 2012 · 8 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one.

Comments

@pcwalton
Copy link
Contributor

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
@bblum
Copy link
Contributor

bblum commented Aug 25, 2012

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.

@nikomatsakis
Copy link
Contributor

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

@thestinger
Copy link
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.

@pnkfelix
Copy link
Member

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.

@pnkfelix
Copy link
Member

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).

@alexcrichton
Copy link
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

@nikomatsakis
Copy link
Contributor

Partial dup of #12201

@steveklabnik
Copy link
Member

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

RalfJung pushed a commit to RalfJung/rust that referenced this issue Nov 6, 2022
./miri updates: toolchain, rustc-push, rustc-pull

This merges the `./rustup-toolchain` script into `./miri` as `./miri toolchain`, and adds two new commands for josh-based syncing.

r? `@rust-lang/miri`
Aaron1011 pushed a commit to Aaron1011/rust that referenced this issue Jan 6, 2023
./miri updates: toolchain, rustc-push, rustc-pull

This merges the `./rustup-toolchain` script into `./miri` as `./miri toolchain`, and adds two new commands for josh-based syncing.

r? `@rust-lang/miri`
celinval pushed a commit to celinval/rust-dev that referenced this issue Jun 4, 2024
Deprecate kani::slice::any_slice in Kani 0.38.0 (and the related AnySlice struct), and remove it in a later version.

Motivation: The Kani library's `slice::any_slice` API is doing more harm than benefit: it is meant to provide a convenient way for users to generate non-deterministic slices, but its current implementation aims to avoid any unsoundness by making sure that for the non-deterministic slice returned by the API, accessing memory beyond the slice length is flagged as an out-of-bounds access (see rust-lang#1009 for details). However, in practical scenarios, using it ends up causing memory to blowup for CBMC. Given that users may not care about this type of unsoundness, which is only possible through using a pointer dereference inside an unsafe block (see discussion in rust-lang#2634). Thus, we should leave it to the user to decide the suitable method for generating slices that fits their verification needs. For example, they can use Kani's alternative API, `any_slice_of_array` that extracts a slice of a non-deterministic start and end from a given array.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one.
Projects
None yet
Development

No branches or pull requests

7 participants