-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #31414 - durka:clone-copy, r=alexcrichton
special-case #[derive(Copy, Clone)] with a shallow clone If a type is Copy then its Clone implementation can be a no-op. Currently `#[derive(Clone)]` generates a deep clone anyway. This can lead to lots of code bloat. This PR detects the case where Copy and Clone are both being derived (the general case of "is this type Copy" can't be determined by a syntax extension) and generates the shallow Clone impl. Right now this can only be done if there are no type parameters (see #31085 (comment)), but this restriction can be removed after specialization. Fixes #31085.
- Loading branch information
Showing
11 changed files
with
203 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// this will get a no-op Clone impl | ||
#[derive(Copy, Clone)] | ||
struct A { | ||
a: i32, | ||
b: i64 | ||
} | ||
|
||
// this will get a deep Clone impl | ||
#[derive(Copy, Clone)] | ||
struct B<T> { | ||
a: i32, | ||
b: T | ||
} | ||
|
||
struct C; // not Copy or Clone | ||
#[derive(Clone)] struct D; // Clone but not Copy | ||
|
||
fn is_copy<T: Copy>(_: T) {} | ||
fn is_clone<T: Clone>(_: T) {} | ||
|
||
fn main() { | ||
// A can be copied and cloned | ||
is_copy(A { a: 1, b: 2 }); | ||
is_clone(A { a: 1, b: 2 }); | ||
|
||
// B<i32> can be copied and cloned | ||
is_copy(B { a: 1, b: 2 }); | ||
is_clone(B { a: 1, b: 2 }); | ||
|
||
// B<C> cannot be copied or cloned | ||
is_copy(B { a: 1, b: C }); //~ERROR Copy | ||
is_clone(B { a: 1, b: C }); //~ERROR Clone | ||
|
||
// B<D> can be cloned but not copied | ||
is_copy(B { a: 1, b: D }); //~ERROR Copy | ||
is_clone(B { a: 1, b: D }); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
//! Test that #[derive(Copy, Clone)] produces a shallow copy | ||
//! even when a member violates RFC 1521 | ||
|
||
use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering}; | ||
|
||
/// A struct that pretends to be Copy, but actually does something | ||
/// in its Clone impl | ||
#[derive(Copy)] | ||
struct Liar; | ||
|
||
/// Static cooperating with the rogue Clone impl | ||
static CLONED: AtomicBool = ATOMIC_BOOL_INIT; | ||
|
||
impl Clone for Liar { | ||
fn clone(&self) -> Self { | ||
// this makes Clone vs Copy observable | ||
CLONED.store(true, Ordering::SeqCst); | ||
|
||
*self | ||
} | ||
} | ||
|
||
/// This struct is actually Copy... at least, it thinks it is! | ||
#[derive(Copy, Clone)] | ||
struct Innocent(Liar); | ||
|
||
impl Innocent { | ||
fn new() -> Self { | ||
Innocent(Liar) | ||
} | ||
} | ||
|
||
fn main() { | ||
let _ = Innocent::new().clone(); | ||
// if Innocent was byte-for-byte copied, CLONED will still be false | ||
assert!(!CLONED.load(Ordering::SeqCst)); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters