Skip to content

Forbid type impls on typedefs #6087

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 14 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
6 changes: 3 additions & 3 deletions doc/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -2187,7 +2187,7 @@ A loop expression denotes an infinite loop;
see [Continue expressions](#continue-expressions) for continue expressions.

~~~~~~~~{.ebnf .gram}
loop_expr : "loop" [ ident ':' ] '{' block '}';
loop_expr : [ lifetime ':' ] "loop" '{' block '}';
~~~~~~~~

A `loop` expression may optionally have a _label_.
Expand All @@ -2198,7 +2198,7 @@ See [Break expressions](#break-expressions).
### Break expressions

~~~~~~~~{.ebnf .gram}
break_expr : "break" [ ident ];
break_expr : "break" [ lifetime ];
~~~~~~~~

A `break` expression has an optional `label`.
Expand All @@ -2211,7 +2211,7 @@ but must enclose it.
### Continue expressions

~~~~~~~~{.ebnf .gram}
continue_expr : "loop" [ ident ];
continue_expr : "loop" [ lifetime ];
~~~~~~~~

A continue expression, written `loop`, also has an optional `label`.
Expand Down
18 changes: 7 additions & 11 deletions src/libcore/at_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use cast::transmute;
use kinds::Copy;
use iter;
use option::Option;
use ptr::addr_of;
use sys;
use uint;
use vec;
Expand All @@ -40,8 +39,7 @@ pub mod rustrt {
#[inline(always)]
pub fn capacity<T>(v: @[T]) -> uint {
unsafe {
let repr: **raw::VecRepr =
::cast::transmute(addr_of(&v));
let repr: **raw::VecRepr = transmute(&v);
(**repr).unboxed.alloc / sys::size_of::<T>()
}
}
Expand Down Expand Up @@ -187,13 +185,12 @@ pub mod traits {}

pub mod raw {
use at_vec::{capacity, rustrt};
use cast::transmute;
use cast::{transmute, transmute_copy};
use libc;
use unstable::intrinsics::{move_val_init};
use ptr::addr_of;
use ptr;
use sys;
use uint;
use unstable::intrinsics::{move_val_init};
use vec;

pub type VecRepr = vec::raw::VecRepr;
Expand All @@ -208,18 +205,17 @@ pub mod raw {
*/
#[inline(always)]
pub unsafe fn set_len<T>(v: @[T], new_len: uint) {
let repr: **mut VecRepr = ::cast::transmute(addr_of(&v));
let repr: **mut VecRepr = transmute(&v);
(**repr).unboxed.fill = new_len * sys::size_of::<T>();
}

#[inline(always)]
pub unsafe fn push<T>(v: &mut @[T], initval: T) {
let repr: **VecRepr = ::cast::reinterpret_cast(&v);
let repr: **VecRepr = transmute_copy(&v);
let fill = (**repr).unboxed.fill;
if (**repr).unboxed.alloc > fill {
push_fast(v, initval);
}
else {
} else {
push_slow(v, initval);
}
}
Expand All @@ -229,7 +225,7 @@ pub mod raw {
let repr: **mut VecRepr = ::cast::transmute(v);
let fill = (**repr).unboxed.fill;
(**repr).unboxed.fill += sys::size_of::<T>();
let p = addr_of(&((**repr).unboxed.data));
let p = &((**repr).unboxed.data);
let p = ptr::offset(p, fill) as *mut T;
move_val_init(&mut(*p), initval);
}
Expand Down
61 changes: 57 additions & 4 deletions src/libcore/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,56 @@

//! Unsafe casting functions

use sys;
use unstable;

pub mod rusti {
#[abi = "rust-intrinsic"]
#[link_name = "rusti"]
pub extern "rust-intrinsic" {
fn forget<T>(+x: T);

#[cfg(stage0)]
fn reinterpret_cast<T, U>(&&e: T) -> U;

#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn transmute<T,U>(e: T) -> U;
}
}

/// Casts the value at `src` to U. The two types must have the same length.
#[inline(always)]
#[cfg(stage0)]
pub unsafe fn reinterpret_cast<T, U>(src: &T) -> U {
rusti::reinterpret_cast(*src)
}

/// Unsafely copies and casts the value at `src` to U, even if the value is
/// noncopyable. The two types must have the same length.
#[inline(always)]
#[cfg(stage0)]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
rusti::reinterpret_cast(*src)
}

#[inline(always)]
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
let mut dest: U = unstable::intrinsics::init();
{
let dest_ptr: *mut u8 = rusti::transmute(&mut dest);
let src_ptr: *u8 = rusti::transmute(src);
unstable::intrinsics::memmove64(dest_ptr,
src_ptr,
sys::size_of::<U>() as u64);
}
dest
}

/**
* Move a thing into the void
*
Expand Down Expand Up @@ -53,12 +88,21 @@ pub unsafe fn bump_box_refcount<T>(t: @T) { forget(t); }
* assert!(transmute("L") == ~[76u8, 0u8]);
*/
#[inline(always)]
#[cfg(stage0)]
pub unsafe fn transmute<L, G>(thing: L) -> G {
let newthing: G = reinterpret_cast(&thing);
forget(thing);
newthing
}

#[inline(always)]
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
pub unsafe fn transmute<L, G>(thing: L) -> G {
rusti::transmute(thing)
}

/// Coerce an immutable reference to be mutable.
#[inline(always)]
pub unsafe fn transmute_mut<'a,T>(ptr: &'a T) -> &'a mut T { transmute(ptr) }
Expand Down Expand Up @@ -112,11 +156,20 @@ pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T {

#[cfg(test)]
mod tests {
use cast::{bump_box_refcount, reinterpret_cast, transmute};
use cast::{bump_box_refcount, transmute};

#[test]
#[cfg(stage0)]
fn test_reinterpret_cast() {
assert!(1u == unsafe { reinterpret_cast(&1) });
assert!(1u == unsafe { ::cast::reinterpret_cast(&1) });
}

#[test]
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn test_transmute_copy() {
assert!(1u == unsafe { ::cast::transmute_copy(&1) });
}

#[test]
Expand All @@ -125,8 +178,8 @@ mod tests {
let box = @~"box box box"; // refcount 1
bump_box_refcount(box); // refcount 2
let ptr: *int = transmute(box); // refcount 2
let _box1: @~str = reinterpret_cast(&ptr);
let _box2: @~str = reinterpret_cast(&ptr);
let _box1: @~str = ::cast::transmute_copy(&ptr);
let _box2: @~str = ::cast::transmute_copy(&ptr);
assert!(*_box1 == ~"box box box");
assert!(*_box2 == ~"box box box");
// Will destroy _box1 and _box2. Without the bump, this would
Expand Down
78 changes: 62 additions & 16 deletions src/libcore/comm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ impl<T: Owned> ::clone::Clone for SharedChan<T> {
#[allow(non_camel_case_types)]
pub mod oneshot {
priv use core::kinds::Owned;
use ptr::to_unsafe_ptr;

pub fn init<T: Owned>() -> (client::Oneshot<T>, server::Oneshot<T>) {
pub use core::pipes::HasBuffer;
Expand All @@ -341,7 +342,7 @@ pub mod oneshot {
do ::core::pipes::entangle_buffer(buffer) |buffer, data| {
{
data.Oneshot.set_buffer(buffer);
::ptr::addr_of(&(data.Oneshot))
to_unsafe_ptr(&data.Oneshot)
}
}
}
Expand Down Expand Up @@ -394,58 +395,103 @@ pub mod oneshot {
}

/// The send end of a oneshot pipe.
pub type ChanOne<T> = oneshot::client::Oneshot<T>;
pub struct ChanOne<T> {
contents: oneshot::client::Oneshot<T>
}

impl<T> ChanOne<T> {
pub fn new(contents: oneshot::client::Oneshot<T>) -> ChanOne<T> {
ChanOne {
contents: contents
}
}
}

/// The receive end of a oneshot pipe.
pub type PortOne<T> = oneshot::server::Oneshot<T>;
pub struct PortOne<T> {
contents: oneshot::server::Oneshot<T>
}

impl<T> PortOne<T> {
pub fn new(contents: oneshot::server::Oneshot<T>) -> PortOne<T> {
PortOne {
contents: contents
}
}
}

/// Initialiase a (send-endpoint, recv-endpoint) oneshot pipe pair.
pub fn oneshot<T: Owned>() -> (PortOne<T>, ChanOne<T>) {
let (chan, port) = oneshot::init();
(port, chan)
(PortOne::new(port), ChanOne::new(chan))
}

pub impl<T: Owned> PortOne<T> {
fn recv(self) -> T { recv_one(self) }
fn try_recv(self) -> Option<T> { try_recv_one(self) }
fn unwrap(self) -> oneshot::server::Oneshot<T> {
match self {
PortOne { contents: s } => s
}
}
}

pub impl<T: Owned> ChanOne<T> {
fn send(self, data: T) { send_one(self, data) }
fn try_send(self, data: T) -> bool { try_send_one(self, data) }
fn unwrap(self) -> oneshot::client::Oneshot<T> {
match self {
ChanOne { contents: s } => s
}
}
}

/**
* Receive a message from a oneshot pipe, failing if the connection was
* closed.
*/
pub fn recv_one<T: Owned>(port: PortOne<T>) -> T {
let oneshot::send(message) = recv(port);
message
match port {
PortOne { contents: port } => {
let oneshot::send(message) = recv(port);
message
}
}
}

/// Receive a message from a oneshot pipe unless the connection was closed.
pub fn try_recv_one<T: Owned> (port: PortOne<T>) -> Option<T> {
let message = try_recv(port);

if message.is_none() { None }
else {
let oneshot::send(message) = message.unwrap();
Some(message)
match port {
PortOne { contents: port } => {
let message = try_recv(port);

if message.is_none() {
None
} else {
let oneshot::send(message) = message.unwrap();
Some(message)
}
}
}
}

/// Send a message on a oneshot pipe, failing if the connection was closed.
pub fn send_one<T: Owned>(chan: ChanOne<T>, data: T) {
oneshot::client::send(chan, data);
match chan {
ChanOne { contents: chan } => oneshot::client::send(chan, data),
}
}

/**
* Send a message on a oneshot pipe, or return false if the connection was
* closed.
*/
pub fn try_send_one<T: Owned>(chan: ChanOne<T>, data: T)
-> bool {
oneshot::client::try_send(chan, data).is_some()
pub fn try_send_one<T: Owned>(chan: ChanOne<T>, data: T) -> bool {
match chan {
ChanOne { contents: chan } => {
oneshot::client::try_send(chan, data).is_some()
}
}
}


Expand Down
4 changes: 2 additions & 2 deletions src/libcore/flate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub fn deflate_bytes(bytes: &const [u8]) -> ~[u8] {
let res =
rustrt::tdefl_compress_mem_to_heap(b as *c_void,
len as size_t,
ptr::addr_of(&outsz),
&outsz,
lz_norm);
assert!(res as int != 0);
let out = vec::raw::from_buf_raw(res as *u8,
Expand All @@ -71,7 +71,7 @@ pub fn inflate_bytes(bytes: &const [u8]) -> ~[u8] {
let res =
rustrt::tinfl_decompress_mem_to_heap(b as *c_void,
len as size_t,
ptr::addr_of(&outsz),
&outsz,
0);
assert!(res as int != 0);
let out = vec::raw::from_buf_raw(res as *u8,
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ pub fn cleanup_stack_for_failure() {
// own stack roots on the stack anyway.
let sentinel_box = ~0;
let sentinel: **Word = if expect_sentinel() {
cast::transmute(ptr::addr_of(&sentinel_box))
cast::transmute(&sentinel_box)
} else {
ptr::null()
};
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/hashmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn resize_at(capacity: uint) -> uint {
pub fn linear_map_with_capacity<K:Eq + Hash,V>(
initial_capacity: uint) -> HashMap<K, V> {
let r = rand::task_rng();
linear_map_with_capacity_and_keys(r.gen(), r.gen(),
linear_map_with_capacity_and_keys((*r).gen_u64(), (*r).gen_u64(),
initial_capacity)
}

Expand Down
Loading