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 #13231. Part of RFC #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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 3 additions & 0 deletions
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 8 additions & 1 deletion
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

Lines changed: 7 additions & 0 deletions
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

Lines changed: 3 additions & 0 deletions
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

Lines changed: 13 additions & 3 deletions
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

Lines changed: 21 additions & 13 deletions
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

0 commit comments

Comments
 (0)