Skip to content

emit error when a noncopyable enum has a raw type #66818

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -3246,6 +3246,9 @@ ERROR(enum_raw_type_nonconforming_and_nonsynthable,none,
"and conformance could not be synthesized", (Type, Type))
NOTE(enum_declares_rawrep_with_raw_type,none,
"%0 declares raw type %1, which implies RawRepresentable", (Type, Type))
ERROR(enum_raw_type_nonconforming_and_noncopyable,none,
"%0 declares raw type %1, but cannot yet conform to RawRepresentable "
"because it is noncopyable", (Type, Type))
ERROR(enum_raw_type_access,none,
"enum %select{must be declared %select{"
"%select{private|fileprivate|internal|package|%error|%error}1|private or fileprivate}3"
Expand Down
18 changes: 14 additions & 4 deletions lib/Sema/TypeCheckDeclPrimary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ static void checkInheritanceClause(
}

// If this is an enum inheritance clause, check for a raw type.
if (isa<EnumDecl>(decl)) {
if (auto enumDecl = dyn_cast<EnumDecl>(decl)) {
// Check if we already had a raw type.
if (superclassTy) {
if (superclassTy->isEqual(inheritedTy)) {
Expand All @@ -293,6 +293,18 @@ static void checkInheritanceClause(
}
continue;
}

// Noncopyable types cannot have a raw type until there is support for
// generics, since the raw type here is only useful if we'll generate
// a conformance to RawRepresentable, which is currently disabled.
if (enumDecl->isMoveOnly()) {
// TODO: getRemovalRange is not yet aware of ~Copyable entries so it
// will accidentally delete commas or colons that are needed.
diags.diagnose(inherited.getSourceRange().Start,
diag::enum_raw_type_nonconforming_and_noncopyable,
enumDecl->getDeclaredInterfaceType(), inheritedTy)
.highlight(inherited.getSourceRange());
}

// If this is not the first entry in the inheritance clause, complain.
if (i > 0) {
Expand All @@ -303,11 +315,9 @@ static void checkInheritanceClause(
.fixItRemoveChars(removeRange.Start, removeRange.End)
.fixItInsert(inheritedClause[0].getSourceRange().Start,
inheritedTy.getString() + ", ");

// Fall through to record the raw type.
}

// Record the raw type.
// Save the raw type locally.
superclassTy = inheritedTy;
superclassRange = inherited.getSourceRange();
continue;
Expand Down
2 changes: 2 additions & 0 deletions test/Sema/moveonly_objc_enum.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@

@_moveOnly
@objc enum Foo : Int { // expected-error {{noncopyable enums cannot be marked '@objc'}}
// expected-error@-1 {{'Foo' declares raw type 'Int', but cannot yet conform to RawRepresentable because it is noncopyable}}
case X, Y, Z
deinit {} // expected-error {{deinitializers cannot be declared on an @objc enum type}}
}

@_moveOnly
@objc enum Foo2 : Int { // expected-error {{noncopyable enums cannot be marked '@objc'}}
// expected-error@-1 {{'Foo2' declares raw type 'Int', but cannot yet conform to RawRepresentable because it is noncopyable}}
case X, Y, Z
}

4 changes: 2 additions & 2 deletions test/Sema/moveonly_restrictions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@ enum Color {
}
}

@_moveOnly
enum StrengthLevel: Int { // ensure move-only raw enums do not conform to RawRepresentable
// expected-error@+1:21 {{'StrengthLevel' declares raw type 'Int', but cannot yet conform to RawRepresentable because it is noncopyable}}
enum StrengthLevel: Int, ~Copyable {
case none = 0
case low
case high
Expand Down