Skip to content

Commit 5859dc1

Browse files
committed
librustc: Make Copy opt-in.
This change makes the compiler no longer infer whether types (structures and enumerations) implement the `Copy` trait (and thus are implicitly copyable). Rather, you must implement `Copy` yourself via `impl Copy for MyType {}`. A new warning has been added, `missing_copy_implementations`, to warn you if a non-generic public type has been added that could have implemented `Copy` but didn't. This breaks code like: #[deriving(Show)] struct Point2D { x: int, y: int, } fn main() { let mypoint = Point2D { x: 1, y: 1, }; let otherpoint = mypoint; println!("{}{}", mypoint, otherpoint); } Change this code to: #[deriving(Show)] struct Point2D { x: int, y: int, } impl Copy for Point2D {} fn main() { let mypoint = Point2D { x: 1, y: 1, }; let otherpoint = mypoint; println!("{}{}", mypoint, otherpoint); } This is the backwards-incompatible part of #13231. Part of RFC #3. [breaking-change]
1 parent 361baab commit 5859dc1

File tree

278 files changed

+2122
-404
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

278 files changed

+2122
-404
lines changed

src/compiletest/common.rs

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ pub enum Mode {
2525
Codegen
2626
}
2727

28+
impl Copy for Mode {}
29+
2830
impl FromStr for Mode {
2931
fn from_str(s: &str) -> Option<Mode> {
3032
match s {

src/doc/guide-unsafe.md

+3
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,9 @@ extern {
661661
fn abort() -> !;
662662
}
663663
664+
#[lang = "owned_box"]
665+
pub struct Box<T>(*mut T);
666+
664667
#[lang="exchange_malloc"]
665668
unsafe fn allocate(size: uint, _align: uint) -> *mut u8 {
666669
let p = libc::malloc(size as libc::size_t) as *mut u8;

src/doc/reference.md

+4
Original file line numberDiff line numberDiff line change
@@ -1660,6 +1660,7 @@ Implementations are defined with the keyword `impl`.
16601660

16611661
```
16621662
# struct Point {x: f64, y: f64};
1663+
# impl Copy for Point {}
16631664
# type Surface = int;
16641665
# struct BoundingBox {x: f64, y: f64, width: f64, height: f64};
16651666
# trait Shape { fn draw(&self, Surface); fn bounding_box(&self) -> BoundingBox; }
@@ -1669,6 +1670,8 @@ struct Circle {
16691670
center: Point,
16701671
}
16711672
1673+
impl Copy for Circle {}
1674+
16721675
impl Shape for Circle {
16731676
fn draw(&self, s: Surface) { do_draw_circle(s, *self); }
16741677
fn bounding_box(&self) -> BoundingBox {
@@ -1791,6 +1794,7 @@ default visibility with the `priv` keyword. When an item is declared as `pub`,
17911794
it can be thought of as being accessible to the outside world. For example:
17921795

17931796
```
1797+
# #![allow(missing_copy_implementations)]
17941798
# fn main() {}
17951799
// Declare a private struct
17961800
struct Foo;

src/libarena/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ impl<T> TypedArena<T> {
466466
}
467467

468468
let ptr: &mut T = unsafe {
469-
let ptr: &mut T = mem::transmute(self.ptr);
469+
let ptr: &mut T = mem::transmute(self.ptr.clone());
470470
ptr::write(ptr, object);
471471
self.ptr.set(self.ptr.get().offset(1));
472472
ptr

src/libcollections/binary_heap.rs

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
//! position: uint
3636
//! }
3737
//!
38+
//! impl Copy for State {}
39+
//!
3840
//! // The priority queue depends on `Ord`.
3941
//! // Explicitly implement the trait so the queue becomes a min-heap
4042
//! // instead of a max-heap.

src/libcollections/dlist.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,12 @@ pub struct DList<T> {
3939
}
4040

4141
type Link<T> = Option<Box<Node<T>>>;
42-
struct Rawlink<T> { p: *mut T }
42+
43+
struct Rawlink<T> {
44+
p: *mut T,
45+
}
46+
47+
impl<T> Copy for Rawlink<T> {}
4348

4449
struct Node<T> {
4550
next: Link<T>,
@@ -59,6 +64,8 @@ impl<'a, T> Clone for Items<'a, T> {
5964
fn clone(&self) -> Items<'a, T> { *self }
6065
}
6166

67+
impl<'a,T> Copy for Items<'a,T> {}
68+
6269
/// An iterator over mutable references to the items of a `DList`.
6370
pub struct MutItems<'a, T:'a> {
6471
list: &'a mut DList<T>,

src/libcollections/enum_set.rs

+7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ pub struct EnumSet<E> {
2727
bits: uint
2828
}
2929

30+
impl<E> Copy for EnumSet<E> {}
31+
3032
impl<E:CLike+fmt::Show> fmt::Show for EnumSet<E> {
3133
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
3234
try!(write!(fmt, "{{"));
@@ -269,6 +271,8 @@ mod test {
269271
A, B, C
270272
}
271273

274+
impl Copy for Foo {}
275+
272276
impl CLike for Foo {
273277
fn to_uint(&self) -> uint {
274278
*self as uint
@@ -477,6 +481,9 @@ mod test {
477481
V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
478482
V60, V61, V62, V63, V64, V65, V66, V67, V68, V69,
479483
}
484+
485+
impl Copy for Bar {}
486+
480487
impl CLike for Bar {
481488
fn to_uint(&self) -> uint {
482489
*self as uint

src/libcollections/hash/sip.rs

+3
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ pub struct SipState {
4343
ntail: uint, // how many bytes in tail are valid
4444
}
4545

46+
impl Copy for SipState {}
47+
4648
// sadly, these macro definitions can't appear later,
4749
// because they're needed in the following defs;
4850
// this design could be improved.
@@ -211,6 +213,7 @@ impl Default for SipState {
211213

212214
/// `SipHasher` computes the SipHash algorithm from a stream of bytes.
213215
#[deriving(Clone)]
216+
#[allow(missing_copy_implementations)]
214217
pub struct SipHasher {
215218
k0: u64,
216219
k1: u64,

src/libcollections/slice.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ use self::Direction::*;
9191
use alloc::boxed::Box;
9292
use core::borrow::{BorrowFrom, BorrowFromMut, ToOwned};
9393
use core::cmp;
94-
use core::kinds::Sized;
94+
use core::kinds::{Copy, Sized};
9595
use core::mem::size_of;
9696
use core::mem;
9797
use core::prelude::{Clone, Greater, Iterator, IteratorExt, Less, None, Option};
@@ -177,12 +177,16 @@ impl ElementSwaps {
177177

178178
enum Direction { Pos, Neg }
179179

180+
impl Copy for Direction {}
181+
180182
/// An `Index` and `Direction` together.
181183
struct SizeDirection {
182184
size: uint,
183185
dir: Direction,
184186
}
185187

188+
impl Copy for SizeDirection {}
189+
186190
impl Iterator<(uint, uint)> for ElementSwaps {
187191
#[inline]
188192
fn next(&mut self) -> Option<(uint, uint)> {
@@ -1482,11 +1486,17 @@ mod tests {
14821486
fn clone(&self) -> S {
14831487
self.f.set(self.f.get() + 1);
14841488
if self.f.get() == 10 { panic!() }
1485-
S { f: self.f, boxes: self.boxes.clone() }
1489+
S {
1490+
f: self.f.clone(),
1491+
boxes: self.boxes.clone(),
1492+
}
14861493
}
14871494
}
14881495

1489-
let s = S { f: Cell::new(0), boxes: (box 0, Rc::new(0)) };
1496+
let s = S {
1497+
f: Cell::new(0),
1498+
boxes: (box 0, Rc::new(0)),
1499+
};
14901500
let _ = Vec::from_elem(100, s);
14911501
}
14921502

src/libcollections/str.rs

+21-13
Original file line numberDiff line numberDiff line change
@@ -228,24 +228,32 @@ impl<'a> Iterator<char> for Decompositions<'a> {
228228
_ => self.sorted = false
229229
}
230230

231-
let decomposer = match self.kind {
232-
Canonical => unicode::char::decompose_canonical,
233-
Compatible => unicode::char::decompose_compatible
234-
};
235-
236231
if !self.sorted {
237232
for ch in self.iter {
238233
let buffer = &mut self.buffer;
239234
let sorted = &mut self.sorted;
240-
decomposer(ch, |d| {
241-
let class = unicode::char::canonical_combining_class(d);
242-
if class == 0 && !*sorted {
243-
canonical_sort(buffer.as_mut_slice());
244-
*sorted = true;
235+
{
236+
let callback = |d| {
237+
let class =
238+
unicode::char::canonical_combining_class(d);
239+
if class == 0 && !*sorted {
240+
canonical_sort(buffer.as_mut_slice());
241+
*sorted = true;
242+
}
243+
buffer.push((d, class));
244+
};
245+
match self.kind {
246+
Canonical => {
247+
unicode::char::decompose_canonical(ch, callback)
248+
}
249+
Compatible => {
250+
unicode::char::decompose_compatible(ch, callback)
251+
}
245252
}
246-
buffer.push((d, class));
247-
});
248-
if *sorted { break }
253+
}
254+
if *sorted {
255+
break
256+
}
249257
}
250258
}
251259

src/libcore/atomic.rs

+3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub use self::Ordering::*;
1717
use intrinsics;
1818
use std::kinds::marker;
1919
use cell::UnsafeCell;
20+
use kinds::Copy;
2021

2122
/// A boolean type which can be safely shared between threads.
2223
#[stable]
@@ -81,6 +82,8 @@ pub enum Ordering {
8182
SeqCst,
8283
}
8384

85+
impl Copy for Ordering {}
86+
8487
/// An `AtomicBool` initialized to `false`.
8588
#[unstable = "may be renamed, pending conventions for static initalizers"]
8689
pub const INIT_ATOMIC_BOOL: AtomicBool =

src/libcore/char.rs

+1
Original file line numberDiff line numberDiff line change
@@ -518,3 +518,4 @@ impl Iterator<char> for DefaultEscapedChars {
518518
}
519519
}
520520
}
521+

src/libcore/cmp.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343

4444
pub use self::Ordering::*;
4545

46-
use kinds::Sized;
46+
use kinds::{Copy, Sized};
4747
use option::{Option, Some, None};
4848

4949
/// Trait for values that can be compared for equality and inequality.
@@ -105,6 +105,8 @@ pub enum Ordering {
105105
Greater = 1i,
106106
}
107107

108+
impl Copy for Ordering {}
109+
108110
impl Ordering {
109111
/// Reverse the `Ordering`, so that `Less` becomes `Greater` and
110112
/// vice versa.

src/libcore/fmt/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ pub type Result = result::Result<(), Error>;
4444
#[experimental = "core and I/O reconciliation may alter this definition"]
4545
pub struct Error;
4646

47+
impl Copy for Error {}
48+
4749
/// A collection of methods that are required to format a message into a stream.
4850
///
4951
/// This trait is the type which this modules requires when formatting
@@ -102,6 +104,8 @@ pub struct Argument<'a> {
102104
value: &'a Void,
103105
}
104106

107+
impl<'a> Copy for Argument<'a> {}
108+
105109
impl<'a> Arguments<'a> {
106110
/// When using the format_args!() macro, this function is used to generate the
107111
/// Arguments structure. The compiler inserts an `unsafe` block to call this,

src/libcore/fmt/num.rs

+5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
use fmt;
1818
use iter::DoubleEndedIteratorExt;
19+
use kinds::Copy;
1920
use num::{Int, cast};
2021
use slice::SlicePrelude;
2122

@@ -114,6 +115,8 @@ pub struct Radix {
114115
base: u8,
115116
}
116117

118+
impl Copy for Radix {}
119+
117120
impl Radix {
118121
fn new(base: u8) -> Radix {
119122
assert!(2 <= base && base <= 36, "the base must be in the range of 2..36: {}", base);
@@ -136,6 +139,8 @@ impl GenericRadix for Radix {
136139
#[unstable = "may be renamed or move to a different module"]
137140
pub struct RadixFmt<T, R>(T, R);
138141

142+
impl<T,R> Copy for RadixFmt<T,R> where T: Copy, R: Copy {}
143+
139144
/// Constructs a radix formatter in the range of `2..36`.
140145
///
141146
/// # Example

src/libcore/fmt/rt.rs

+13
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@ pub use self::Alignment::*;
2020
pub use self::Count::*;
2121
pub use self::Position::*;
2222
pub use self::Flag::*;
23+
use kinds::Copy;
2324

2425
#[doc(hidden)]
2526
pub struct Argument<'a> {
2627
pub position: Position,
2728
pub format: FormatSpec,
2829
}
2930

31+
impl<'a> Copy for Argument<'a> {}
32+
3033
#[doc(hidden)]
3134
pub struct FormatSpec {
3235
pub fill: char,
@@ -36,6 +39,8 @@ pub struct FormatSpec {
3639
pub width: Count,
3740
}
3841

42+
impl Copy for FormatSpec {}
43+
3944
/// Possible alignments that can be requested as part of a formatting directive.
4045
#[deriving(PartialEq)]
4146
pub enum Alignment {
@@ -49,16 +54,22 @@ pub enum Alignment {
4954
AlignUnknown,
5055
}
5156

57+
impl Copy for Alignment {}
58+
5259
#[doc(hidden)]
5360
pub enum Count {
5461
CountIs(uint), CountIsParam(uint), CountIsNextParam, CountImplied,
5562
}
5663

64+
impl Copy for Count {}
65+
5766
#[doc(hidden)]
5867
pub enum Position {
5968
ArgumentNext, ArgumentIs(uint)
6069
}
6170

71+
impl Copy for Position {}
72+
6273
/// Flags which can be passed to formatting via a directive.
6374
///
6475
/// These flags are discovered through the `flags` field of the `Formatter`
@@ -78,3 +89,5 @@ pub enum Flag {
7889
/// being aware of the sign to be printed.
7990
FlagSignAwareZeroPad,
8091
}
92+
93+
impl Copy for Flag {}

src/libcore/intrinsics.rs

+6
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
#![experimental]
4343
#![allow(missing_docs)]
4444

45+
use kinds::Copy;
46+
4547
pub type GlueFn = extern "Rust" fn(*const i8);
4648

4749
#[lang="ty_desc"]
@@ -59,6 +61,8 @@ pub struct TyDesc {
5961
pub name: &'static str,
6062
}
6163

64+
impl Copy for TyDesc {}
65+
6266
extern "rust-intrinsic" {
6367

6468
// NB: These intrinsics take unsafe pointers because they mutate aliased
@@ -539,6 +543,8 @@ pub struct TypeId {
539543
t: u64,
540544
}
541545

546+
impl Copy for TypeId {}
547+
542548
impl TypeId {
543549
/// Returns the `TypeId` of the type this generic function has been instantiated with
544550
pub fn of<T: 'static>() -> TypeId {

0 commit comments

Comments
 (0)