TAIT + next-solver will allow constructing a unit struct without mentioning its type, causing `pinned-init` to be unsound.
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
I have also described this issue at https://github.com/rust-lang/rfcs/pull/3444#issuecomment-4016145373
The pinned-init crate has a macro whose soundness relies on having a type that cannot be constructed outside the macro, due to the type's name being impossible to mention.
The TAIT feature, along with the next-solver, allows writing a struct literal without mentioning the type name.
Therefore, TAIT with the next-solver will cause the pinned-init crate to become unsound.
The below code creates an uninitialized Box<i32> with the pinned-init crate version 0.0.10, and with the -Znext-solver flag enabled. It causes a segmentation fault in my testing.
#![feature(type_alias_impl_trait)]
use std::pin::Pin;
use pinned_init::{init, stack_pin_init};
struct Thing<T> {
field: T,
}
fn conjure<T>() -> T {
panic!()
}
#[expect(unreachable_code, unused_variables)]
fn make_uninit<T: Unpin>(dummy: T) -> T {
let initializer = init!(Thing {
field <- {
return Ok('block: {
// This type will end up being inferred to be the unnamable `__InitOk` type defined in the `init!` macro
type InferredType = impl Sized;
if false {
let fake_value: InferredType = loop {};
break 'block fake_value;
}
InferredType {}
});
conjure::<T>()
}
});
stack_pin_init!(let pinned_value = initializer);
let mut pinned_value: Pin<&mut Thing<T>> = pinned_value;
let mut_value: &mut T = &mut pinned_value.field;
std::mem::replace(mut_value, dummy)
}
fn main() {
println!("{}", make_uninit::<Box<i32>>(Box::new(1)));
}
cc @rust-lang/rust-for-linux (owner of the pinned-init crate)
cc @lcnr
Meta
rustc --version --verbose:
rustc 1.96.0-nightly (80282b130 2026-03-06)
binary: rustc
commit-hash: 80282b130679a654eaa22f028a908c51be53d436
commit-date: 2026-03-06
host: x86_64-pc-windows-msvc
release: 1.96.0-nightly
LLVM version: 22.1.0
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the provided pinned-init example with -Znext-solver, then inspect the init! macro in pinned_init/macros.rs alongside TAIT handling and the next-solver behavior described in issues #63063 and RFC PR #3444. Done means the interaction no longer permits the unsound construction, with coverage for the demonstrated case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100