Skip to content

Commit 096a286

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. For convenience, you may *temporarily* opt out of this behavior by using `#![feature(opt_out_copy)]`. Note though that this feature gate will never be accepted and will be removed by the time that 1.0 is released, so you should transition your code away from using it. 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 rust-lang#13231. Part of RFC rust-lang#3. [breaking-change]
1 parent c7a9b49 commit 096a286

File tree

277 files changed

+2182
-513
lines changed

Some content is hidden

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

277 files changed

+2182
-513
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
@@ -519,3 +519,4 @@ impl Iterator<char> for DefaultEscapedChars {
519519
}
520520
}
521521
}
522+

src/libcore/cmp.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@
4343

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

46-
use kinds::Sized;
47-
use option::Option;
48-
use option::Option::{Some, None};
46+
use kinds::{Copy, Sized};
47+
use option::{Option, Some, None};
4948

5049
/// Trait for values that can be compared for equality and inequality.
5150
///
@@ -106,6 +105,8 @@ pub enum Ordering {
106105
Greater = 1i,
107106
}
108107

108+
impl Copy for Ordering {}
109+
109110
impl Ordering {
110111
/// Reverse the `Ordering`, so that `Less` becomes `Greater` and
111112
/// vice versa.

src/libcore/fmt/mod.rs

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

49+
impl Copy for Error {}
50+
4951
/// A collection of methods that are required to format a message into a stream.
5052
///
5153
/// This trait is the type which this modules requires when formatting
@@ -135,6 +137,8 @@ impl<'a> Argument<'a> {
135137
}
136138
}
137139

140+
impl<'a> Copy for Argument<'a> {}
141+
138142
impl<'a> Arguments<'a> {
139143
/// When using the format_args!() macro, this function is used to generate the
140144
/// Arguments structure.

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)