Skip to content

TAIT + next-solver will allow constructing a unit struct without mentioning its type, causing pinned-init to be unsound. #153535

@theemathas

Description

@theemathas

I have also described this issue at rust-lang/rfcs#3444 (comment)

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.A-inferenceArea: Type inferenceA-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)A-rust-for-linuxRelevant for the Rust-for-Linux projectC-bugCategory: This is a bug.F-type_alias_impl_trait`#[feature(type_alias_impl_trait)]`I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-langRelevant to the language teamT-typesRelevant to the types team, which will review and decide on the PR/issue.WG-trait-system-refactorThe Rustc Trait System Refactor Initiative (-Znext-solver)

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions