Only suggest implementing Copy if it can actually be done

This commit is contained in:
Oliver Schneider 2018-01-18 14:27:47 +01:00
parent 552e950080
commit 8217e33718
No known key found for this signature in database
GPG key ID: A69F8D225B3AD7D9
3 changed files with 82 additions and 27 deletions

View file

@ -205,8 +205,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
let sugg = |db: &mut DiagnosticBuilder| {
if let ty::TypeVariants::TyAdt(ref def, ..) = ty.sty {
if let Some(span) = cx.tcx.hir.span_if_local(def.did) {
// FIXME (#2374) Restrict this to types which can impl Copy
db.span_help(span, "consider marking this type as Copy if possible");
let param_env = ty::ParamEnv::empty(traits::Reveal::UserFacing);
if param_env.can_type_implement_copy(cx.tcx, ty, span).is_ok() {
db.span_help(span, "consider marking this type as Copy");
}
}
}

View file

@ -120,4 +120,21 @@ fn range<T: ::std::collections::range::RangeArgument<usize>>(range: T) {
let _ = range.start();
}
struct CopyWrapper(u32);
fn bar_copy(x: u32, y: CopyWrapper) {
assert_eq!(x, 42);
assert_eq!(y.0, 42);
}
// x and y should be warned, but z is ok
fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
let CopyWrapper(s) = z; // moved
let CopyWrapper(ref t) = y; // not moved
let CopyWrapper(_) = y; // still not moved
assert_eq!(x.0, s);
println!("{}", t);
}
fn main() {}

View file

@ -17,12 +17,6 @@ error: this argument is passed by value, but not consumed in the function body
|
28 | fn bar(x: String, y: Wrapper) {
| ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
|
help: consider marking this type as Copy if possible
--> $DIR/needless_pass_by_value.rs:26:1
|
26 | struct Wrapper(String);
| ^^^^^^^^^^^^^^^^^^^^^^^
error: this argument is passed by value, but not consumed in the function body
--> $DIR/needless_pass_by_value.rs:34:71
@ -46,24 +40,12 @@ error: this argument is passed by value, but not consumed in the function body
|
59 | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
| ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
|
help: consider marking this type as Copy if possible
--> $DIR/needless_pass_by_value.rs:26:1
|
26 | struct Wrapper(String);
| ^^^^^^^^^^^^^^^^^^^^^^^
error: this argument is passed by value, but not consumed in the function body
--> $DIR/needless_pass_by_value.rs:59:36
|
59 | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
| ^^^^^^^
|
help: consider marking this type as Copy if possible
--> $DIR/needless_pass_by_value.rs:26:1
|
26 | struct Wrapper(String);
| ^^^^^^^^^^^^^^^^^^^^^^^
help: consider taking a reference instead
|
59 | fn test_destructure(x: Wrapper, y: &Wrapper, z: Wrapper) {
@ -141,12 +123,66 @@ error: this argument is passed by value, but not consumed in the function body
|
103 | _s: Self,
| ^^^^ help: consider taking a reference instead: `&Self`
|
help: consider marking this type as Copy if possible
--> $DIR/needless_pass_by_value.rs:84:1
|
84 | struct S<T, U>(T, U);
| ^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 16 previous errors
error: this argument is passed by value, but not consumed in the function body
--> $DIR/needless_pass_by_value.rs:125:24
|
125 | fn bar_copy(x: u32, y: CopyWrapper) {
| ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
|
help: consider marking this type as Copy
--> $DIR/needless_pass_by_value.rs:123:1
|
123 | struct CopyWrapper(u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: this argument is passed by value, but not consumed in the function body
--> $DIR/needless_pass_by_value.rs:131:29
|
131 | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
| ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
|
help: consider marking this type as Copy
--> $DIR/needless_pass_by_value.rs:123:1
|
123 | struct CopyWrapper(u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: this argument is passed by value, but not consumed in the function body
--> $DIR/needless_pass_by_value.rs:131:45
|
131 | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
| ^^^^^^^^^^^
|
help: consider marking this type as Copy
--> $DIR/needless_pass_by_value.rs:123:1
|
123 | struct CopyWrapper(u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^
help: consider taking a reference instead
|
131 | fn test_destructure_copy(x: CopyWrapper, y: &CopyWrapper, z: CopyWrapper) {
132 | let CopyWrapper(s) = z; // moved
133 | let CopyWrapper(ref t) = *y; // not moved
134 | let CopyWrapper(_) = *y; // still not moved
|
error: this argument is passed by value, but not consumed in the function body
--> $DIR/needless_pass_by_value.rs:131:61
|
131 | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
| ^^^^^^^^^^^
|
help: consider marking this type as Copy
--> $DIR/needless_pass_by_value.rs:123:1
|
123 | struct CopyWrapper(u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^
help: consider taking a reference instead
|
131 | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: &CopyWrapper) {
132 | let CopyWrapper(s) = *z; // moved
|
error: aborting due to 20 previous errors