Skip to content

Commit b78e2f5

Browse files
committed
Ensure all decls using move-only types are feature-guarded
rdar://106262652
1 parent 6a9e9d6 commit b78e2f5

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3159,8 +3159,27 @@ static bool usesFeatureFlowSensitiveConcurrencyCaptures(Decl *decl) {
31593159
}
31603160

31613161
static bool usesFeatureMoveOnly(Decl *decl) {
3162-
if (auto nominal = dyn_cast<NominalTypeDecl>(decl))
3163-
return nominal->isMoveOnly();
3162+
if (auto *extension = dyn_cast<ExtensionDecl>(decl)) {
3163+
if (auto *nominal = extension->getSelfNominalTypeDecl())
3164+
if (nominal->isMoveOnly())
3165+
return true;
3166+
}
3167+
3168+
if (auto value = dyn_cast<ValueDecl>(decl)) {
3169+
if (value->isMoveOnly())
3170+
return true;
3171+
3172+
// Check for move-only types in the types of this declaration.
3173+
if (Type type = value->getInterfaceType()) {
3174+
bool hasMoveOnly = type.findIf([](Type type) {
3175+
return type->isPureMoveOnly();
3176+
});
3177+
3178+
if (hasMoveOnly)
3179+
return true;
3180+
}
3181+
}
3182+
31643183
return false;
31653184
}
31663185

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-emit-module-interface(%t/Library.swiftinterface) %s -module-name Library -enable-experimental-feature MoveOnly
3+
// RUN: %target-swift-typecheck-module-from-interface(%t/Library.swiftinterface) -I %t
4+
// RUN: %FileCheck %s < %t/Library.swiftinterface
5+
6+
// this test makes sure that decls containing a move-only type are guarded by the $MoveOnly feature flag
7+
8+
// CHECK: swift-module-flags-ignorable: -enable-experimental-feature MoveOnly
9+
10+
// CHECK: #if compiler(>=5.3) && $MoveOnly
11+
// CHECK-NEXT: @_moveOnly public struct MoveOnlyStruct {
12+
13+
// CHECK: #if compiler(>=5.3) && $MoveOnly
14+
// CHECK-NEXT: @_moveOnly public enum MoveOnlyEnum {
15+
16+
// CHECK: #if compiler(>=5.3) && $MoveOnly
17+
// CHECK-NEXT: public func someFn() -> Library.MoveOnlyEnum
18+
19+
// CHECK: public class What {
20+
// CHECK: #if compiler(>=5.3) && $MoveOnly
21+
// CHECK-NEXT: public func diamonds(_ f: (borrowing Library.MoveOnlyStruct) -> Swift.Int)
22+
23+
// CHECK: #if compiler(>=5.3) && $MoveOnly
24+
// CHECK-NEXT: extension Library.MoveOnlyStruct {
25+
26+
@_moveOnly public struct MoveOnlyStruct {
27+
let x = 0
28+
}
29+
30+
@_moveOnly public enum MoveOnlyEnum {
31+
case depth
32+
}
33+
34+
public func someFn() -> MoveOnlyEnum { return .depth }
35+
36+
public class What {
37+
public func diamonds(_ f: (borrowing MoveOnlyStruct) -> Int) {}
38+
}
39+
40+
public extension MoveOnlyStruct {
41+
func who() {}
42+
}
43+
44+

0 commit comments

Comments
 (0)