diff --git a/lib/SILGen/SILGenPattern.cpp b/lib/SILGen/SILGenPattern.cpp index a201c94989b1d..18b31b4efb4d0 100644 --- a/lib/SILGen/SILGenPattern.cpp +++ b/lib/SILGen/SILGenPattern.cpp @@ -3500,7 +3500,7 @@ void SILGenFunction::emitSwitchStmt(SwitchStmt *S) { // exits out of the switch. // // When we break out of a case block, we take the subject's remnants with us - // in the former case, but not the latter.q + // in the former case, but not the latter. CleanupsDepth subjectDepth = Cleanups.getCleanupsDepth(); LexicalScope switchScope(*this, CleanupLocation(S)); std::optional switchFormalAccess; @@ -3563,6 +3563,10 @@ void SILGenFunction::emitSwitchStmt(SwitchStmt *S) { } case ValueOwnership::Owned: { // A consuming pattern match. Emit as a +1 rvalue. + // Create a tight evaluation scope for temporary borrows emitted during the + // evaluation. + FormalEvaluationScope limitedScope(*this); + subjectMV = emitRValueAsSingleValue(S->getSubjectExpr()); break; } diff --git a/test/SILGen/switch_noncopyable_consumed_subject_with_open_existential.swift b/test/SILGen/switch_noncopyable_consumed_subject_with_open_existential.swift new file mode 100644 index 0000000000000..30f381d85a8b9 --- /dev/null +++ b/test/SILGen/switch_noncopyable_consumed_subject_with_open_existential.swift @@ -0,0 +1,17 @@ +// RUN: %target-swift-emit-silgen -verify %s + +func fooify(p: any P) { + switch p.foo() { + case .success: + break + } +} + +enum Resoult: ~Copyable { + case success +} + +protocol P { + func foo() -> Resoult +} +