diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp index e5dc2e67ed559..0e7b9fd693fb2 100644 --- a/lib/AST/Module.cpp +++ b/lib/AST/Module.cpp @@ -1768,10 +1768,18 @@ static ProtocolConformanceRef getBuiltinFunctionTypeConformance( /// appropriate. static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance( Type type, const AnyMetatypeType *metatypeType, ProtocolDecl *protocol) { - // All metatypes are Sendable and Copyable - if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable) || - protocol->isSpecificProtocol(KnownProtocolKind::Copyable)) { - ASTContext &ctx = protocol->getASTContext(); + ASTContext &ctx = protocol->getASTContext(); + + // Only metatypes of Copyable types are Copyable. + if (protocol->isSpecificProtocol(KnownProtocolKind::Copyable) && + !metatypeType->getInstanceType()->isPureMoveOnly()) { + return ProtocolConformanceRef( + ctx.getBuiltinConformance(type, protocol, GenericSignature(), { }, + BuiltinConformanceKind::Synthesized)); + } + + // All metatypes are Sendable + if (protocol->isSpecificProtocol(KnownProtocolKind::Sendable)) { return ProtocolConformanceRef( ctx.getBuiltinConformance(type, protocol, GenericSignature(), { }, BuiltinConformanceKind::Synthesized)); diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 2d85992a5102e..711534da435d4 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -3806,8 +3806,8 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2, return getTypeMatchAmbiguous(); } - // move-only types cannot match with any existential types. - if (type1->isPureMoveOnly()) { + // move-only types (and their metatypes) cannot match with existential types. + if (type1->getMetatypeInstanceType()->isPureMoveOnly()) { // tailor error message if (shouldAttemptFixes()) { auto *fix = MustBeCopyable::create(*this, type1, diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp index 1034a1b458409..15a2cb26ad7d4 100644 --- a/lib/Sema/TypeCheckConstraints.cpp +++ b/lib/Sema/TypeCheckConstraints.cpp @@ -1629,12 +1629,12 @@ TypeChecker::typeCheckCheckedCast(Type fromType, Type toType, } // Since move-only types currently cannot conform to protocols, nor be a class - // type, the subtyping hierarchy is a bit bizarre as of now: + // type, the subtyping hierarchy looks a bit like this: // - // noncopyable - // structs and enums - // | - // +--------- Any + // ~Copyable + // / \ + // / \ + // +--------- Any noncopyable structs/enums // | | // AnyObject protocol // | existentials @@ -1646,7 +1646,9 @@ TypeChecker::typeCheckCheckedCast(Type fromType, Type toType, // // // Thus, right now, a move-only type is only a subtype of itself. - if (fromType->isPureMoveOnly() || toType->isPureMoveOnly()) + // We also want to prevent conversions of a move-only type's metatype. + if (fromType->getMetatypeInstanceType()->isPureMoveOnly() + || toType->getMetatypeInstanceType()->isPureMoveOnly()) return CheckedCastKind::Unresolved; // Check for a bridging conversion. diff --git a/stdlib/public/Concurrency/PartialAsyncTask.swift b/stdlib/public/Concurrency/PartialAsyncTask.swift index 020f7da03b157..523c83bb4908e 100644 --- a/stdlib/public/Concurrency/PartialAsyncTask.swift +++ b/stdlib/public/Concurrency/PartialAsyncTask.swift @@ -142,9 +142,9 @@ public struct ExecutorJob: Sendable { /// and it appearing as 0 for _different_ jobs may lead to misunderstanding it as /// being "the same 0 id job", we specifically print 0 (id not set) as nil. if (id > 0) { - return "\(Self.self)(id: \(id))" + return "ExecutorJob(id: \(id))" } else { - return "\(Self.self)(id: nil)" + return "ExecutorJob(id: nil)" } } } diff --git a/stdlib/public/Distributed/DistributedDefaultExecutor.swift b/stdlib/public/Distributed/DistributedDefaultExecutor.swift index 4f6c5027ea488..99a64fe56f4d8 100644 --- a/stdlib/public/Distributed/DistributedDefaultExecutor.swift +++ b/stdlib/public/Distributed/DistributedDefaultExecutor.swift @@ -26,7 +26,7 @@ internal final class DistributedRemoteActorReferenceExecutor: SerialExecutor { @inlinable public func enqueue(_ job: __owned ExecutorJob) { let jobDescription = job.description - fatalError("Attempted to enqueue \(ExecutorJob.self) (\(jobDescription)) on executor of remote distributed actor reference!") + fatalError("Attempted to enqueue ExecutorJob (\(jobDescription)) on executor of remote distributed actor reference!") } public func asUnownedSerialExecutor() -> UnownedSerialExecutor { diff --git a/test/Constraints/moveonly_constraints.swift b/test/Constraints/moveonly_constraints.swift index 188efa795c19d..8d838e5b07997 100644 --- a/test/Constraints/moveonly_constraints.swift +++ b/test/Constraints/moveonly_constraints.swift @@ -148,6 +148,11 @@ func checkCasting(_ b: any Box, _ mo: borrowing MO, _ a: Any) { let _: MO = dup.get() let _: MO = dup.val + let _: Any = MO.self // expected-error {{move-only type 'MO.Type' cannot be used with generics yet}} + let _: AnyObject = MO.self // expected-error {{move-only type 'MO.Type' cannot be used with generics yet}} + let _ = MO.self as Any // expected-error {{move-only type 'MO.Type' cannot be used with generics yet}} + let _ = MO.self is Any // expected-warning {{cast from 'MO.Type' to unrelated type 'Any' always fails}} + let _: Sendable = (MO(), MO()) // expected-error {{move-only type '(MO, MO)' cannot be used with generics yet}} let _: Sendable = MO() // expected-error {{move-only type 'MO' cannot be used with generics yet}} let _: _Copyable = mo // expected-error {{'_Copyable' is unavailable}} @@ -266,3 +271,14 @@ struct GenerousGuy: Gives { // expected-error {{type 'GenerousGuy' does not conf typealias Ty = MO // expected-note {{possibly intended match 'GenerousGuy.Ty' (aka 'MO') does not conform to '_Copyable'}} func give() -> Ty {} } + +func doBadMetatypeStuff(_ t: T) { + let y = t as! Any.Type + if let MO_MetaType = y as? MO.Type { // expected-warning {{cast from 'any Any.Type' to unrelated type 'MO.Type' always fails}} + let x = MO_MetaType.init() + let _ = x + } +} +func tryToDoBadMetatypeStuff() { + doBadMetatypeStuff(MO.self) // expected-error {{move-only type 'MO.Type' cannot be used with generics yet}} +}