Skip to content

Commit 103bd04

Browse files
committed
Revert "Revert "Prevent noncopyable metatypes from being converted to Any""
This reverts commit 1a3b42c.
1 parent bd1cc4c commit 103bd04

File tree

6 files changed

+41
-15
lines changed

6 files changed

+41
-15
lines changed

Diff for: lib/AST/Module.cpp

+12-4
Original file line numberDiff line numberDiff line change
@@ -1768,10 +1768,18 @@ static ProtocolConformanceRef getBuiltinFunctionTypeConformance(
17681768
/// appropriate.
17691769
static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance(
17701770
Type type, const AnyMetatypeType *metatypeType, ProtocolDecl *protocol) {
1771-
// All metatypes are Sendable and Copyable
1772-
if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable) ||
1773-
protocol->isSpecificProtocol(KnownProtocolKind::Copyable)) {
1774-
ASTContext &ctx = protocol->getASTContext();
1771+
ASTContext &ctx = protocol->getASTContext();
1772+
1773+
// Only metatypes of Copyable types are Copyable.
1774+
if (protocol->isSpecificProtocol(KnownProtocolKind::Copyable) &&
1775+
!metatypeType->getInstanceType()->isPureMoveOnly()) {
1776+
return ProtocolConformanceRef(
1777+
ctx.getBuiltinConformance(type, protocol, GenericSignature(), { },
1778+
BuiltinConformanceKind::Synthesized));
1779+
}
1780+
1781+
// All metatypes are Sendable
1782+
if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable)) {
17751783
return ProtocolConformanceRef(
17761784
ctx.getBuiltinConformance(type, protocol, GenericSignature(), { },
17771785
BuiltinConformanceKind::Synthesized));

Diff for: lib/Sema/CSSimplify.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -3834,8 +3834,8 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
38343834
return getTypeMatchAmbiguous();
38353835
}
38363836

3837-
// move-only types cannot match with any existential types.
3838-
if (type1->isPureMoveOnly()) {
3837+
// move-only types (and their metatypes) cannot match with existential types.
3838+
if (type1->getMetatypeInstanceType()->isPureMoveOnly()) {
38393839
// tailor error message
38403840
if (shouldAttemptFixes()) {
38413841
auto *fix = MustBeCopyable::create(*this, type1,

Diff for: lib/Sema/TypeCheckConstraints.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -1642,12 +1642,12 @@ TypeChecker::typeCheckCheckedCast(Type fromType, Type toType,
16421642
}
16431643

16441644
// Since move-only types currently cannot conform to protocols, nor be a class
1645-
// type, the subtyping hierarchy is a bit bizarre as of now:
1645+
// type, the subtyping hierarchy looks a bit like this:
16461646
//
1647-
// noncopyable
1648-
// structs and enums
1649-
// |
1650-
// +--------- Any
1647+
// ~Copyable
1648+
// / \
1649+
// / \
1650+
// +--------- Any noncopyable structs/enums
16511651
// | |
16521652
// AnyObject protocol
16531653
// | existentials
@@ -1659,7 +1659,9 @@ TypeChecker::typeCheckCheckedCast(Type fromType, Type toType,
16591659
//
16601660
//
16611661
// Thus, right now, a move-only type is only a subtype of itself.
1662-
if (fromType->isPureMoveOnly() || toType->isPureMoveOnly())
1662+
// We also want to prevent conversions of a move-only type's metatype.
1663+
if (fromType->getMetatypeInstanceType()->isPureMoveOnly()
1664+
|| toType->getMetatypeInstanceType()->isPureMoveOnly())
16631665
return CheckedCastKind::Unresolved;
16641666

16651667
// Check for a bridging conversion.

Diff for: stdlib/public/Concurrency/PartialAsyncTask.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,9 @@ public struct ExecutorJob: Sendable {
221221
/// and it appearing as 0 for _different_ jobs may lead to misunderstanding it as
222222
/// being "the same 0 id job", we specifically print 0 (id not set) as nil.
223223
if (id > 0) {
224-
return "\(Self.self)(id: \(id))"
224+
return "ExecutorJob(id: \(id))"
225225
} else {
226-
return "\(Self.self)(id: nil)"
226+
return "ExecutorJob(id: nil)"
227227
}
228228
}
229229
}

Diff for: stdlib/public/Distributed/DistributedDefaultExecutor.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ internal final class DistributedRemoteActorReferenceExecutor: SerialExecutor {
2626
@inlinable
2727
public func enqueue(_ job: __owned ExecutorJob) {
2828
let jobDescription = job.description
29-
fatalError("Attempted to enqueue \(ExecutorJob.self) (\(jobDescription)) on executor of remote distributed actor reference!")
29+
fatalError("Attempted to enqueue ExecutorJob (\(jobDescription)) on executor of remote distributed actor reference!")
3030
}
3131

3232
public func asUnownedSerialExecutor() -> UnownedSerialExecutor {

Diff for: test/Constraints/moveonly_constraints.swift

+16
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ func checkCasting(_ b: any Box, _ mo: borrowing MO, _ a: Any) {
148148
let _: MO = dup.get()
149149
let _: MO = dup.val
150150

151+
let _: Any = MO.self // expected-error {{move-only type 'MO.Type' cannot be used with generics yet}}
152+
let _: AnyObject = MO.self // expected-error {{move-only type 'MO.Type' cannot be used with generics yet}}
153+
let _ = MO.self as Any // expected-error {{move-only type 'MO.Type' cannot be used with generics yet}}
154+
let _ = MO.self is Any // expected-warning {{cast from 'MO.Type' to unrelated type 'Any' always fails}}
155+
151156
let _: Sendable = (MO(), MO()) // expected-error {{move-only type '(MO, MO)' cannot be used with generics yet}}
152157
let _: Sendable = MO() // expected-error {{move-only type 'MO' cannot be used with generics yet}}
153158
let _: _Copyable = mo // expected-error {{'_Copyable' is unavailable}}
@@ -266,3 +271,14 @@ struct GenerousGuy: Gives { // expected-error {{type 'GenerousGuy' does not conf
266271
typealias Ty = MO // expected-note {{possibly intended match 'GenerousGuy.Ty' (aka 'MO') does not conform to '_Copyable'}}
267272
func give() -> Ty {}
268273
}
274+
275+
func doBadMetatypeStuff<T>(_ t: T) {
276+
let y = t as! Any.Type
277+
if let MO_MetaType = y as? MO.Type { // expected-warning {{cast from 'any Any.Type' to unrelated type 'MO.Type' always fails}}
278+
let x = MO_MetaType.init()
279+
let _ = x
280+
}
281+
}
282+
func tryToDoBadMetatypeStuff() {
283+
doBadMetatypeStuff(MO.self) // expected-error {{move-only type 'MO.Type' cannot be used with generics yet}}
284+
}

0 commit comments

Comments
 (0)