Files
swift-mirror/test/Concurrency/transfernonsendable_functionsubtyping.swift
Alex Hoppen 66104395d7 [Sema/SourceKit] Emit same diagnostics for missing protocol requirements on the command line and in SourceKit
Some editors use diagnostics from SourceKit to replace build issues. This causes issues if the diagnostics from SourceKit are formatted differently than the build issues. Make sure they are rendered the same way, removing most uses of `DiagnosticsEditorMode`.

To do so, always emit the `add stubs for conformance` note (which previously was only emitted in editor mode) and remove all `; add <something>` suffixes from notes that state which requirements are missing.

rdar://129283608
2024-08-07 14:01:30 -07:00

115 lines
6.7 KiB
Swift

// RUN: %target-typecheck-verify-swift -swift-version 6
// READ THIS! This file only contains tests that validate that the relevant
// function subtyping rules for sending work. Please do not put other tests in
// the file!
// REQUIRES: concurrency
// REQUIRES: asserts
////////////////////////
// MARK: Declarations //
////////////////////////
class NonSendableKlass {}
protocol ProtocolWithSendingReqs {
func sendingResult() -> sending NonSendableKlass // expected-note {{}}
func nonSendingParam(_ x: NonSendableKlass) // expected-note {{}}
}
protocol ProtocolWithMixedReqs {
func nonSendingParamAndSendingResult(_ x: NonSendableKlass) -> sending NonSendableKlass // expected-note 4{{}}
}
/////////////////////////////////
// MARK: Normal Function Tests //
/////////////////////////////////
func functionWithSendingResult() -> sending NonSendableKlass { fatalError() }
func functionWithoutSendingResult() -> NonSendableKlass { fatalError() }
func functionWithSendingParameter(_ x: sending NonSendableKlass) { fatalError() }
func functionWithoutSendingParameter(_ x: NonSendableKlass) { fatalError() }
func takeFnWithSendingResult(_ fn: () -> sending NonSendableKlass) {}
func takeFnWithoutSendingResult(_ fn: () -> NonSendableKlass) {}
func takeFnWithSendingParam(_ fn: (sending NonSendableKlass) -> ()) {}
func takeFnWithoutSendingParam(_ fn: (NonSendableKlass) -> ()) {}
func testFunctionMatching() {
let _: (NonSendableKlass) -> () = functionWithSendingParameter
// expected-error @-1 {{converting a value of type '@Sendable (sending NonSendableKlass) -> ()' to type '(NonSendableKlass) -> ()' risks causing data races}}
// expected-note @-2 {{converting a function typed value with a sending parameter to one without risks allowing actor-isolated values to escape their isolation domain as an argument to an invocation of value}}
let _: (sending NonSendableKlass) -> () = functionWithSendingParameter
let _: (NonSendableKlass) -> () = functionWithoutSendingParameter
let _: (sending NonSendableKlass) -> () = functionWithoutSendingParameter
takeFnWithSendingParam(functionWithSendingParameter)
takeFnWithoutSendingParam(functionWithSendingParameter)
// expected-error @-1 {{converting a value of type '@Sendable (sending NonSendableKlass) -> ()' to type '(NonSendableKlass) -> ()' risks causing data races}}
// expected-note @-2 {{converting a function typed value with a sending parameter to one without risks allowing actor-isolated values to escape their isolation domain as an argument to an invocation of value}}
takeFnWithSendingParam(functionWithoutSendingParameter)
takeFnWithoutSendingParam(functionWithoutSendingParameter)
}
func testReturnValueMatching() {
let _: () -> NonSendableKlass = functionWithSendingResult
let _: () -> sending NonSendableKlass = functionWithSendingResult
let _: () -> NonSendableKlass = functionWithoutSendingResult
let _: () -> sending NonSendableKlass = functionWithoutSendingResult
// expected-error @-1 {{converting a value of type '@Sendable () -> NonSendableKlass' to type '() -> sending NonSendableKlass' risks causing data races}}
// expected-note @-2 {{converting a function typed value without a sending result as one with risks allowing actor-isolated values to escape their isolation domain through a result of an invocation of value}}
takeFnWithSendingResult(functionWithSendingResult)
takeFnWithSendingResult(functionWithoutSendingResult)
// expected-error @-1 {{converting a value of type '@Sendable () -> NonSendableKlass' to type '() -> sending NonSendableKlass' risks causing data races}}
// expected-note @-2 {{converting a function typed value without a sending result as one with risks allowing actor-isolated values to escape their isolation domain through a result of an invocation of value}}
let x: () -> NonSendableKlass = { fatalError() }
takeFnWithSendingResult(x)
// expected-error @-1 {{converting a value of type '() -> NonSendableKlass' to type '() -> sending NonSendableKlass' risks causing data races}}
// expected-note @-2 {{converting a function typed value without a sending result as one with risks allowing actor-isolated values to escape their isolation domain through a result of an invocation of value}}
takeFnWithoutSendingResult(functionWithSendingResult)
takeFnWithoutSendingResult(functionWithoutSendingResult)
takeFnWithoutSendingResult(x)
}
//////////////////////////
// MARK: Protocol Tests //
//////////////////////////
struct MatchSuccess : ProtocolWithSendingReqs, ProtocolWithMixedReqs {
func sendingResult() -> sending NonSendableKlass { fatalError() }
func nonSendingParam(_ x: NonSendableKlass) -> () { fatalError() }
func nonSendingParamAndSendingResult(_ x: NonSendableKlass) -> sending NonSendableKlass { fatalError() }
}
struct FailToMatch : ProtocolWithSendingReqs, ProtocolWithMixedReqs {
// expected-error@-1 {{type 'FailToMatch' does not conform to protocol 'ProtocolWithSendingReqs'}}
// expected-error@-2 {{type 'FailToMatch' does not conform to protocol 'ProtocolWithMixedReqs'}}
// expected-note@-3 {{add stubs for conformance}}
func sendingResult() -> NonSendableKlass { fatalError() }
// expected-note @-1 {{candidate has non-matching type '() -> NonSendableKlass'}}
func nonSendingParam(_ x: sending NonSendableKlass) -> () { fatalError() }
// expected-note @-1 {{candidate has non-matching type '(sending NonSendableKlass) -> ()'}}
func nonSendingParamAndSendingResult(_ x: sending NonSendableKlass) -> NonSendableKlass { fatalError() }
// expected-note @-1 {{candidate has non-matching type '(sending NonSendableKlass) -> NonSendableKlass'}}
}
struct FailToMatch2 : ProtocolWithMixedReqs { // expected-error {{type 'FailToMatch2' does not conform to protocol 'ProtocolWithMixedReqs'}} expected-note {{add stubs for conformance}}
func nonSendingParamAndSendingResult(_ x: sending NonSendableKlass) -> NonSendableKlass { fatalError() }
// expected-note @-1 {{candidate has non-matching type '(sending NonSendableKlass) -> NonSendableKlass'}}
}
struct FailToMatch3 : ProtocolWithMixedReqs { // expected-error {{type 'FailToMatch3' does not conform to protocol 'ProtocolWithMixedReqs'}} expected-note {{add stubs for conformance}}
func nonSendingParamAndSendingResult(_ x: NonSendableKlass) -> NonSendableKlass { fatalError() }
// expected-note @-1 {{candidate has non-matching type '(NonSendableKlass) -> NonSendableKlass'}}
}
struct FailToMatch4 : ProtocolWithMixedReqs { // expected-error {{type 'FailToMatch4' does not conform to protocol 'ProtocolWithMixedReqs'}} expected-note {{add stubs for conformance}}
func nonSendingParamAndSendingResult(_ x: sending NonSendableKlass) -> sending NonSendableKlass { fatalError() }
// expected-note @-1 {{candidate has non-matching type '(sending NonSendableKlass) -> sending NonSendableKlass'}}
}