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#4720: Add lang pin/unpin

Link: Rust-GCC/gccrs#4720

Definition:

#![allow(unused)]
fn main() {
#[stable(feature = "pin", since = "1.33.0")]
#[lang = "pin"]
#[fundamental]
#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct Pin<P> {
    pointer: P,
}
}
#![allow(unused)]
fn main() {
#[stable(feature = "pin", since = "1.33.0")]
#[rustc_on_unimplemented(
    on(_Self = "std::future::Future", note = "consider using `Box::pin`",),
    message = "`{Self}` cannot be unpinned"
)]
#[lang = "unpin"]
pub auto trait Unpin {}
}

Objective

This patch adds the pin and unpin lang items to the compiler.

Changes Made

Registered the lang items. Full behavioral testing is currently blocked due to upstream issues #4709 and #4678. Therefore, the validation in this patch specifically targets auto-trait behavior and negative implementations (!Unpin).

Why is this needed for alloc?

Pin and Unpin are essential for safely working with self-referential structures and Futures. The alloc crate provides implementations for pinning heap-allocated objects (e.g., Box::pin), making these lang items a prerequisite.

Test Case

use std::marker::PhantomPinned;
use std::pin::Pin;

struct PinnedStruct {
    _marker: PhantomPinned,
}

struct NormalStruct;

fn main() {
    let normal = NormalStruct;
    let _ = Pin::new(&normal);
    println!("valid");

    let pinned = PinnedStruct { _marker: PhantomPinned };

    // uncomment the line below to see the bound error
    // let _ = Pin::new(&pinned);
}

This test demonstrates that the compiler correctly enforces negative trait bounds (!Unpin) when attempting to pin a type that explicitly opts out of it.