-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Immovable types prototype where the Move trait is builtin #44917
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -185,6 +185,8 @@ use marker::Unsize; | |
use mem; | ||
use ops::{Deref, DerefMut, CoerceUnsized}; | ||
use ptr; | ||
#[cfg(not(stage0))] | ||
use marker::Move; | ||
|
||
/// A mutable memory location. | ||
/// | ||
|
@@ -1292,3 +1294,35 @@ fn assert_coerce_unsized(a: UnsafeCell<&i32>, b: Cell<&i32>, c: RefCell<&i32>) { | |
let _: Cell<&Send> = b; | ||
let _: RefCell<&Send> = c; | ||
} | ||
|
||
/// A cell that is always movable, even if the interior type is immovable. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's worth checking the performance effects if you add That will probably require an additional check that no where-clauses are interfering so that |
||
/// This prevents pointers to the inner type which means it can never be observed. | ||
#[cfg(not(stage0))] | ||
#[unstable(feature = "immovable_types", issue = "0")] | ||
#[lang = "movable_cell"] | ||
#[allow(missing_debug_implementations)] | ||
#[derive(Default)] | ||
pub struct MovableCell<T: ?Move> { | ||
value: T, | ||
} | ||
|
||
#[unstable(feature = "immovable_types", issue = "0")] | ||
#[cfg(not(stage0))] | ||
impl<T: ?Move> MovableCell<T> { | ||
/// Creates a new MovableCell. | ||
pub const fn new(value: T) -> Self { | ||
MovableCell { | ||
value: value, | ||
} | ||
} | ||
|
||
/// Extracts the inner value. | ||
pub fn into_inner(self) -> T { | ||
self.value | ||
} | ||
|
||
/// Replaces the inner value. | ||
pub fn replace(&mut self, new_value: T) -> T { | ||
mem::replace(self, MovableCell::new(new_value)).into_inner() | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing newline |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,6 +41,16 @@ use hash::Hasher; | |
#[stable(feature = "rust1", since = "1.0.0")] | ||
#[cfg_attr(stage0, lang = "send")] | ||
#[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"] | ||
#[cfg(not(stage0))] | ||
pub unsafe trait Send: ?Move { | ||
// empty. | ||
} | ||
|
||
/// docs | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
#[lang = "send"] | ||
#[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"] | ||
#[cfg(stage0)] | ||
pub unsafe trait Send { | ||
// empty. | ||
} | ||
|
@@ -50,11 +60,20 @@ pub unsafe trait Send { | |
#[allow(auto_impl)] | ||
unsafe impl Send for .. { } | ||
|
||
#[cfg(stage0)] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
impl<T: ?Sized> !Send for *const T { } | ||
#[cfg(stage0)] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
impl<T: ?Sized> !Send for *mut T { } | ||
|
||
#[cfg(not(stage0))] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
impl<T: ?Sized+?Move> !Send for *const T { } | ||
#[cfg(not(stage0))] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
impl<T: ?Sized+?Move> !Send for *mut T { } | ||
|
||
/// Types with a constant size known at compile time. | ||
/// | ||
/// All type parameters have an implicit bound of `Sized`. The special syntax | ||
|
@@ -92,10 +111,37 @@ impl<T: ?Sized> !Send for *mut T { } | |
#[lang = "sized"] | ||
#[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"] | ||
#[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable | ||
#[cfg(not(stage0))] | ||
pub trait Sized: ?Move { | ||
// Empty. | ||
} | ||
|
||
/// docs | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
#[lang = "sized"] | ||
#[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"] | ||
#[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable | ||
#[cfg(stage0)] | ||
pub trait Sized { | ||
// Empty. | ||
} | ||
|
||
/// Types that can be moved after being borrowed. | ||
#[cfg(not(stage0))] | ||
#[lang = "move"] | ||
#[unstable(feature = "immovable_types", issue = "0")] | ||
pub unsafe trait Move: ?Move { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. weird: do you have to have Just curious, since I noticed that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Auto traits cannot have supertraits because that is unsound. Also we do not want |
||
// Empty. | ||
} | ||
|
||
/// A zero-sized struct which is immovable. | ||
#[cfg(not(stage0))] | ||
#[lang = "immovable"] | ||
#[unstable(feature = "immovable_types", issue = "0")] | ||
#[allow(missing_debug_implementations)] | ||
#[derive(Default)] | ||
pub struct Immovable; | ||
|
||
/// Types that can be "unsized" to a dynamically-sized type. | ||
/// | ||
/// For example, the sized array type `[i8; 2]` implements `Unsize<[i8]>` and | ||
|
@@ -346,6 +392,16 @@ pub trait Copy : Clone { | |
#[stable(feature = "rust1", since = "1.0.0")] | ||
#[lang = "sync"] | ||
#[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"] | ||
#[cfg(not(stage0))] | ||
pub unsafe trait Sync: ?Move { | ||
// Empty | ||
} | ||
|
||
/// docs | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
#[lang = "sync"] | ||
#[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"] | ||
#[cfg(stage0)] | ||
pub unsafe trait Sync { | ||
// Empty | ||
} | ||
|
@@ -355,11 +411,20 @@ pub unsafe trait Sync { | |
#[allow(auto_impl)] | ||
unsafe impl Sync for .. { } | ||
|
||
#[cfg(stage0)] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
impl<T: ?Sized> !Sync for *const T { } | ||
#[cfg(stage0)] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
impl<T: ?Sized> !Sync for *mut T { } | ||
|
||
#[cfg(not(stage0))] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
impl<T: ?Sized+?Move> !Sync for *const T { } | ||
#[cfg(not(stage0))] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
impl<T: ?Sized+?Move> !Sync for *mut T { } | ||
|
||
macro_rules! impls{ | ||
($t: ident) => ( | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
|
@@ -546,6 +611,13 @@ macro_rules! impls{ | |
/// as not to indicate ownership. | ||
/// | ||
/// [drop check]: ../../nomicon/dropck.html | ||
#[cfg(not(stage0))] | ||
#[lang = "phantom_data"] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub struct PhantomData<T:?Sized+?Move>; | ||
|
||
/// docs | ||
#[cfg(stage0)] | ||
#[lang = "phantom_data"] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub struct PhantomData<T:?Sized>; | ||
|
@@ -564,6 +636,11 @@ mod impls { | |
/// This affects, for example, whether a `static` of that type is | ||
/// placed in read-only static memory or writable static memory. | ||
#[lang = "freeze"] | ||
#[cfg(not(stage0))] | ||
unsafe trait Freeze: ?Move {} | ||
|
||
#[lang = "freeze"] | ||
#[cfg(stage0)] | ||
unsafe trait Freeze {} | ||
|
||
#[allow(unknown_lints)] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't a normalCell
takeT: ?Move
? I suppose that wouldn't work because we need a lang-item.