SILGen: Don't use diagnoseUnexpectedEnumCase intrinsic for noncopyable enums.

It should be impossible to reach an unexpected case statically while using
noncopyable enums, and the intrinsic has not been updated to remove its
`Copyable` requirement. Emit a plain trap in cases where this code emission
path might still occur, such as when a redundant but incomplete set of case
patterns follow a wildcard pattern. Fixes rdar://130037881.
This commit is contained in:
Joe Groff
2024-06-17 14:19:19 -10:00
parent b7b93a12a0
commit e3fef32a9b
2 changed files with 24 additions and 0 deletions

View File

@@ -3109,6 +3109,13 @@ static void emitDiagnoseOfUnexpectedEnumCaseValue(SILGenFunction &SGF,
static void emitDiagnoseOfUnexpectedEnumCase(SILGenFunction &SGF,
SILLocation loc,
UnexpectedEnumCaseInfo ueci) {
if (ueci.subjectTy->isNoncopyable()) {
// TODO: The DiagnoseUnexpectedEnumCase intrinsic currently requires a
// Copyable parameter. For noncopyable enums it should be impossible to
// reach an unexpected case statically, so just emit a trap for now.
SGF.B.createUnconditionalFail(loc, "unexpected enum case");
return;
}
ASTContext &ctx = SGF.getASTContext();
auto diagnoseFailure = ctx.getDiagnoseUnexpectedEnumCase();
if (!diagnoseFailure) {

View File

@@ -0,0 +1,17 @@
// RUN: %target-swift-emit-silgen -verify %s
struct NC: ~Copyable {}
enum NoncopyableEnum: ~Copyable {
case copyable(Int)
case noncopyable(NC)
}
func test(foo: consuming NoncopyableEnum) {
switch foo {
case let x: // expected-warning{{'x' was never used}}
break
case .copyable(let x): // expected-warning{{already handled by previous patterns}} expected-warning{{'x' was never used}}
break
}
}