Files
swift-mirror/test/Concurrency/isolated_conformance_default_actor.swift
Doug Gregor 9f7dff0417 [SE-0466] Treat explicit "nonisolated" like implicit "nonisolated" on protocols
Make explicit "nonisolated" also not special on protocols, so a
nonisolated protocol does not suppress default isolation.
SendableMetatype is the proper way to suppress default isolation for a
protocol.

Unfortunately, these rules made it appear like issue #82168
was fixed, when in fact it was not. Keep the test case, but as a
failing test, and we'll investigate separately.
2025-07-25 09:47:24 -07:00

101 lines
3.4 KiB
Swift

// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.1-abi-triple -swift-version 6 -default-isolation MainActor %s
// REQUIRES: concurrency
@MainActor func onMain() { }
nonisolated
protocol P {
func f()
}
@MainActor
protocol Q {
func g()
}
// expected-note@+4{{turn data races into runtime errors with '@preconcurrency'}}
// expected-note@+3{{isolate this conformance to the main actor with '@MainActor'}}
// expected-note@+2{{mark all declarations used in the conformance 'nonisolated'}}
// expected-error@+1{{conformance of 'CImplicitMainActorNonisolatedConformance' to protocol 'P' crosses into main actor-isolated code and can cause data races}}
class CImplicitMainActorNonisolatedConformance: nonisolated P {
func f() { // expected-note{{main actor-isolated instance method 'f()' cannot satisfy nonisolated requirement}}
onMain() // okay, f is on @MainActor
}
}
@MainActor
class CExplicitMainActor: P {
func f() { } // okay! conformance above is isolated
}
class CImplicitMainActor: P {
func f() { } // okay! conformance above is isolated
}
// If the protocol itself is isolated, don't do anything.
extension CExplicitMainActor: Q {
func g() { }
}
extension CImplicitMainActor: Q {
func g() { }
}
// expected-error@+3{{conformance of 'CNonIsolated' to protocol 'P' crosses into main actor-isolated code and can cause data races}}
// expected-note@+2{{turn data races into runtime errors with '@preconcurrency'}}
// expected-note@+1{{isolate this conformance to the main actor with '@MainActor'}}{{33-33=@MainActor }}
nonisolated class CNonIsolated: P {
@MainActor func f() { } // expected-note{{main actor-isolated instance method 'f()' cannot satisfy nonisolated requirement}}
}
// Synthesized conformances
struct EquatableStruct: Equatable {
var state: Int = 0
}
struct HashableStruct: Hashable {
var state: Int = 0
}
enum RawRepresentableEnum: Int {
case one
case two
}
class CodableClass: Codable {
var state: Int = 0
}
class OtherClass {
var otherState: any Encodable.Type = CodableClass.self
}
struct Landmark: Codable {
var name: String
var foundingYear: Int
}
func acceptSendablePMeta<T: Sendable & P>(_: T.Type) { }
func acceptSendableQMeta<T: Sendable & Q>(_: T.Type) { }
nonisolated func testConformancesFromNonisolated() {
let _: any P = CNonIsolated()
let _: any P = CImplicitMainActorNonisolatedConformance()
// Okay, these are nonisolated conformances.
let _: any Q = CExplicitMainActor()
let _: any Q = CImplicitMainActor()
// Error, these are main-actor-isolated conformances
let _: any P = CExplicitMainActor() // expected-error{{main actor-isolated conformance of 'CExplicitMainActor' to 'P' cannot be used in nonisolated context}}
let _: any P = CImplicitMainActor() // expected-error{{main actor-isolated conformance of 'CImplicitMainActor' to 'P' cannot be used in nonisolated context}}
let _: any Equatable.Type = EquatableStruct.self // expected-error{{main actor-isolated conformance of 'EquatableStruct' to 'Equatable' cannot be used in nonisolated context}}
let _: any Hashable.Type = HashableStruct.self // expected-error{{main actor-isolated conformance of 'HashableStruct' to 'Hashable' cannot be used in nonisolated context}}
let _: any RawRepresentable.Type = RawRepresentableEnum.self
let _: any Encodable.Type = CodableClass.self // expected-error{{main actor-isolated conformance of 'CodableClass' to 'Encodable' cannot be used in nonisolated context}}
}