Stablize the alloc module without changing stability of its contents.
This commit is contained in:
parent
e9fd063edb
commit
951bc28fd0
4 changed files with 51 additions and 18 deletions
|
@ -10,17 +10,13 @@
|
||||||
|
|
||||||
//! Memory allocation APIs
|
//! Memory allocation APIs
|
||||||
|
|
||||||
#![unstable(feature = "allocator_api",
|
#![stable(feature = "alloc_module", since = "1.28.0")]
|
||||||
reason = "the precise API and guarantees it provides may be tweaked \
|
|
||||||
slightly, especially to possibly take into account the \
|
|
||||||
types being stored to make room for a future \
|
|
||||||
tracing garbage collector",
|
|
||||||
issue = "32838")]
|
|
||||||
|
|
||||||
use core::intrinsics::{min_align_of_val, size_of_val};
|
use core::intrinsics::{min_align_of_val, size_of_val};
|
||||||
use core::ptr::{NonNull, Unique};
|
use core::ptr::{NonNull, Unique};
|
||||||
use core::usize;
|
use core::usize;
|
||||||
|
|
||||||
|
#[stable(feature = "alloc_module", since = "1.28.0")]
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use core::alloc::*;
|
pub use core::alloc::*;
|
||||||
|
|
||||||
|
@ -44,6 +40,7 @@ extern "Rust" {
|
||||||
/// This type implements the [`Alloc`] trait by forwarding calls
|
/// This type implements the [`Alloc`] trait by forwarding calls
|
||||||
/// to the allocator registered with the `#[global_allocator]` attribute
|
/// to the allocator registered with the `#[global_allocator]` attribute
|
||||||
/// if there is one, or the `std` crate’s default.
|
/// if there is one, or the `std` crate’s default.
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[derive(Copy, Clone, Default, Debug)]
|
#[derive(Copy, Clone, Default, Debug)]
|
||||||
pub struct Global;
|
pub struct Global;
|
||||||
|
|
||||||
|
@ -119,6 +116,7 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
|
||||||
__rust_alloc_zeroed(layout.size(), layout.align())
|
__rust_alloc_zeroed(layout.size(), layout.align())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
unsafe impl Alloc for Global {
|
unsafe impl Alloc for Global {
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
|
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
|
||||||
|
@ -188,6 +186,7 @@ pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
|
||||||
/// and abort the process.
|
/// and abort the process.
|
||||||
/// It can be replaced with [`std::alloc::set_oom_hook`]
|
/// It can be replaced with [`std::alloc::set_oom_hook`]
|
||||||
/// and [`std::alloc::take_oom_hook`].
|
/// and [`std::alloc::take_oom_hook`].
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[rustc_allocator_nounwind]
|
#[rustc_allocator_nounwind]
|
||||||
pub fn oom(layout: Layout) -> ! {
|
pub fn oom(layout: Layout) -> ! {
|
||||||
#[allow(improper_ctypes)]
|
#[allow(improper_ctypes)]
|
||||||
|
|
|
@ -10,12 +10,7 @@
|
||||||
|
|
||||||
//! Memory allocation APIs
|
//! Memory allocation APIs
|
||||||
|
|
||||||
#![unstable(feature = "allocator_api",
|
#![stable(feature = "alloc_module", since = "1.28.0")]
|
||||||
reason = "the precise API and guarantees it provides may be tweaked \
|
|
||||||
slightly, especially to possibly take into account the \
|
|
||||||
types being stored to make room for a future \
|
|
||||||
tracing garbage collector",
|
|
||||||
issue = "32838")]
|
|
||||||
|
|
||||||
use cmp;
|
use cmp;
|
||||||
use fmt;
|
use fmt;
|
||||||
|
@ -24,11 +19,13 @@ use usize;
|
||||||
use ptr::{self, NonNull};
|
use ptr::{self, NonNull};
|
||||||
use num::NonZeroUsize;
|
use num::NonZeroUsize;
|
||||||
|
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[cfg(stage0)]
|
#[cfg(stage0)]
|
||||||
pub type Opaque = u8;
|
pub type Opaque = u8;
|
||||||
|
|
||||||
/// Represents the combination of a starting address and
|
/// Represents the combination of a starting address and
|
||||||
/// a total capacity of the returned block.
|
/// a total capacity of the returned block.
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Excess(pub NonNull<u8>, pub usize);
|
pub struct Excess(pub NonNull<u8>, pub usize);
|
||||||
|
|
||||||
|
@ -49,6 +46,7 @@ fn size_align<T>() -> (usize, usize) {
|
||||||
/// requests have positive size. A caller to the `Alloc::alloc`
|
/// requests have positive size. A caller to the `Alloc::alloc`
|
||||||
/// method must either ensure that conditions like this are met, or
|
/// method must either ensure that conditions like this are met, or
|
||||||
/// use specific allocators with looser requirements.)
|
/// use specific allocators with looser requirements.)
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct Layout {
|
pub struct Layout {
|
||||||
// size of the requested block of memory, measured in bytes.
|
// size of the requested block of memory, measured in bytes.
|
||||||
|
@ -74,6 +72,7 @@ impl Layout {
|
||||||
/// * `size`, when rounded up to the nearest multiple of `align`,
|
/// * `size`, when rounded up to the nearest multiple of `align`,
|
||||||
/// must not overflow (i.e. the rounded value must be less than
|
/// must not overflow (i.e. the rounded value must be less than
|
||||||
/// `usize::MAX`).
|
/// `usize::MAX`).
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutErr> {
|
pub fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutErr> {
|
||||||
if !align.is_power_of_two() {
|
if !align.is_power_of_two() {
|
||||||
|
@ -109,20 +108,24 @@ impl Layout {
|
||||||
///
|
///
|
||||||
/// This function is unsafe as it does not verify the preconditions from
|
/// This function is unsafe as it does not verify the preconditions from
|
||||||
/// [`Layout::from_size_align`](#method.from_size_align).
|
/// [`Layout::from_size_align`](#method.from_size_align).
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
|
pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
|
||||||
Layout { size_: size, align_: NonZeroUsize::new_unchecked(align) }
|
Layout { size_: size, align_: NonZeroUsize::new_unchecked(align) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The minimum size in bytes for a memory block of this layout.
|
/// The minimum size in bytes for a memory block of this layout.
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn size(&self) -> usize { self.size_ }
|
pub fn size(&self) -> usize { self.size_ }
|
||||||
|
|
||||||
/// The minimum byte alignment for a memory block of this layout.
|
/// The minimum byte alignment for a memory block of this layout.
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn align(&self) -> usize { self.align_.get() }
|
pub fn align(&self) -> usize { self.align_.get() }
|
||||||
|
|
||||||
/// Constructs a `Layout` suitable for holding a value of type `T`.
|
/// Constructs a `Layout` suitable for holding a value of type `T`.
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new<T>() -> Self {
|
pub fn new<T>() -> Self {
|
||||||
let (size, align) = size_align::<T>();
|
let (size, align) = size_align::<T>();
|
||||||
|
@ -139,6 +142,7 @@ impl Layout {
|
||||||
/// Produces layout describing a record that could be used to
|
/// Produces layout describing a record that could be used to
|
||||||
/// allocate backing structure for `T` (which could be a trait
|
/// allocate backing structure for `T` (which could be a trait
|
||||||
/// or other unsized type like a slice).
|
/// or other unsized type like a slice).
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn for_value<T: ?Sized>(t: &T) -> Self {
|
pub fn for_value<T: ?Sized>(t: &T) -> Self {
|
||||||
let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
|
let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
|
||||||
|
@ -166,6 +170,7 @@ impl Layout {
|
||||||
/// Panics if the combination of `self.size()` and the given `align`
|
/// Panics if the combination of `self.size()` and the given `align`
|
||||||
/// violates the conditions listed in
|
/// violates the conditions listed in
|
||||||
/// [`Layout::from_size_align`](#method.from_size_align).
|
/// [`Layout::from_size_align`](#method.from_size_align).
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn align_to(&self, align: usize) -> Self {
|
pub fn align_to(&self, align: usize) -> Self {
|
||||||
Layout::from_size_align(self.size(), cmp::max(self.align(), align)).unwrap()
|
Layout::from_size_align(self.size(), cmp::max(self.align(), align)).unwrap()
|
||||||
|
@ -187,6 +192,7 @@ impl Layout {
|
||||||
/// to be less than or equal to the alignment of the starting
|
/// to be less than or equal to the alignment of the starting
|
||||||
/// address for the whole allocated block of memory. One way to
|
/// address for the whole allocated block of memory. One way to
|
||||||
/// satisfy this constraint is to ensure `align <= self.align()`.
|
/// satisfy this constraint is to ensure `align <= self.align()`.
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn padding_needed_for(&self, align: usize) -> usize {
|
pub fn padding_needed_for(&self, align: usize) -> usize {
|
||||||
let len = self.size();
|
let len = self.size();
|
||||||
|
@ -223,6 +229,7 @@ impl Layout {
|
||||||
/// of each element in the array.
|
/// of each element in the array.
|
||||||
///
|
///
|
||||||
/// On arithmetic overflow, returns `LayoutErr`.
|
/// On arithmetic overflow, returns `LayoutErr`.
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutErr> {
|
pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutErr> {
|
||||||
let padded_size = self.size().checked_add(self.padding_needed_for(self.align()))
|
let padded_size = self.size().checked_add(self.padding_needed_for(self.align()))
|
||||||
|
@ -248,6 +255,7 @@ impl Layout {
|
||||||
/// (assuming that the record itself starts at offset 0).
|
/// (assuming that the record itself starts at offset 0).
|
||||||
///
|
///
|
||||||
/// On arithmetic overflow, returns `LayoutErr`.
|
/// On arithmetic overflow, returns `LayoutErr`.
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
|
pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
|
||||||
let new_align = cmp::max(self.align(), next.align());
|
let new_align = cmp::max(self.align(), next.align());
|
||||||
|
@ -274,6 +282,7 @@ impl Layout {
|
||||||
/// aligned.
|
/// aligned.
|
||||||
///
|
///
|
||||||
/// On arithmetic overflow, returns `LayoutErr`.
|
/// On arithmetic overflow, returns `LayoutErr`.
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutErr> {
|
pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutErr> {
|
||||||
let size = self.size().checked_mul(n).ok_or(LayoutErr { private: () })?;
|
let size = self.size().checked_mul(n).ok_or(LayoutErr { private: () })?;
|
||||||
|
@ -295,6 +304,7 @@ impl Layout {
|
||||||
/// `extend`.)
|
/// `extend`.)
|
||||||
///
|
///
|
||||||
/// On arithmetic overflow, returns `LayoutErr`.
|
/// On arithmetic overflow, returns `LayoutErr`.
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn extend_packed(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
|
pub fn extend_packed(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
|
||||||
let new_size = self.size().checked_add(next.size())
|
let new_size = self.size().checked_add(next.size())
|
||||||
|
@ -306,6 +316,7 @@ impl Layout {
|
||||||
/// Creates a layout describing the record for a `[T; n]`.
|
/// Creates a layout describing the record for a `[T; n]`.
|
||||||
///
|
///
|
||||||
/// On arithmetic overflow, returns `LayoutErr`.
|
/// On arithmetic overflow, returns `LayoutErr`.
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn array<T>(n: usize) -> Result<Self, LayoutErr> {
|
pub fn array<T>(n: usize) -> Result<Self, LayoutErr> {
|
||||||
Layout::new::<T>()
|
Layout::new::<T>()
|
||||||
|
@ -320,12 +331,14 @@ impl Layout {
|
||||||
/// The parameters given to `Layout::from_size_align`
|
/// The parameters given to `Layout::from_size_align`
|
||||||
/// or some other `Layout` constructor
|
/// or some other `Layout` constructor
|
||||||
/// do not satisfy its documented constraints.
|
/// do not satisfy its documented constraints.
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
pub struct LayoutErr {
|
pub struct LayoutErr {
|
||||||
private: ()
|
private: ()
|
||||||
}
|
}
|
||||||
|
|
||||||
// (we need this for downstream impl of trait Error)
|
// (we need this for downstream impl of trait Error)
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
impl fmt::Display for LayoutErr {
|
impl fmt::Display for LayoutErr {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.write_str("invalid parameters to Layout::from_size_align")
|
f.write_str("invalid parameters to Layout::from_size_align")
|
||||||
|
@ -336,10 +349,12 @@ impl fmt::Display for LayoutErr {
|
||||||
/// that may be due to resource exhaustion or to
|
/// that may be due to resource exhaustion or to
|
||||||
/// something wrong when combining the given input arguments with this
|
/// something wrong when combining the given input arguments with this
|
||||||
/// allocator.
|
/// allocator.
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
pub struct AllocErr;
|
pub struct AllocErr;
|
||||||
|
|
||||||
// (we need this for downstream impl of trait Error)
|
// (we need this for downstream impl of trait Error)
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
impl fmt::Display for AllocErr {
|
impl fmt::Display for AllocErr {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.write_str("memory allocation failed")
|
f.write_str("memory allocation failed")
|
||||||
|
@ -350,9 +365,11 @@ impl fmt::Display for AllocErr {
|
||||||
/// `shrink_in_place` were unable to reuse the given memory block for
|
/// `shrink_in_place` were unable to reuse the given memory block for
|
||||||
/// a requested layout.
|
/// a requested layout.
|
||||||
// FIXME: should this be in libcore or liballoc?
|
// FIXME: should this be in libcore or liballoc?
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
pub struct CannotReallocInPlace;
|
pub struct CannotReallocInPlace;
|
||||||
|
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
impl CannotReallocInPlace {
|
impl CannotReallocInPlace {
|
||||||
pub fn description(&self) -> &str {
|
pub fn description(&self) -> &str {
|
||||||
"cannot reallocate allocator's memory in place"
|
"cannot reallocate allocator's memory in place"
|
||||||
|
@ -360,6 +377,7 @@ impl CannotReallocInPlace {
|
||||||
}
|
}
|
||||||
|
|
||||||
// (we need this for downstream impl of trait Error)
|
// (we need this for downstream impl of trait Error)
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
impl fmt::Display for CannotReallocInPlace {
|
impl fmt::Display for CannotReallocInPlace {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{}", self.description())
|
write!(f, "{}", self.description())
|
||||||
|
@ -449,6 +467,7 @@ impl From<LayoutErr> for CollectionAllocErr {
|
||||||
/// * `Layout` queries and calculations in general must be correct. Callers of
|
/// * `Layout` queries and calculations in general must be correct. Callers of
|
||||||
/// this trait are allowed to rely on the contracts defined on each method,
|
/// this trait are allowed to rely on the contracts defined on each method,
|
||||||
/// and implementors must ensure such contracts remain true.
|
/// and implementors must ensure such contracts remain true.
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
pub unsafe trait GlobalAlloc {
|
pub unsafe trait GlobalAlloc {
|
||||||
/// Allocate memory as described by the given `layout`.
|
/// Allocate memory as described by the given `layout`.
|
||||||
///
|
///
|
||||||
|
@ -664,6 +683,7 @@ pub unsafe trait GlobalAlloc {
|
||||||
///
|
///
|
||||||
/// Note that this list may get tweaked over time as clarifications are made in
|
/// Note that this list may get tweaked over time as clarifications are made in
|
||||||
/// the future.
|
/// the future.
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
pub unsafe trait Alloc {
|
pub unsafe trait Alloc {
|
||||||
|
|
||||||
// (Note: some existing allocators have unspecified but well-defined
|
// (Note: some existing allocators have unspecified but well-defined
|
||||||
|
|
|
@ -10,17 +10,20 @@
|
||||||
|
|
||||||
//! Memory allocation APIs
|
//! Memory allocation APIs
|
||||||
|
|
||||||
#![unstable(issue = "32838", feature = "allocator_api")]
|
#![stable(feature = "alloc_module", since = "1.28.0")]
|
||||||
|
|
||||||
#[doc(inline)] pub use alloc_crate::alloc::{Global, Layout, oom};
|
|
||||||
#[doc(inline)] pub use alloc_crate::alloc::{alloc, alloc_zeroed, dealloc, realloc};
|
|
||||||
#[doc(inline)] pub use alloc_system::System;
|
|
||||||
#[doc(inline)] pub use core::alloc::*;
|
|
||||||
|
|
||||||
use core::sync::atomic::{AtomicPtr, Ordering};
|
use core::sync::atomic::{AtomicPtr, Ordering};
|
||||||
use core::{mem, ptr};
|
use core::{mem, ptr};
|
||||||
use sys_common::util::dumb_print;
|
use sys_common::util::dumb_print;
|
||||||
|
|
||||||
|
#[stable(feature = "alloc_module", since = "1.28.0")]
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use alloc_crate::alloc::*;
|
||||||
|
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use alloc_system::System;
|
||||||
|
|
||||||
static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut());
|
static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut());
|
||||||
|
|
||||||
/// Registers a custom OOM hook, replacing any that was previously registered.
|
/// Registers a custom OOM hook, replacing any that was previously registered.
|
||||||
|
@ -34,6 +37,7 @@ static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut());
|
||||||
/// about the allocation that failed.
|
/// about the allocation that failed.
|
||||||
///
|
///
|
||||||
/// The OOM hook is a global resource.
|
/// The OOM hook is a global resource.
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
pub fn set_oom_hook(hook: fn(Layout)) {
|
pub fn set_oom_hook(hook: fn(Layout)) {
|
||||||
HOOK.store(hook as *mut (), Ordering::SeqCst);
|
HOOK.store(hook as *mut (), Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
@ -43,6 +47,7 @@ pub fn set_oom_hook(hook: fn(Layout)) {
|
||||||
/// *See also the function [`set_oom_hook`].*
|
/// *See also the function [`set_oom_hook`].*
|
||||||
///
|
///
|
||||||
/// If no custom hook is registered, the default hook will be returned.
|
/// If no custom hook is registered, the default hook will be returned.
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
pub fn take_oom_hook() -> fn(Layout) {
|
pub fn take_oom_hook() -> fn(Layout) {
|
||||||
let hook = HOOK.swap(ptr::null_mut(), Ordering::SeqCst);
|
let hook = HOOK.swap(ptr::null_mut(), Ordering::SeqCst);
|
||||||
if hook.is_null() {
|
if hook.is_null() {
|
||||||
|
@ -59,6 +64,7 @@ fn default_oom_hook(layout: Layout) {
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[lang = "oom"]
|
#[lang = "oom"]
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
pub extern fn rust_oom(layout: Layout) -> ! {
|
pub extern fn rust_oom(layout: Layout) -> ! {
|
||||||
let hook = HOOK.load(Ordering::SeqCst);
|
let hook = HOOK.load(Ordering::SeqCst);
|
||||||
let hook: fn(Layout) = if hook.is_null() {
|
let hook: fn(Layout) = if hook.is_null() {
|
||||||
|
@ -73,6 +79,7 @@ pub extern fn rust_oom(layout: Layout) -> ! {
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[allow(unused_attributes)]
|
#[allow(unused_attributes)]
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
pub mod __default_lib_allocator {
|
pub mod __default_lib_allocator {
|
||||||
use super::{System, Layout, GlobalAlloc};
|
use super::{System, Layout, GlobalAlloc};
|
||||||
// for symbol names src/librustc/middle/allocator.rs
|
// for symbol names src/librustc/middle/allocator.rs
|
||||||
|
|
|
@ -18,6 +18,11 @@
|
||||||
mod cross_crate {
|
mod cross_crate {
|
||||||
extern crate lint_stability_fields;
|
extern crate lint_stability_fields;
|
||||||
|
|
||||||
|
mod reexport {
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
pub use super::lint_stability_fields::*;
|
||||||
|
}
|
||||||
|
|
||||||
use self::lint_stability_fields::*;
|
use self::lint_stability_fields::*;
|
||||||
|
|
||||||
pub fn foo() {
|
pub fn foo() {
|
||||||
|
@ -73,6 +78,8 @@ mod cross_crate {
|
||||||
// the patterns are all fine:
|
// the patterns are all fine:
|
||||||
{ .. } = x;
|
{ .. } = x;
|
||||||
|
|
||||||
|
// Unstable items are still unstable even when used through a stable "pub use".
|
||||||
|
let x = reexport::Unstable2(1, 2, 3); //~ ERROR use of unstable
|
||||||
|
|
||||||
let x = Unstable2(1, 2, 3); //~ ERROR use of unstable
|
let x = Unstable2(1, 2, 3); //~ ERROR use of unstable
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue