From cd2daa931ffce7299b991925d3590049103ba3b9 Mon Sep 17 00:00:00 2001 From: Matt Diephouse Date: Mon, 22 Oct 2018 06:46:46 -0400 Subject: [PATCH] Fix assertion from empty switch over uninhabited enum Fixes SR-8933. Swift's uninhabited checking is conservative. An enum might not be found to be uninhabited, but all of its cases might. In that case, the switch can be empty even though the type isn't known to be uninhabited. Fix an assertion that assumed there would always be at least one case for types that aren't known to be uninhabited. --- lib/SILGen/SILGenPattern.cpp | 5 +++++ test/Sema/exhaustive_switch.swift | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/lib/SILGen/SILGenPattern.cpp b/lib/SILGen/SILGenPattern.cpp index 8944c4550254e..985c96e9bd967 100644 --- a/lib/SILGen/SILGenPattern.cpp +++ b/lib/SILGen/SILGenPattern.cpp @@ -983,6 +983,11 @@ chooseNecessaryColumn(const ClauseMatrix &matrix, unsigned firstRow) { /// Recursively emit a decision tree from the given pattern matrix. void PatternMatchEmission::emitDispatch(ClauseMatrix &clauses, ArgArray args, const FailureHandler &outerFailure) { + if (clauses.rows() == 0) { + SGF.B.createUnreachable(SILLocation(PatternMatchStmt)); + return; + } + unsigned firstRow = 0; while (true) { // If there are no rows remaining, then we fail. diff --git a/test/Sema/exhaustive_switch.swift b/test/Sema/exhaustive_switch.swift index f9629dd091946..728d13e9c2363 100644 --- a/test/Sema/exhaustive_switch.swift +++ b/test/Sema/exhaustive_switch.swift @@ -360,6 +360,10 @@ enum MyNever {} func ~= (_ : MyNever, _ : MyNever) -> Bool { return true } func myFatalError() -> MyNever { fatalError() } +@_frozen public enum UninhabitedT4 { + case x(A) +} + func checkUninhabited() { // Scrutinees of uninhabited type may match any number and kind of patterns // that Sema is willing to accept at will. After all, it's quite a feat to @@ -379,6 +383,10 @@ func checkUninhabited() { case myFatalError(): break } } + + func test4(x: UninhabitedT4) { + switch x {} // No diagnostic. + } } enum Runcible {