Rollup merge of #155280 - Zalathar:opaque-capture-bug, r=JonathanBrouwer

Tests for precise-capture through RPIT and TAIT

- Tests for https://github.com/rust-lang/rust/issues/155151.

These tests succeed under `-Znext-solver`, but incorrectly fail under the old trait solver.

---

The bug can be triggered via return-position `impl Trait` on stable, but requires some rather contrived code. When using type-alias `impl Trait`, it's easier to imagine the issue being triggered by real code.
This commit is contained in:
Jacob Pratt
2026-04-14 23:02:35 -04:00
committed by GitHub
4 changed files with 70 additions and 0 deletions
@@ -0,0 +1,12 @@
error[E0381]: used binding `x` isn't initialized
--> $DIR/precise-capture-155151.rs:19:22
|
LL | let Foo { x } = foo;
| - binding declared here but left uninitialized
...
LL | let _y = x;
| ^ `x` used here but it isn't initialized
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0381`.
@@ -0,0 +1,24 @@
#![crate_type = "rlib"]
//@ revisions: current next
//@ edition: 2021
//@[current] known-bug: #155151
//@[current] check-fail
//@[next] compile-flags: -Znext-solver
//@[next] check-pass
pub fn wut() -> impl Sized {
struct Foo { x: u32 }
if false {
// `foo` has an opaque type, but this function knows that it's `Foo`.
let foo = wut();
let _closure = move || {
let Foo { x } = foo;
// `x` should have been captured, but under old-solver the compiler
// thinks it's uninitialized here.
let _y = x;
};
}
Foo { x: 7 }
}
@@ -0,0 +1,12 @@
error[E0381]: used binding `x` isn't initialized
--> $DIR/precise-capture-155151.rs:20:18
|
LL | let Foo { x } = foo;
| - binding declared here but left uninitialized
...
LL | let _y = x;
| ^ `x` used here but it isn't initialized
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0381`.
@@ -0,0 +1,22 @@
#![feature(type_alias_impl_trait)]
//@ revisions: current next
//@ edition: 2021
//@[current] known-bug: #155151
//@[current] check-fail
//@[next] compile-flags: -Znext-solver
//@[next] check-pass
fn main() {
struct Foo { x: u32 }
type T = impl Sized;
// `foo` has an opaque type, but this function knows that it's `Foo`.
let foo: T = Foo { x: 7 };
let _closure = move || {
let Foo { x } = foo;
// `x` should have been captured, but under old-solver the compiler
// thinks it's uninitialized here.
let _y = x;
};
}