Skip to content

libsyntax: Remove "copy" pattern bindings from the language #7051

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 9 commits into from
14 changes: 7 additions & 7 deletions doc/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -2859,13 +2859,13 @@ call to the method `make_string`.
Types in Rust are categorized into kinds, based on various properties of the components of the type.
The kinds are:

`Const`
`Freeze`
: Types of this kind are deeply immutable;
they contain no mutable memory locations directly or indirectly via pointers.
`Owned`
`Send`
: Types of this kind can be safely sent between tasks.
This kind includes scalars, owning pointers, owned closures, and
structural types containing only other owned types. All `Owned` types are `Static`.
structural types containing only other owned types. All `Send` types are `Static`.
`Static`
: Types of this kind do not contain any borrowed pointers;
this can be a useful guarantee for code that breaks borrowing assumptions using [`unsafe` operations](#unsafe-functions).
Expand All @@ -2879,7 +2879,7 @@ The kinds are:
trait provides a single method `finalize` that takes no parameters, and is run
when values of the type are dropped. Such a method is called a "destructor",
and are always executed in "top-down" order: a value is completely destroyed
before any of the values it owns run their destructors. Only `Owned` types
before any of the values it owns run their destructors. Only `Send` types
that do not implement `Copy` can implement `Drop`.

> **Note:** The `finalize` method may be renamed in future versions of Rust.
Expand Down Expand Up @@ -2965,10 +2965,10 @@ frame they are allocated within.
A task owns all memory it can *safely* reach through local variables,
as well as managed, owning and borrowed pointers.

When a task sends a value that has the `Owned` trait to another task,
When a task sends a value that has the `Send` trait to another task,
it loses ownership of the value sent and can no longer refer to it.
This is statically guaranteed by the combined use of "move semantics",
and the compiler-checked _meaning_ of the `Owned` trait:
and the compiler-checked _meaning_ of the `Send` trait:
it is only instantiated for (transitively) sendable kinds of data constructor and pointers,
never including managed or borrowed pointers.

Expand Down Expand Up @@ -3113,7 +3113,7 @@ These include:
- read-only and read-write shared variables with various safe mutual exclusion patterns
- simple locks and semaphores

When such facilities carry values, the values are restricted to the [`Owned` type-kind](#type-kinds).
When such facilities carry values, the values are restricted to the [`Send` type-kind](#type-kinds).
Restricting communication interfaces to this kind ensures that no borrowed or managed pointers move between tasks.
Thus access to an entire data structure can be mediated through its owning "root" value;
no further locking or copying is required to avoid data races within the substructure of such a value.
Expand Down
4 changes: 2 additions & 2 deletions doc/tutorial-ffi.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ pub struct Unique<T> {
priv ptr: *mut T
}

impl<T: Owned> Unique<T> {
impl<T: Send> Unique<T> {
pub fn new(value: T) -> Unique<T> {
unsafe {
let ptr = malloc(std::sys::size_of::<T>() as size_t) as *mut T;
Expand All @@ -182,7 +182,7 @@ impl<T: Owned> Unique<T> {
}

#[unsafe_destructor]
impl<T: Owned> Drop for Unique<T> {
impl<T: Send> Drop for Unique<T> {
fn finalize(&self) {
unsafe {
let x = intrinsics::init(); // dummy value to swap in
Expand Down
28 changes: 14 additions & 14 deletions src/libextra/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,15 @@ impl<'self> Condvar<'self> {
pub struct ARC<T> { x: UnsafeAtomicRcBox<T> }

/// Create an atomically reference counted wrapper.
pub fn ARC<T:Const + Owned>(data: T) -> ARC<T> {
pub fn ARC<T:Freeze + Send>(data: T) -> ARC<T> {
ARC { x: UnsafeAtomicRcBox::new(data) }
}

/**
* Access the underlying data in an atomically reference counted
* wrapper.
*/
impl<T:Const+Owned> ARC<T> {
impl<T:Freeze+Send> ARC<T> {
pub fn get<'a>(&'a self) -> &'a T {
unsafe { &*self.x.get_immut() }
}
Expand All @@ -133,7 +133,7 @@ impl<T:Const+Owned> ARC<T> {
* object. However, one of the `arc` objects can be sent to another task,
* allowing them to share the underlying data.
*/
impl<T:Const + Owned> Clone for ARC<T> {
impl<T:Freeze + Send> Clone for ARC<T> {
fn clone(&self) -> ARC<T> {
ARC { x: self.x.clone() }
}
Expand All @@ -149,22 +149,22 @@ struct MutexARCInner<T> { lock: Mutex, failed: bool, data: T }
struct MutexARC<T> { x: UnsafeAtomicRcBox<MutexARCInner<T>> }

/// Create a mutex-protected ARC with the supplied data.
pub fn MutexARC<T:Owned>(user_data: T) -> MutexARC<T> {
pub fn MutexARC<T:Send>(user_data: T) -> MutexARC<T> {
mutex_arc_with_condvars(user_data, 1)
}
/**
* Create a mutex-protected ARC with the supplied data and a specified number
* of condvars (as sync::mutex_with_condvars).
*/
pub fn mutex_arc_with_condvars<T:Owned>(user_data: T,
pub fn mutex_arc_with_condvars<T:Send>(user_data: T,
num_condvars: uint) -> MutexARC<T> {
let data =
MutexARCInner { lock: mutex_with_condvars(num_condvars),
failed: false, data: user_data };
MutexARC { x: UnsafeAtomicRcBox::new(data) }
}

impl<T:Owned> Clone for MutexARC<T> {
impl<T:Send> Clone for MutexARC<T> {
/// Duplicate a mutex-protected ARC, as arc::clone.
fn clone(&self) -> MutexARC<T> {
// NB: Cloning the underlying mutex is not necessary. Its reference
Expand All @@ -173,7 +173,7 @@ impl<T:Owned> Clone for MutexARC<T> {
}
}

impl<T:Owned> MutexARC<T> {
impl<T:Send> MutexARC<T> {

/**
* Access the underlying mutable data with mutual exclusion from other
Expand Down Expand Up @@ -285,14 +285,14 @@ struct RWARC<T> {
}

/// Create a reader/writer ARC with the supplied data.
pub fn RWARC<T:Const + Owned>(user_data: T) -> RWARC<T> {
pub fn RWARC<T:Freeze + Send>(user_data: T) -> RWARC<T> {
rw_arc_with_condvars(user_data, 1)
}
/**
* Create a reader/writer ARC with the supplied data and a specified number
* of condvars (as sync::rwlock_with_condvars).
*/
pub fn rw_arc_with_condvars<T:Const + Owned>(
pub fn rw_arc_with_condvars<T:Freeze + Send>(
user_data: T,
num_condvars: uint) -> RWARC<T>
{
Expand All @@ -302,7 +302,7 @@ pub fn rw_arc_with_condvars<T:Const + Owned>(
RWARC { x: UnsafeAtomicRcBox::new(data), cant_nest: () }
}

impl<T:Const + Owned> RWARC<T> {
impl<T:Freeze + Send> RWARC<T> {
/// Duplicate a rwlock-protected ARC, as arc::clone.
pub fn clone(&self) -> RWARC<T> {
RWARC {
Expand All @@ -313,7 +313,7 @@ impl<T:Const + Owned> RWARC<T> {

}

impl<T:Const + Owned> RWARC<T> {
impl<T:Freeze + Send> RWARC<T> {
/**
* Access the underlying data mutably. Locks the rwlock in write mode;
* other readers and writers will block.
Expand Down Expand Up @@ -439,7 +439,7 @@ impl<T:Const + Owned> RWARC<T> {
// lock it. This wraps the unsafety, with the justification that the 'lock'
// field is never overwritten; only 'failed' and 'data'.
#[doc(hidden)]
fn borrow_rwlock<T:Const + Owned>(state: *const RWARCInner<T>) -> *RWlock {
fn borrow_rwlock<T:Freeze + Send>(state: *const RWARCInner<T>) -> *RWlock {
unsafe { cast::transmute(&const (*state).lock) }
}

Expand All @@ -456,7 +456,7 @@ pub struct RWReadMode<'self, T> {
token: sync::RWlockReadMode<'self>,
}

impl<'self, T:Const + Owned> RWWriteMode<'self, T> {
impl<'self, T:Freeze + Send> RWWriteMode<'self, T> {
/// Access the pre-downgrade RWARC in write mode.
pub fn write<U>(&mut self, blk: &fn(x: &mut T) -> U) -> U {
match *self {
Expand Down Expand Up @@ -497,7 +497,7 @@ impl<'self, T:Const + Owned> RWWriteMode<'self, T> {
}
}

impl<'self, T:Const + Owned> RWReadMode<'self, T> {
impl<'self, T:Freeze + Send> RWReadMode<'self, T> {
/// Access the post-downgrade rwlock in read mode.
pub fn read<U>(&self, blk: &fn(x: &T) -> U) -> U {
match *self {
Expand Down
14 changes: 7 additions & 7 deletions src/libextra/comm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub struct DuplexStream<T, U> {
}

// Allow these methods to be used without import:
impl<T:Owned,U:Owned> DuplexStream<T, U> {
impl<T:Send,U:Send> DuplexStream<T, U> {
pub fn send(&self, x: T) {
self.chan.send(x)
}
Expand All @@ -48,19 +48,19 @@ impl<T:Owned,U:Owned> DuplexStream<T, U> {
}
}

impl<T:Owned,U:Owned> GenericChan<T> for DuplexStream<T, U> {
impl<T:Send,U:Send> GenericChan<T> for DuplexStream<T, U> {
fn send(&self, x: T) {
self.chan.send(x)
}
}

impl<T:Owned,U:Owned> GenericSmartChan<T> for DuplexStream<T, U> {
impl<T:Send,U:Send> GenericSmartChan<T> for DuplexStream<T, U> {
fn try_send(&self, x: T) -> bool {
self.chan.try_send(x)
}
}

impl<T:Owned,U:Owned> GenericPort<U> for DuplexStream<T, U> {
impl<T:Send,U:Send> GenericPort<U> for DuplexStream<T, U> {
fn recv(&self) -> U {
self.port.recv()
}
Expand All @@ -70,20 +70,20 @@ impl<T:Owned,U:Owned> GenericPort<U> for DuplexStream<T, U> {
}
}

impl<T:Owned,U:Owned> Peekable<U> for DuplexStream<T, U> {
impl<T:Send,U:Send> Peekable<U> for DuplexStream<T, U> {
fn peek(&self) -> bool {
self.port.peek()
}
}

impl<T:Owned,U:Owned> Selectable for DuplexStream<T, U> {
impl<T:Send,U:Send> Selectable for DuplexStream<T, U> {
fn header(&mut self) -> *mut pipes::PacketHeader {
self.port.header()
}
}

/// Creates a bidirectional stream.
pub fn DuplexStream<T:Owned,U:Owned>()
pub fn DuplexStream<T:Send,U:Send>()
-> (DuplexStream<T, U>, DuplexStream<U, T>)
{
let (p1, c2) = comm::stream();
Expand Down
24 changes: 12 additions & 12 deletions src/libextra/flatpipes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ Constructors for flat pipes that send POD types using memcpy.

# Safety Note

This module is currently unsafe because it uses `Copy Owned` as a type
parameter bounds meaning POD (plain old data), but `Copy Owned` and
This module is currently unsafe because it uses `Copy Send` as a type
parameter bounds meaning POD (plain old data), but `Copy Send` and
POD are not equivelant.

*/
Expand All @@ -191,7 +191,7 @@ pub mod pod {
pub type PipeChan<T> = FlatChan<T, PodFlattener<T>, PipeByteChan>;

/// Create a `FlatPort` from a `Reader`
pub fn reader_port<T:Copy + Owned,R:Reader>(
pub fn reader_port<T:Copy + Send,R:Reader>(
reader: R
) -> ReaderPort<T, R> {
let unflat: PodUnflattener<T> = PodUnflattener::new();
Expand All @@ -200,7 +200,7 @@ pub mod pod {
}

/// Create a `FlatChan` from a `Writer`
pub fn writer_chan<T:Copy + Owned,W:Writer>(
pub fn writer_chan<T:Copy + Send,W:Writer>(
writer: W
) -> WriterChan<T, W> {
let flat: PodFlattener<T> = PodFlattener::new();
Expand All @@ -209,21 +209,21 @@ pub mod pod {
}

/// Create a `FlatPort` from a `Port<~[u8]>`
pub fn pipe_port<T:Copy + Owned>(port: Port<~[u8]>) -> PipePort<T> {
pub fn pipe_port<T:Copy + Send>(port: Port<~[u8]>) -> PipePort<T> {
let unflat: PodUnflattener<T> = PodUnflattener::new();
let byte_port = PipeBytePort::new(port);
FlatPort::new(unflat, byte_port)
}

/// Create a `FlatChan` from a `Chan<~[u8]>`
pub fn pipe_chan<T:Copy + Owned>(chan: Chan<~[u8]>) -> PipeChan<T> {
pub fn pipe_chan<T:Copy + Send>(chan: Chan<~[u8]>) -> PipeChan<T> {
let flat: PodFlattener<T> = PodFlattener::new();
let byte_chan = PipeByteChan::new(chan);
FlatChan::new(flat, byte_chan)
}

/// Create a pair of `FlatChan` and `FlatPort`, backed by pipes
pub fn pipe_stream<T:Copy + Owned>() -> (PipePort<T>, PipeChan<T>) {
pub fn pipe_stream<T:Copy + Send>() -> (PipePort<T>, PipeChan<T>) {
let (port, chan) = comm::stream();
return (pipe_port(port), pipe_chan(chan));
}
Expand Down Expand Up @@ -352,7 +352,7 @@ pub mod flatteners {
use core::sys::size_of;
use core::vec;

// FIXME #4074: Copy + Owned != POD
// FIXME #4074: Copy + Send != POD
pub struct PodUnflattener<T> {
bogus: ()
}
Expand All @@ -361,7 +361,7 @@ pub mod flatteners {
bogus: ()
}

impl<T:Copy + Owned> Unflattener<T> for PodUnflattener<T> {
impl<T:Copy + Send> Unflattener<T> for PodUnflattener<T> {
fn unflatten(&self, buf: ~[u8]) -> T {
assert!(size_of::<T>() != 0);
assert_eq!(size_of::<T>(), buf.len());
Expand All @@ -371,7 +371,7 @@ pub mod flatteners {
}
}

impl<T:Copy + Owned> Flattener<T> for PodFlattener<T> {
impl<T:Copy + Send> Flattener<T> for PodFlattener<T> {
fn flatten(&self, val: T) -> ~[u8] {
assert!(size_of::<T>() != 0);
let val: *T = ptr::to_unsafe_ptr(&val);
Expand All @@ -380,15 +380,15 @@ pub mod flatteners {
}
}

impl<T:Copy + Owned> PodUnflattener<T> {
impl<T:Copy + Send> PodUnflattener<T> {
pub fn new() -> PodUnflattener<T> {
PodUnflattener {
bogus: ()
}
}
}

impl<T:Copy + Owned> PodFlattener<T> {
impl<T:Copy + Send> PodFlattener<T> {
pub fn new() -> PodFlattener<T> {
PodFlattener {
bogus: ()
Expand Down
4 changes: 2 additions & 2 deletions src/libextra/future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ pub fn from_value<A>(val: A) -> Future<A> {
Future {state: Forced(val)}
}

pub fn from_port<A:Owned>(port: PortOne<A>) -> Future<A> {
pub fn from_port<A:Send>(port: PortOne<A>) -> Future<A> {
/*!
* Create a future from a port
*
Expand All @@ -127,7 +127,7 @@ pub fn from_fn<A>(f: ~fn() -> A) -> Future<A> {
Future {state: Pending(f)}
}

pub fn spawn<A:Owned>(blk: ~fn() -> A) -> Future<A> {
pub fn spawn<A:Send>(blk: ~fn() -> A) -> Future<A> {
/*!
* Create a future from a unique closure.
*
Expand Down
3 changes: 2 additions & 1 deletion src/libextra/md4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ pub fn md4(msg: &[u8]) -> Quad {
while i < e {
let (aa, bb, cc, dd) = (a, b, c, d);

let mut (j, base) = (0u, i);
let mut j = 0u;
let mut base = i;
while j < 16u {
x[j] = (msg[base] as u32) + (msg[base + 1u] as u32 << 8u32) +
(msg[base + 2u] as u32 << 16u32) +
Expand Down
4 changes: 3 additions & 1 deletion src/libextra/net_url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,9 @@ fn get_authority(rawurl: &str) ->
let mut port = None;

let mut colon_count = 0;
let mut (pos, begin, end) = (0, 2, len);
let mut pos = 0;
let mut begin = 2;
let mut end = len;

for rawurl.iter().enumerate().advance |(i,c)| {
if i < 2 { loop; } // ignore the leading //
Expand Down
Loading