Skip to content

[RFC] Split Copy trait in two traits: Pod and Copy #23016

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1705,6 +1705,7 @@ specific type.
Implementations are defined with the keyword `impl`.

```
# use std::marker::Pod;
# #[derive(Copy)]
# struct Point {x: f64, y: f64};
# type Surface = i32;
Expand All @@ -1716,6 +1717,7 @@ struct Circle {
center: Point,
}

impl Pod for Circle {}
impl Copy for Circle {}

impl Shape for Circle {
Expand Down
2 changes: 2 additions & 0 deletions src/libcollections/enum_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ pub struct EnumSet<E> {
marker: marker::PhantomData<E>,
}

#[cfg(not(stage0))]
impl<E> marker::Pod for EnumSet<E> {}
impl<E> Copy for EnumSet<E> {}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
4 changes: 4 additions & 0 deletions src/libcollections/linked_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ use core::hash::{Hasher, Hash};
use core::iter::{self, FromIterator, IntoIterator};
use core::mem;
use core::ptr;
#[cfg(not(stage0))]
use core::marker::Pod;

#[deprecated(since = "1.0.0", reason = "renamed to LinkedList")]
#[unstable(feature = "collections")]
Expand All @@ -50,6 +52,8 @@ struct Rawlink<T> {
p: *mut T,
}

#[cfg(not(stage0))]
impl<T> Pod for Rawlink<T> {}
impl<T> Copy for Rawlink<T> {}
unsafe impl<T:Send> Send for Rawlink<T> {}
unsafe impl<T:Sync> Sync for Rawlink<T> {}
Expand Down
117 changes: 116 additions & 1 deletion src/libcore/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,18 @@

#![stable(feature = "rust1", since = "1.0.0")]

// TODO(japaric) update docs

use clone::Clone;
use cmp::PartialEq;
use default::Default;
use marker::{Copy, Send, Sync};
#[cfg(not(stage0))]
use mem;
#[cfg(stage0)]
use marker::Copy;
use marker::{Send, Sync};
#[cfg(not(stage0))]
use marker::Pod;
use ops::{Deref, DerefMut, Drop};
use option::Option;
use option::Option::{None, Some};
Expand All @@ -157,6 +165,7 @@ pub struct Cell<T> {
value: UnsafeCell<T>,
}

#[cfg(stage0)]
impl<T:Copy> Cell<T> {
/// Creates a new `Cell` containing the given value.
///
Expand Down Expand Up @@ -232,16 +241,104 @@ impl<T:Copy> Cell<T> {
}
}

#[cfg(not(stage0))]
impl<T:Pod> Cell<T> {
/// Creates a new `Cell` containing the given value.
///
/// # Examples
///
/// ```
/// use std::cell::Cell;
///
/// let c = Cell::new(5);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new(value: T) -> Cell<T> {
Cell {
value: UnsafeCell::new(value),
}
}

/// Returns a copy of the contained value.
///
/// # Examples
///
/// ```
/// use std::cell::Cell;
///
/// let c = Cell::new(5);
///
/// let five = c.get();
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get(&self) -> T {
unsafe {
mem::transmute_copy(mem::transmute::<_, &T>(self.value.get()))
}
}

/// Sets the contained value.
///
/// # Examples
///
/// ```
/// use std::cell::Cell;
///
/// let c = Cell::new(5);
///
/// c.set(10);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn set(&self, value: T) {
unsafe {
*self.value.get() = value;
}
}

/// Get a reference to the underlying `UnsafeCell`.
///
/// # Unsafety
///
/// This function is `unsafe` because `UnsafeCell`'s field is public.
///
/// # Examples
///
/// ```
/// use std::cell::Cell;
///
/// let c = Cell::new(5);
///
/// let uc = unsafe { c.as_unsafe_cell() };
/// ```
#[inline]
#[unstable(feature = "core")]
pub unsafe fn as_unsafe_cell<'a>(&'a self) -> &'a UnsafeCell<T> {
&self.value
}
}

#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<T> Send for Cell<T> where T: Send {}

#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T:Copy> Clone for Cell<T> {
fn clone(&self) -> Cell<T> {
Cell::new(self.get())
}
}

#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T:Pod> Clone for Cell<T> {
fn clone(&self) -> Cell<T> {
Cell::new(self.get())
}
}

#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T:Default + Copy> Default for Cell<T> {
#[stable(feature = "rust1", since = "1.0.0")]
Expand All @@ -250,13 +347,31 @@ impl<T:Default + Copy> Default for Cell<T> {
}
}

#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T:Default + Pod> Default for Cell<T> {
#[stable(feature = "rust1", since = "1.0.0")]
fn default() -> Cell<T> {
Cell::new(Default::default())
}
}

#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T:PartialEq + Copy> PartialEq for Cell<T> {
fn eq(&self, other: &Cell<T>) -> bool {
self.get() == other.get()
}
}

#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T:PartialEq + Pod> PartialEq for Cell<T> {
fn eq(&self, other: &Cell<T>) -> bool {
self.get() == other.get()
}
}

/// A mutable memory location with dynamically checked borrow rules
///
/// See the [module-level documentation](index.html) for more.
Expand Down
17 changes: 17 additions & 0 deletions src/libcore/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub trait Sized : MarkerTrait {
// Empty.
}

#[cfg(stage0)]
/// Types that can be copied by simply copying bits (i.e. `memcpy`).
///
/// By default, variable bindings have 'move semantics.' In other
Expand Down Expand Up @@ -156,6 +157,20 @@ pub trait Copy : MarkerTrait {
// Empty.
}

/// TODO(japaric) docs
#[cfg(not(stage0))]
#[lang="copy"]
pub trait Copy: Pod {
// Empty
}

/// TODO(japaric) docs
#[cfg(not(stage0))]
#[lang="pod"]
pub trait Pod: MarkerTrait {
// Empty
}

/// Types that can be safely shared between threads when aliased.
///
/// The precise definition is: a type `T` is `Sync` if `&T` is
Expand Down Expand Up @@ -258,6 +273,8 @@ macro_rules! impls{
}
}

#[cfg(not(stage0))]
impl<T:?Sized> Pod for $t<T> { }
impl<T:?Sized> Copy for $t<T> { }

impl<T:?Sized> Clone for $t<T> {
Expand Down
13 changes: 13 additions & 0 deletions src/libcore/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,7 @@ impl fmt::Debug for RangeFull {
}
}

#[cfg(stage0)]
/// A (half-open) range which is bounded at both ends.
#[derive(Clone, PartialEq, Eq)]
#[lang="range"]
Expand All @@ -988,6 +989,18 @@ pub struct Range<Idx> {
pub end: Idx,
}

#[cfg(not(stage0))]
/// A (half-open) range which is bounded at both ends.
#[derive(Clone, Eq, PartialEq, Pod)]
#[lang="range"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Range<Idx> {
/// The lower bound of the range (inclusive).
pub start: Idx,
/// The upper bound of the range (exclusive).
pub end: Idx,
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
Expand Down
4 changes: 4 additions & 0 deletions src/libcore/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
//! Their definition should always match the ABI defined in `rustc::back::abi`.

use marker::Copy;
#[cfg(not(stage0))]
use marker::Pod;
use mem;

/// The representation of a slice like `&[T]`.
Expand Down Expand Up @@ -62,6 +64,8 @@ pub struct Slice<T> {
}

impl<T> Copy for Slice<T> {}
#[cfg(not(stage0))]
impl<T> Pod for Slice<T> {}

/// The representation of an old closure.
#[repr(C)]
Expand Down
5 changes: 4 additions & 1 deletion src/librustc/metadata/tydecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -891,9 +891,12 @@ fn parse_builtin_bounds_<F>(st: &mut PState, _conv: &mut F) -> ty::BuiltinBounds
'Z' => {
builtin_bounds.insert(ty::BoundSized);
}
'P' => {
'C' => {
builtin_bounds.insert(ty::BoundCopy);
}
'P' => {
builtin_bounds.insert(ty::BoundPod);
}
'T' => {
builtin_bounds.insert(ty::BoundSync);
}
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/metadata/tyencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,8 @@ pub fn enc_builtin_bounds(w: &mut Encoder, _cx: &ctxt, bs: &ty::BuiltinBounds) {
match bound {
ty::BoundSend => mywrite!(w, "S"),
ty::BoundSized => mywrite!(w, "Z"),
ty::BoundCopy => mywrite!(w, "P"),
ty::BoundCopy => mywrite!(w, "C"),
ty::BoundPod => mywrite!(w, "P"),
ty::BoundSync => mywrite!(w, "T"),
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/librustc/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ impl LanguageItems {
ty::BoundSend => self.require(SendTraitLangItem),
ty::BoundSized => self.require(SizedTraitLangItem),
ty::BoundCopy => self.require(CopyTraitLangItem),
ty::BoundPod => self.require(PodTraitLangItem),
ty::BoundSync => self.require(SyncTraitLangItem),
}
}
Expand All @@ -106,6 +107,8 @@ impl LanguageItems {
Some(ty::BoundSized)
} else if Some(id) == self.copy_trait() {
Some(ty::BoundCopy)
} else if Some(id) == self.pod_trait() {
Some(ty::BoundPod)
} else if Some(id) == self.sync_trait() {
Some(ty::BoundSync)
} else {
Expand Down Expand Up @@ -242,6 +245,7 @@ lets_do_this! {
SendTraitLangItem, "send", send_trait;
SizedTraitLangItem, "sized", sized_trait;
CopyTraitLangItem, "copy", copy_trait;
PodTraitLangItem, "pod", pod_trait;
SyncTraitLangItem, "sync", sync_trait;

DropTraitLangItem, "drop", drop_trait;
Expand Down
4 changes: 4 additions & 0 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ use syntax::print::pprust;
use syntax::parse::token;

use std::cell::RefCell;
#[cfg(not(stage0))]
use std::marker::Pod;
use std::rc::Rc;

#[derive(Clone, PartialEq, Debug)]
Expand Down Expand Up @@ -260,6 +262,8 @@ pub struct MemCategorizationContext<'t,TYPER:'t> {
typer: &'t TYPER
}

#[cfg(not(stage0))]
impl<'t,TYPER:'t> Pod for MemCategorizationContext<'t,TYPER> {}
impl<'t,TYPER:'t> Copy for MemCategorizationContext<'t,TYPER> {}

pub type McResult<T> = Result<T, ()>;
Expand Down
Loading