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.