Skip to content

Commit 6d045b0

Browse files
committed
Merge pull request #1554 from JaSpa/enum-case-is-no-type
[AST/Sema] Don't crash when referencing enum case in where-clause
2 parents 6571f8b + 8bca045 commit 6d045b0

File tree

5 files changed

+22
-9
lines changed

5 files changed

+22
-9
lines changed

include/swift/AST/Decl.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5270,7 +5270,9 @@ class EnumElementDecl : public ValueDecl {
52705270
static_cast<unsigned>(ElementRecursiveness::NotRecursive);
52715271
}
52725272

5273-
void computeType();
5273+
/// \returns false if there was an error during the computation rendering the
5274+
/// EnumElementDecl invalid, true otherwise.
5275+
bool computeType();
52745276

52755277
bool hasArgumentType() const { return !ArgumentType.getType().isNull(); }
52765278
Type getArgumentType() const { return ArgumentType.getType(); }

lib/AST/Decl.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4309,10 +4309,15 @@ SourceRange EnumElementDecl::getSourceRange() const {
43094309
return {getStartLoc(), getNameLoc()};
43104310
}
43114311

4312-
void EnumElementDecl::computeType() {
4312+
bool EnumElementDecl::computeType() {
43134313
EnumDecl *ED = getParentEnum();
4314-
43154314
Type resultTy = ED->getDeclaredTypeInContext();
4315+
4316+
if (resultTy->is<ErrorType>()) {
4317+
setType(resultTy);
4318+
return false;
4319+
}
4320+
43164321
Type argTy = MetatypeType::get(resultTy);
43174322

43184323
// The type of the enum element is either (T) -> T or (T) -> ArgType -> T.
@@ -4326,6 +4331,7 @@ void EnumElementDecl::computeType() {
43264331
resultTy = FunctionType::get(argTy, resultTy);
43274332

43284333
setType(resultTy);
4334+
return true;
43294335
}
43304336

43314337
Type EnumElementDecl::getArgumentInterfaceType() const {

lib/Sema/TypeCheckDecl.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5543,11 +5543,14 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
55435543
EED->setRecursiveness(ElementRecursiveness::NotRecursive);
55445544
}
55455545

5546-
// Now that we have an argument type we can set the element's declared
5547-
// type.
5548-
if (!EED->hasType())
5549-
EED->computeType();
5550-
EED->setIsBeingTypeChecked(false);
5546+
{
5547+
defer { EED->setIsBeingTypeChecked(false); };
5548+
5549+
// Now that we have an argument type we can set the element's declared
5550+
// type.
5551+
if (!EED->hasType() && !EED->computeType())
5552+
return;
5553+
}
55515554

55525555
// Test for type parameters, as opposed to a generic decl context, in
55535556
// case the enclosing enum type was illegally declared inside of a generic

test/Generics/generic_types.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,3 +334,5 @@ struct UnsolvableInheritance1<T : T.A> {}
334334
struct UnsolvableInheritance2<T : U.A, U : T.A> {}
335335
// expected-error@-1 {{inheritance from non-protocol, non-class type 'U.A'}}
336336
// expected-error@-2 {{inheritance from non-protocol, non-class type 'T.A'}}
337+
338+
enum X7<T where X7.X : G> { case X } // expected-error{{'X' is not a member type of 'X7<T>'}}

validation-test/compiler_crashers/28224-swift-genericfunctiontype-get.swift renamed to validation-test/compiler_crashers_fixed/28224-swift-genericfunctiontype-get.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55
// See http://swift.org/LICENSE.txt for license information
66
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
77

8-
// RUN: not --crash %target-swift-frontend %s -parse
8+
// RUN: not %target-swift-frontend %s -parse
99
// REQUIRES: asserts
1010
{enum S<T where S.c:A{case c

0 commit comments

Comments
 (0)