Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

gccrs#4721: Register lang items for alloc crate

Link: Rust-GCC/gccrs#4721

Definitions:

#![allow(unused)]
fn main() {
#[cfg(all(bootstrap, not(test)))]
#[stable(feature = "global_alloc", since = "1.28.0")]
#[rustc_allocator_nounwind]
pub fn handle_alloc_error(layout: Layout) -> ! {
    extern "Rust" {
        #[lang = "oom"]
        fn oom_impl(layout: Layout) -> !;
    }
    unsafe { oom_impl(layout) }
}
}
#![allow(unused)]
fn main() {
#[stable(feature = "alloc_layout", since = "1.28.0")]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[lang = "alloc_layout"]
pub struct Layout {
    size_: usize,

    align_: NonZeroUsize,
}
}
#![allow(unused)]
fn main() {
#[cfg_attr(not(test), lang = "box_free")]
#[inline]
pub(crate) unsafe fn box_free<T: ?Sized, A: AllocRef>(ptr: Unique<T>, alloc: A) {
    unsafe {
        let size = size_of_val(ptr.as_ref());
        let align = min_align_of_val(ptr.as_ref());
        let layout = Layout::from_size_align_unchecked(size, align);
        alloc.dealloc(ptr.cast().into(), layout)
    }
}
}
#![allow(unused)]
fn main() {
#[stable(feature = "drop_in_place", since = "1.8.0")]
#[lang = "drop_in_place"]
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
    // Code here does not matter - this is replaced by the
    // real drop glue by the compiler.

    // SAFETY: see comment above
    unsafe { drop_in_place(to_drop) }
}
}
#![allow(unused)]
fn main() {
#[stable(feature = "maybe_uninit", since = "1.36.0")]
// Lang item so we can wrap other types in it. This is useful for generators.
#[lang = "maybe_uninit"]
#[derive(Copy)]
#[repr(transparent)]
pub union MaybeUninit<T> {
    uninit: (),
    value: ManuallyDrop<T>,
}
}
#![allow(unused)]
fn main() {
#[stable(feature = "futures_api", since = "1.36.0")]
#[lang = "future_trait"]
pub trait Future {
    #[stable(feature = "futures_api", since = "1.36.0")]
    type Output;

    #[lang = "poll"]
    #[stable(feature = "futures_api", since = "1.36.0")]
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}
}
#![allow(unused)]
fn main() {
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub enum Poll<T> {
    /// Represents that a value is immediately ready.
    #[lang = "Ready"]
    #[stable(feature = "futures_api", since = "1.36.0")]
    Ready(#[stable(feature = "futures_api", since = "1.36.0")] T),

    #[lang = "Pending"]
    #[stable(feature = "futures_api", since = "1.36.0")]
    Pending,
}

}
#![allow(unused)]
fn main() {
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
#[lang = "generator_state"]
#[unstable(feature = "generator_trait", issue = "43122")]
pub enum GeneratorState<Y, R> {
    Yielded(Y),
    Complete(R),
}

#[lang = "generator"]
#[unstable(feature = "generator_trait", issue = "43122")]
#[fundamental]
pub trait Generator<R = ()> {
    type Return;

    fn resume(self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return>;
}
}

Objective

This PR registers several lang items as stubs, acting as a crucial stepping stone to unblock the compilation of the alloc crate.

Changes Made

  • oom, alloc_layout: Require no specific handling; symbol generation is sufficient.
  • box_free, drop_in_place: Full implementation requires a mature drop infrastructure. Registered as a stub for now.
  • maybe_uninit: Requires layout engine maturity and niche-filling mechanisms. Registered as a stub.
  • future_trait, poll, Ready, Pending: Registered as stubs due to lack of async support.
  • generator, generator_state: Registered as stubs due to lack of generator support.

Note: The Ready and Pending lang items are excluded from the test cases because lang item attributes on enum variants are not currently handled by the compiler (see #4703).

Why is this needed for alloc?

The standard alloc crate contains definitions for memory layout handling, out-of-memory states, dropping mechanics, and foundational async traits (Future, Generator). Providing these stubs satisfies the compiler’s symbol and attribute resolution, allowing the parser and type checker to process the alloc crate without throwing unknown attribute errors.

Test Case

#![allow(unused)]
fn main() {
#[lang = "future_trait"]
pub trait Future {
    #[lang = "poll"]
    fn poll() {}
}

#[lang = "generator"]
pub trait Generator {}

#[lang = "generator_state"]
pub enum GeneratorState {}

#[lang = "box_free"]
pub fn _box_free() {}

#[repr(transparent)]
pub struct ManuallyDrop<T: ?Sized> {
    _value: T,
}

#[lang = "maybe_uninit"]
#[repr(transparent)]
pub union MaybeUninit<T> {
    uninit: (),
    value: ManuallyDrop<T>,
}

#[lang = "drop_in_place"]
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {}

// ---

#[lang = "alloc_layout"]
pub struct Layout;

#[lang = "oom"]
pub fn _oom() {}
}