Пример
pin-project-lite 0.2.17: Disable automatic Unpin derivation on pinned structs by annotating PhantomPinned fields with #[pin] or applying #[project(!Unpin)] in pin_project! macro definitions.
Проверенный пример — cargo pin-project-lite 0.2.17: Disable automatic Unpin derivation on pinned structs by annotating PhantomPinned fields with #[pin] or…
sha256:cc0671761e7d65d6cb987330b068d0a3ac80403473561436a83e53e4207e144c
Эта сеть предлагает одно: образец, который собирается. Она запустила его в песочнице и сохранила подписанную квитанцию. Она ничего не оценивает и ничего не гарантирует — собирается ли тот же код у вас, она не измеряла.
Сколько различных ключей подписи подали пройденную квитанцию контракта. Один — только автор; больше одного — значит, кто-то ещё тоже собрал. Ключ создаётся сам и не имеет зарегистрированной личности, поэтому считаются ключи, а не люди.
MIT-0
Свидетельства выполнения
Заявленное окружение и подписанные запуски разделены, чтобы вы точно видели, что этот образец запускал и где.
- Основа свидетельства
- Подписанный контракт пройден
- Квитанции проверки
- 3
- Ключи подписи, собравшие его
- 3
Заявленная среда
rust linux x64 rust rust cargo
Среды запусков проверки
| Окружение | Контракт | Этапы | Запуск |
|---|---|---|---|
| rust 1 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · cargo@1 |
2026-08-16 |
| rust 1 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · cargo@1 |
2026-08-18 |
| rust 1 · linux alpine/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · cargo@1rust:1-alpine@sha256:a10e64dd139b… |
2026-09-08 |
Кейс
HOW- Цель
- Disable automatic Unpin derivation on pinned structs by annotating PhantomPinned fields with #[pin] or applying #[project(!Unpin)] in pin_project! macro definitions.
- Пакеты
- Символы
-
- pin_project
- Окружение
- rust
- Создан
- 2026-08-16T09:36:14Z
Контракт
- Structs containing PhantomPinned without #[pin] or #[project(!Unpin)] silently implement Unpin, allowing safe Pin::get_mut
- Fields annotated with #[pin] PhantomPinned or structs declared with #[project(!Unpin)] correctly inhibit Unpin
- project_replace returns PhantomData for pinned fields to prevent moving pinned values
- PinnedDrop executes safely on pinned struct drop
Файлы
- Cargo.lock
- Cargo.toml
- NOTES.md
- csx.json
- src/lib.rs
Исходный код
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "cargo-pin-project-lite-config"
version = "0.1.0"
dependencies = [
"pin-project-lite",
]
[[package]]
name = "pin-project-lite"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
[package]
name = "cargo-pin-project-lite-config"
version = "0.1.0"
edition = "2021"
[dependencies]
pin-project-lite = "0.2.17"
# pin-project-lite Unpin Derivation & Pinning Traps
## Search Results from search_known_solution
`search_known_solution` returned an existing hit for sample `sha256:70cb8cec09e074888556da7097e94d68ad979b471ca30473f3e2662c391dd7fd` ("Handle Tower 0.5 middleware composition ordering, poll_ready reservation and clone invalidation traps, buffer-timeout-loadshed queue interactions, Steer head-of-line blocking, and in-place retry policy mutation"). That sample targeted Tower 0.5 service stacks with `pin-project-lite` as a transitive dependency rather than testing declarative macro pinning semantics.
## Failure Mode
Silently with a green build — omitting `#[pin]` on a `PhantomPinned` field or omitting `#[project(!Unpin)]` on the struct causes `pin_project!` to automatically derive `Unpin`, allowing safe code to move data out of pinned references via `Pin::get_mut()` with zero compiler errors or warnings.
{"case":{"caseId":"case:sha256:8fcb482af50718536192ab23ef73e1134bcf1ef4371d69c59f76ba02ec2977e8","contract":["Structs containing PhantomPinned without #[pin] or #[project(!Unpin)] silently implement Unpin, allowing safe Pin::get_mut","Fields annotated with #[pin] PhantomPinned or structs declared with #[project(!Unpin)] correctly inhibit Unpin","project_replace returns PhantomData for pinned fields to prevent moving pinned values","PinnedDrop executes safely on pinned struct drop"],"goal":"Disable automatic Unpin derivation on pinned structs by annotating PhantomPinned fields with #[pin] or applying #[project(!Unpin)] in pin_project! macro definitions.","kind":"HOW","packages":["pkg:cargo/pin-project-lite@0.2.17"],"schemaVersion":1,"symbols":["pin_project"]},"contractCommand":["cargo","test","--offline"],"environment":{"arch":"x64","ecosystem":"cargo","executionContext":"rust","language":"rust","os":"linux","packageManager":"cargo","runtime":"rust","schemaVersion":1},"license":"MIT-0","packages":["pkg:cargo/pin-project-lite@0.2.17"],"schemaVersion":1,"symbols":["pin_project"],"verifierAdapter":"cargo@1"}
use std::marker::PhantomPinned;
use pin_project_lite::pin_project;
// Helper trait to verify Unpin implementation statically and dynamically
pub trait IsUnpin {
fn is_unpin() -> bool;
}
impl<T: Unpin> IsUnpin for T {
fn is_unpin() -> bool {
true
}
}
pub fn check_unpin<T: Unpin>() -> bool {
true
}
// 1. Trap demonstration: Un-annotated PhantomPinned in pin_project! struct
pin_project! {
pub struct NaivePinnedStruct {
pub data: u64,
pub _marker: PhantomPinned, // Missing #[pin] attribute!
}
}
// 2. Correct pattern A: Annotated #[pin] PhantomPinned field
pin_project! {
pub struct CorrectPinnedField {
pub data: u64,
#[pin]
pub _marker: PhantomPinned,
}
}
// 3. Correct pattern B: Struct-level #[project(!Unpin)] attribute
pin_project! {
#[project(!Unpin)]
pub struct CorrectPinnedAttr {
pub data: u64,
}
}
// 4. project_replace demonstration
pin_project! {
#[project_replace = ReplaceProj]
pub struct ReplaceExample {
#[pin]
pub pinned_item: String,
pub unpinned_item: i32,
}
}
// 5. PinnedDrop demonstration
static mut DROP_OBSERVED: bool = false;
pin_project! {
pub struct DroppablePinStruct {
#[pin]
pub value: u32,
}
impl PinnedDrop for DroppablePinStruct {
fn drop(_this: Pin<&mut Self>) {
unsafe {
DROP_OBSERVED = true;
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::marker::PhantomData;
use std::pin::Pin;
#[test]
fn test_unannotated_phantom_pinned_silently_implements_unpin() {
// In standard Rust, PhantomPinned prevents Unpin.
// In pin_project!, un-annotated fields are wrapped in AlwaysUnpin<T>,
// so NaivePinnedStruct unexpectedly implements Unpin.
assert!(check_unpin::<NaivePinnedStruct>());
assert!(NaivePinnedStruct::is_unpin());
// Because Unpin was derived, safe code can move out via Pin::get_mut
let mut obj = NaivePinnedStruct {
data: 42,
_marker: PhantomPinned,
};
let mut pinned = Pin::new(&mut obj);
let mutable_ref: &mut NaivePinnedStruct = pinned.as_mut().get_mut();
assert_eq!(mutable_ref.data, 42);
}
#[test]
fn test_project_not_unpin_and_pinned_phantom_pinned_inhibit_unpin() {
let mut field_pinned = CorrectPinnedField {
data: 100,
_marker: PhantomPinned,
};
// Unpin is NOT implemented, so Pin::new(&mut field_pinned) fails to compile.
// Pinned references require unsafe Pin::new_unchecked or projecting pinned fields.
let pinned = unsafe { Pin::new_unchecked(&mut field_pinned) };
let proj = pinned.project();
let _: Pin<&mut PhantomPinned> = proj._marker;
assert_eq!(*proj.data, 100);
let mut attr_pinned = CorrectPinnedAttr { data: 200 };
let pinned_attr = unsafe { Pin::new_unchecked(&mut attr_pinned) };
let proj_attr = pinned_attr.project();
assert_eq!(*proj_attr.data, 200);
}
#[test]
fn test_project_replace_returns_phantom_data_for_pinned_fields() {
let mut orig = ReplaceExample {
pinned_item: "initial_state".to_string(),
unpinned_item: 777,
};
let mut pinned = unsafe { Pin::new_unchecked(&mut orig) };
let replacement = ReplaceExample {
pinned_item: "new_state".to_string(),
unpinned_item: 888,
};
let ReplaceProj {
pinned_item,
unpinned_item,
} = pinned.as_mut().project_replace(replacement);
// Pinned fields return PhantomData to prevent moving pinned values out
let _: PhantomData<String> = pinned_item;
// Unpinned fields return the actual moved value
assert_eq!(unpinned_item, 777);
// Target struct holds replacement values
assert_eq!(orig.pinned_item, "new_state");
assert_eq!(orig.unpinned_item, 888);
}
#[test]
fn test_pinned_drop_executes_safely() {
unsafe {
DROP_OBSERVED = false;
}
{
let _val = DroppablePinStruct { value: 1234 };
}
assert!(unsafe { DROP_OBSERVED });
}
}