Skip to content

Commit 4308a14

Browse files
committed
[Sema] Compiler should diagnose non-unique raw values without crashing
Enums with raw type `: String ` use the case name as the raw value. So, two identical case names cause an identical raw value error. Also, identical case names cause a separate redeclaration error. The second error is diagnosed in a separate request in the DeclVisitor. We may need a special case for this situation to ignore the first error and defer diagnosing to the CheckRedeclarationRequest. For now we will diagnose both errors. `enum Foo : String { case Bar case Bar = "FooBar" // redclaration error only case Bar // redeclaration and raw value error }`
1 parent ac134e4 commit 4308a14

File tree

2 files changed

+21
-3
lines changed

2 files changed

+21
-3
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,9 +1342,7 @@ EnumRawValuesRequest::evaluate(Evaluator &eval, EnumDecl *ED,
13421342

13431343
// Diagnose the duplicate value.
13441344
Diags.diagnose(diagLoc, diag::enum_raw_value_not_unique);
1345-
assert(lastExplicitValueElt &&
1346-
"should not be able to have non-unique raw values when "
1347-
"relying on autoincrement");
1345+
13481346
if (lastExplicitValueElt != elt &&
13491347
valueKind == AutomaticEnumValueKind::Integer) {
13501348
Diags.diagnose(uncheckedRawValueOf(lastExplicitValueElt)->getLoc(),
@@ -1356,6 +1354,7 @@ EnumRawValuesRequest::evaluate(Evaluator &eval, EnumDecl *ED,
13561354
diagLoc = uncheckedRawValueOf(foundElt)->isImplicit()
13571355
? foundElt->getLoc() : uncheckedRawValueOf(foundElt)->getLoc();
13581356
Diags.diagnose(diagLoc, diag::enum_raw_value_used_here);
1357+
13591358
if (foundElt != prevSource.lastExplicitValueElt &&
13601359
valueKind == AutomaticEnumValueKind::Integer) {
13611360
if (prevSource.lastExplicitValueElt)

test/Parse/enum.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,25 @@ enum DuplicateMembers7 : String { // expected-error {{'DuplicateMembers7' declar
364364
case Foo = "Bar" // expected-error {{invalid redeclaration of 'Foo'}}
365365
}
366366

367+
enum DuplicateMembers8 : String { // expected-error {{'DuplicateMembers8' declares raw type 'String', but does not conform to RawRepresentable and conformance could not be synthesized}}
368+
case Foo // expected-note {{'Foo' previously declared here}}
369+
// expected-note@-1 {{raw value previously used here}}
370+
case Foo // expected-error {{invalid redeclaration of 'Foo'}}
371+
// expected-error@-1 {{raw value for enum case is not unique}}
372+
}
373+
374+
enum DuplicateMembers9 : String { // expected-error {{'DuplicateMembers9' declares raw type 'String', but does not conform to RawRepresentable and conformance could not be synthesized}}
375+
case Foo = "Foo" // expected-note {{'Foo' previously declared here}}
376+
// expected-note@-1 {{raw value previously used here}}
377+
case Foo = "Foo"// expected-error {{invalid redeclaration of 'Foo'}}
378+
// expected-error@-1 {{raw value for enum case is not unique}}
379+
}
380+
381+
enum DuplicateMembers10 : String {
382+
case Foo // expected-note {{raw value previously used here}}
383+
case Bar = "Foo" // expected-error {{raw value for enum case is not unique}}
384+
}
385+
367386
// Refs to duplicated enum cases shouldn't crash the compiler.
368387
// rdar://problem/20922401
369388
func check20922401() -> String {

0 commit comments

Comments
 (0)