Repository navigation
Field within opaque type is not captured by closure under old solver #155151
Description
Activity
- addedneeds-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triagingThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
on Apr 11, 2026 The failure only occurs under edition 2021 or later (since it requires precise-capture), and does not occur under
-Znext-solver.Triggering this issue without TAIT requires some pretty contrived code, but with TAIT it's a lot more plausible:
rust/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs
Lines 15 to 24 in c29effd
fn upvar() { #[derive(Copy, Clone)] struct Foo((u32, u32)); type T = impl Copy; let foo: T = Foo((1u32, 2u32)); let x = move || { let Foo((a, b)) = foo; }; } This existing test currently doesn't trigger the bug, but actually using
aorbin the closure would produce a similar error.Possibly related to #119786. cc @meithecatte
- addedA-closuresArea: Closures (`|…| { … }`)Area: Closures (`|…| { … }`)A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.A-patternsRelating to patterns and pattern matchingRelating to patterns and pattern matchingT-typesRelevant to the types team, which will review and decide on the PR/issue.Relevant to the types team, which will review and decide on the PR/issue.fixed-by-next-solverFixed by the next-generation trait solver, `-Znext-solver`.Fixed by the next-generation trait solver, `-Znext-solver`.and removedneeds-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triagingThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
on Apr 11, 2026 For additional background, I noticed the issue while looking into situations where this code fails to create a binding for a
PatKind::Bindingnode, becauseplaceis None:rust/compiler/rustc_mir_build/src/builder/matches/match_pair.rs
Lines 218 to 227 in bf4fbfb
// Then push this binding, after any bindings in the subpattern. if let Some(source) = place { extra_data.bindings.push(super::SubpatternBindings::One(super::Binding { span: pattern.span, source, var_id: var, binding_mode: mode, is_shorthand, })); } - added a commit that references this issue
on Apr 15, 2026 - added a commit that references this issue
on Sep 20, 2026
I tried this code:
(Thanks to @theemathas for a minimization not requiring TAIT.)
I expected to see this happen: Compiles successfully.
Instead, this happened:
Meta
(Tested on playground with stable 1.94.1 and nightly 1.96.)