Files
swift-mirror/test/Concurrency/async_conformance.swift
Kavon Farvardin ff54f3b834 witnesses for an async ObjC protocol requirement cannot be sync
While a Swift protocol can have its async requirements satisfied
by a sync witness, this is not the case for ObjC protocols because
it is not just a calling convention difference.

Because every async ObjC function requirement in the protocol also
has a sibling that is sync, a sync witness might be trying
to conform to the sync version that takes a completion handler.

Without this change, we were seeing an issue where we would
consider both the async and sync versions of an ObjC requirement,
and accidentially choose the async version when the witness was
sync, and then raise an error about the typechecker's mistake.

Instead of raising an error, this change removes the ability for
the typechecker to even consider the errornous conformance.

resolves rdar://73326234
2021-02-01 17:18:11 -08:00

42 lines
1.6 KiB
Swift

// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency
// REQUIRES: objc_interop
// REQUIRES: concurrency
import Foundation
// async objc requirement, sync witness
@objc protocol Tracker {
func track(event: String) async // expected-note {{protocol requires function 'track(event:)' with type '(String) async -> ()'; do you want to add a stub?}}
}
class Dog: NSObject, Tracker { // expected-error {{type 'Dog' does not conform to protocol 'Tracker'}}
func track(event: String) {} // expected-note {{candidate is not 'async', but @objc protocol requirement is}}
}
// sync objc requirement, async witness
@objc protocol Runner {
func run(event: String) // expected-note {{protocol requires function 'run(event:)' with type '(String) -> ()'; do you want to add a stub?}}
}
class Athlete: NSObject, Runner { // expected-error {{type 'Athlete' does not conform to protocol 'Runner'}}
func run(event: String) async {} // expected-note {{candidate is 'async', but @objc protocol requirement is not}}
}
// async swift protocol, sync witness
protocol Snacker {
func snack(food: String) async
}
class Foodie: Snacker {
func snack(food: String) {}
}
// sync swift protocol, async witness
protocol Backer {
func back(stonk: String) // expected-note {{protocol requires function 'back(stonk:)' with type '(String) -> ()'; do you want to add a stub?}}
}
class Investor: Backer { // expected-error {{type 'Investor' does not conform to protocol 'Backer'}}
func back(stonk: String) async {} // expected-note {{candidate is 'async', but protocol requirement is not}}
}