Skip to content

Commit 271d408

Browse files
committed
functions, builtins, metatypes and some kinds of tuples to conform to _Copyable
1 parent ab13088 commit 271d408

File tree

2 files changed

+42
-11
lines changed

2 files changed

+42
-11
lines changed

lib/AST/Module.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,8 +1362,10 @@ static ProtocolConformanceRef getBuiltinTupleTypeConformance(
13621362
return ProtocolConformanceRef(specialized);
13631363
}
13641364

1365-
// Tuple type are Sendable when all of their element types are Sendable.
1366-
if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable)) {
1365+
/// For some known protocols like Sendable and Copyable, a tuple type
1366+
/// conforms to the protocol KP when all of their element types conform to KP.
1367+
if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable) ||
1368+
protocol->isSpecificProtocol(KnownProtocolKind::Copyable)) {
13671369

13681370
// Create the pieces for a generic tuple type (T1, T2, ... TN) and a
13691371
// generic signature <T1, T2, ..., TN>.
@@ -1389,9 +1391,9 @@ static ProtocolConformanceRef getBuiltinTupleTypeConformance(
13891391
BuiltinConformanceKind::Synthesized));
13901392
}
13911393

1392-
// Form a generic conformance of (T1, T2, ..., TN): Sendable with signature
1393-
// <T1, T2, ..., TN> and conditional requirements T1: Sendable,
1394-
// T2: Sendable, ..., TN: Sendable.
1394+
// Form a generic conformance of (T1, T2, ..., TN): KP with signature
1395+
// <T1, T2, ..., TN> and conditional requirements T1: KP,
1396+
// T2: P, ..., TN: KP.
13951397
auto genericTupleType = TupleType::get(genericElements, ctx);
13961398
auto genericSig = GenericSignature::get(
13971399
genericParams, conditionalRequirements);
@@ -1440,24 +1442,33 @@ static bool isSendableFunctionType(const FunctionType *functionType) {
14401442
/// appropriate.
14411443
static ProtocolConformanceRef getBuiltinFunctionTypeConformance(
14421444
Type type, const FunctionType *functionType, ProtocolDecl *protocol) {
1445+
ASTContext &ctx = protocol->getASTContext();
14431446
// @Sendable function types are Sendable.
14441447
if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable) &&
14451448
isSendableFunctionType(functionType)) {
1446-
ASTContext &ctx = protocol->getASTContext();
14471449
return ProtocolConformanceRef(
14481450
ctx.getBuiltinConformance(type, protocol, GenericSignature(), { },
14491451
BuiltinConformanceKind::Synthesized));
14501452
}
14511453

1454+
// Functions cannot destroy move-only vars/lets that they capture, so it's
1455+
// safe to copy functions, as if they're classes.
1456+
if (protocol->isSpecificProtocol(KnownProtocolKind::Copyable)) {
1457+
return ProtocolConformanceRef(
1458+
ctx.getBuiltinConformance(type, protocol, GenericSignature(), {},
1459+
BuiltinConformanceKind::Synthesized));
1460+
}
1461+
14521462
return ProtocolConformanceRef::forMissingOrInvalid(type, protocol);
14531463
}
14541464

14551465
/// Synthesize a builtin metatype type conformance to the given protocol, if
14561466
/// appropriate.
14571467
static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance(
14581468
Type type, const AnyMetatypeType *metatypeType, ProtocolDecl *protocol) {
1459-
// All metatypes are Sendable.
1460-
if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable)) {
1469+
// All metatypes are Sendable and Copyable
1470+
if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable) ||
1471+
protocol->isSpecificProtocol(KnownProtocolKind::Copyable)) {
14611472
ASTContext &ctx = protocol->getASTContext();
14621473
return ProtocolConformanceRef(
14631474
ctx.getBuiltinConformance(type, protocol, GenericSignature(), { },
@@ -1471,8 +1482,9 @@ static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance(
14711482
/// appropriate.
14721483
static ProtocolConformanceRef getBuiltinBuiltinTypeConformance(
14731484
Type type, const BuiltinType *builtinType, ProtocolDecl *protocol) {
1474-
// All builtin are Sendable.
1475-
if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable)) {
1485+
// All builtin are Sendable and Copyable
1486+
if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable) ||
1487+
protocol->isSpecificProtocol(KnownProtocolKind::Copyable)) {
14761488
ASTContext &ctx = protocol->getASTContext();
14771489
return ProtocolConformanceRef(
14781490
ctx.getBuiltinConformance(type, protocol, GenericSignature(), { },

test/Constraints/moveonly_constraints.swift

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@ enum Maybe<T> {
4242

4343
func takeConcrete(_ m: MO) {}
4444
func takeGeneric<T>(_ t: T) {}
45+
func takeGenericSendable<T>(_ t: T) where T: Sendable {}
4546
func takeMaybe<T>(_ m: Maybe<T>) {}
4647
func takeAnyBoxErased(_ b: any Box) {}
4748
func takeAnyBox<T>(_ b: any Box<T>) {}
4849
func takeAny(_ a: Any) {}
50+
func takeAnyObject(_ a: AnyObject) {}
51+
func genericVarArg<T>(_ t: T...) {}
4952

5053
var globalMO: MO = MO()
5154

@@ -66,12 +69,28 @@ func testAny() {
6669
takeAny(MO()) // expected-error {{move-only type 'MO' cannot be used with generics yet}}
6770
}
6871

69-
func testFunctionCalls() {
72+
func testBasic(_ mo: MO) {
7073
takeConcrete(globalMO)
7174
takeConcrete(MO())
7275

7376
takeGeneric(globalMO) // expected-error {{move-only type 'MO' cannot be used with generics yet}}
7477
takeGeneric(MO()) // expected-error {{move-only type 'MO' cannot be used with generics yet}}
78+
takeGeneric(mo) // expected-error {{move-only type 'MO' cannot be used with generics yet}}
79+
80+
takeAny(mo) // expected-error {{move-only type 'MO' cannot be used with generics yet}}
81+
print(mo) // expected-error {{move-only type 'MO' cannot be used with generics yet}}
82+
_ = "\(mo)" // expected-error {{move-only type 'MO' cannot be used with generics yet}}
83+
let _: String = String(describing: mo) // expected-error {{move-only type 'MO' cannot be used with generics yet}}
84+
85+
takeGeneric { () -> Int? in mo.x }
86+
genericVarArg(5)
87+
genericVarArg(mo) // expected-error {{move-only type 'MO' cannot be used with generics yet}}
88+
89+
takeGeneric( (mo, 5) ) // expected-error {{global function 'takeGeneric' requires that 'MO' conform to '_Copyable'}}
90+
takeGenericSendable((mo, mo)) // expected-error 2{{global function 'takeGenericSendable' requires that 'MO' conform to '_Copyable'}}
91+
92+
let singleton : (MO) = (mo)
93+
takeGeneric(singleton) // expected-error {{move-only type 'MO' cannot be used with generics yet}}
7594
}
7695

7796
func checkBasicBoxes() {

0 commit comments

Comments
 (0)