Skip to content

Commit 455c663

Browse files
committed
[move-only] Temporarily ban deinits on non-copyable enums.
The reason why we are doing this is that: 1. For non-copyable types, switches are always at +1 for now. 2. non-copyable enums with deinits cannot be switched upon since that would invalidate the deinit. So deinits on non-copyable enums are just not useful at this point since you cannot open the enum. Once we make it so that you can bind a non-copyable enum at +0, we will remove this check. I added an experimental feature MoveOnlyEnumDeinits so tests that validate the codegen/etc will still work. rdar://101651138
1 parent 9f38648 commit 455c663

13 files changed

+40
-12
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,8 @@ ERROR(initializer_result_type,PointsToFirstBadToken,
424424
// Destructor
425425
ERROR(destructor_decl_outside_class_or_noncopyable,none,
426426
"deinitializers may only be declared within a class, actor, or noncopyable type", ())
427+
ERROR(destructor_decl_on_noncopyable_enum,none,
428+
"deinitializers are not yet supported on noncopyable enums", ())
427429
ERROR(destructor_decl_on_objc_enum,none,
428430
"deinitializers cannot be declared on an @objc enum type", ())
429431
ERROR(expected_lbrace_destructor,PointsToFirstBadToken,

include/swift/Basic/Features.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ EXPERIMENTAL_FEATURE(FreestandingMacros, true)
116116
// but our tests currently rely on it, and we want to run those
117117
// tests in non-asserts builds too.
118118
EXPERIMENTAL_FEATURE(MoveOnlyClasses, true)
119+
EXPERIMENTAL_FEATURE(MoveOnlyEnumDeinits, true)
119120

120121
EXPERIMENTAL_FEATURE(OneWayClosureParameters, false)
121122
EXPERIMENTAL_FEATURE(TypeWitnessSystemInference, false)

lib/AST/ASTPrinter.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3232,6 +3232,13 @@ static bool usesFeatureMoveOnlyClasses(Decl *decl) {
32323232
return isa<ClassDecl>(decl) && usesFeatureMoveOnly(decl);
32333233
}
32343234

3235+
static bool usesFeatureMoveOnlyEnumDeinits(Decl *decl) {
3236+
if (auto *ei = dyn_cast<EnumDecl>(decl)) {
3237+
return usesFeatureMoveOnly(ei) && ei->getValueTypeDestructor();
3238+
}
3239+
return false;
3240+
}
3241+
32353242
static bool usesFeatureOneWayClosureParameters(Decl *decl) {
32363243
return false;
32373244
}

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3609,6 +3609,14 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
36093609
DD->diagnose(diag::destructor_decl_outside_class_or_noncopyable);
36103610
}
36113611

3612+
// Temporarily ban deinit on noncopyable enums, unless the experimental
3613+
// feature flag is set.
3614+
if (!DD->getASTContext().LangOpts.hasFeature(
3615+
Feature::MoveOnlyEnumDeinits) &&
3616+
nom->isMoveOnly() && isa<EnumDecl>(nom)) {
3617+
DD->diagnose(diag::destructor_decl_on_noncopyable_enum);
3618+
}
3619+
36123620
// If we have a noncopyable type, check if we have an @objc enum with a
36133621
// deinit and emit a specialized error. We will have technically already
36143622
// emitted an error since @objc enum cannot be marked noncopyable, but

test/IRGen/moveonly_deinit.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %{python} %utils/chex.py < %s > %t/moveonly_deinit.sil
3-
// RUN: %target-swift-frontend -emit-ir %t/moveonly_deinit.sil | %FileCheck %t/moveonly_deinit.sil --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
3+
// RUN: %target-swift-frontend -enable-experimental-feature MoveOnlyEnumDeinits -emit-ir %t/moveonly_deinit.sil | %FileCheck %t/moveonly_deinit.sil --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
44

55
// UNSUPPORTED: CPU=arm64e
66

test/Interpreter/moveonly_forget.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-run-simple-swift(-Xfrontend -sil-verify-all) | %FileCheck %s --implicit-check-not closing
1+
// RUN: %target-run-simple-swift(-Xfrontend -enable-experimental-feature -Xfrontend MoveOnlyEnumDeinits -Xfrontend -sil-verify-all) | %FileCheck %s --implicit-check-not closing
22

33
// REQUIRES: executable_test
44

test/SILGen/moveonly_deinits.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// TODO: re-enable the simplification passes once rdar://104875010 is fixed
2-
// RUN: %target-swift-emit-silgen -Xllvm -sil-disable-pass=simplification %s | %FileCheck -check-prefix=SILGEN %s
3-
// RUN: %target-swift-emit-sil -Xllvm -sil-disable-pass=simplification %s | %FileCheck -check-prefix=SIL %s
2+
// RUN: %target-swift-emit-silgen -enable-experimental-feature MoveOnlyEnumDeinits -Xllvm -sil-disable-pass=simplification %s | %FileCheck -check-prefix=SILGEN %s
3+
// RUN: %target-swift-emit-sil -enable-experimental-feature MoveOnlyEnumDeinits -Xllvm -sil-disable-pass=simplification %s | %FileCheck -check-prefix=SIL %s
44

55
// Test that makes sure that throughout the pipeline we properly handle
66
// conditional releases for trivial and non-trivial move only types.

test/SILOptimizer/moveonly_deinit_insertion.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-sil-opt -module-name main -enable-sil-verify-all -sil-move-only-deinit-insertion -enable-experimental-feature MoveOnlyClasses %s | %FileCheck %s
1+
// RUN: %target-sil-opt -module-name main -enable-sil-verify-all -sil-move-only-deinit-insertion -enable-experimental-feature MoveOnlyClasses -enable-experimental-feature MoveOnlyEnumDeinits %s | %FileCheck %s
22

33
sil_stage raw
44

test/SILOptimizer/moveonly_deinits.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -sil-verify-all -verify -emit-sil %s
1+
// RUN: %target-swift-frontend -sil-verify-all -verify -emit-sil -enable-experimental-feature MoveOnlyEnumDeinits %s
22

33
class Klass {}
44

test/Sema/moveonly_enum.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
@_moveOnly
4+
enum Foo {
5+
deinit {} // expected-error {{deinitializers are not yet supported on noncopyable enums}}
6+
}
7+
8+
@_moveOnly
9+
enum Foo2 {
10+
}

test/Sema/moveonly_objc_enum.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift
1+
// RUN: %target-typecheck-verify-swift -enable-experimental-feature MoveOnlyEnumDeinits
22

33
// REQUIRES: objc_interop
44

test/Serialization/moveonly_deinit.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %empty-directory(%t)
22
// TODO: re-enable the simplification passes once rdar://104875010 is fixed
3-
// RUN: %target-swift-frontend -Xllvm -sil-disable-pass=simplification -g -emit-module -module-name OtherModule %S/Inputs/moveonly_deinit.swift -emit-module-path %t/OtherModule.swiftmodule
4-
// RUN: %target-swift-frontend -Xllvm -sil-disable-pass=simplification -g -I %t %s -emit-silgen
3+
// RUN: %target-swift-frontend -enable-experimental-feature MoveOnlyEnumDeinits -Xllvm -sil-disable-pass=simplification -g -emit-module -module-name OtherModule %S/Inputs/moveonly_deinit.swift -emit-module-path %t/OtherModule.swiftmodule
4+
// RUN: %target-swift-frontend -enable-experimental-feature MoveOnlyEnumDeinits -Xllvm -sil-disable-pass=simplification -g -I %t %s -emit-silgen
55

66
// Make sure we can deserialize deinits of both enums and structs.
77

test/Serialization/moveonly_error_on_import_into_module_without_flag.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
// RUN: %empty-directory(%t)
22
// TODO: re-enable the simplification passes once rdar://104875010 is fixed
3-
// RUN: %target-swift-frontend -Xllvm -sil-disable-pass=simplification -emit-module -o %t/Library.swiftmodule -module-name Library %S/Inputs/moveonly_deinit.swift
3+
// RUN: %target-swift-frontend -Xllvm -sil-disable-pass=simplification -emit-module -o %t/Library.swiftmodule -module-name Library %S/Inputs/moveonly_deinit.swift -enable-experimental-feature MoveOnlyEnumDeinits
44

55
// >>> make sure borrow scopes are required when using a move-only type from another module
6-
// RUN: not %target-swift-frontend -DUSE_MOVEONLY_TYPE -typecheck -enable-lexical-borrow-scopes=false -I %t %s 2>&1 | %FileCheck %s --check-prefix CHECK-ERROR
6+
// RUN: not %target-swift-frontend -DUSE_MOVEONLY_TYPE -typecheck -enable-experimental-feature MoveOnlyEnumDeinits -enable-lexical-borrow-scopes=false -I %t %s 2>&1 | %FileCheck %s --check-prefix CHECK-ERROR
77
// RUN: %target-swift-frontend -DUSE_MOVEONLY_TYPE -typecheck -I %t %s 2>&1 | %FileCheck %s --allow-empty
88

99
// >>> try turning off lexical borrow scopes with no move-only types; shouldn't be an error.
1010
// we have to pipe into FileCheck because -verify ignores errors from other files.
11-
// RUN: %target-swift-frontend -enable-lexical-borrow-scopes=false -typecheck -I %t %s 2>&1 | %FileCheck %s --allow-empty
11+
// RUN: %target-swift-frontend -enable-experimental-feature MoveOnlyEnumDeinits -enable-lexical-borrow-scopes=false -typecheck -I %t %s 2>&1 | %FileCheck %s --allow-empty
1212

1313
// This test makes sure that if we import a move only type
1414
// and do not have lexical borrow scopes enabled, we emit an error.

0 commit comments

Comments
 (0)