Skip to content

Commit 07d0cfa

Browse files
committed
Allow overloads with varying @sendable func types
Specifically, an override can validly have a parameter type that is not `@Sendable` or a function type that is `@Sendable` even if that contradicts the base declaration. That’s becuase it’s always valid to provide a sendable function when one is not actually needed, but not vice versa.
1 parent 1b4b5f5 commit 07d0cfa

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

lib/AST/Type.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3167,6 +3167,11 @@ static bool matchesFunctionType(CanAnyFunctionType fn1, CanAnyFunctionType fn2,
31673167
matchMode.contains(TypeMatchFlags::AllowABICompatible))) {
31683168
ext1 = ext1.withThrows(true);
31693169
}
3170+
3171+
// Removing '@Sendable' is ABI-compatible because there's nothing wrong with
3172+
// a function being sendable when it doesn't need to be.
3173+
if (!ext2.isSendable())
3174+
ext1 = ext1.withConcurrent(false);
31703175
}
31713176

31723177
// If specified, allow an escaping function parameter to override a

test/attr/attr_concurrent.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,17 @@ func testExplicitConcurrentClosure() {
125125
}
126126
let _: String = fn // expected-error{{cannot convert value of type '@Sendable () -> Int' to specified type 'String'}}
127127
}
128+
129+
class SuperSendable {
130+
func runsInBackground(_: @Sendable () -> Void) {}
131+
func runsInForeground(_: () -> Void) {} // expected-note {{potential overridden instance method 'runsInForeground' here}}
132+
func runnableInBackground() -> @Sendable () -> Void { fatalError() } // expected-note {{potential overridden instance method 'runnableInBackground()' here}}
133+
func runnableInForeground() -> () -> Void { fatalError() }
134+
}
135+
136+
class SubSendable: SuperSendable {
137+
override func runsInBackground(_: () -> Void) {}
138+
override func runsInForeground(_: @Sendable () -> Void) {} // expected-error {{method does not override any method from its superclass}}
139+
override func runnableInBackground() -> () -> Void { fatalError() } // expected-error {{method does not override any method from its superclass}}
140+
override func runnableInForeground() -> @Sendable () -> Void { fatalError() }
141+
}

0 commit comments

Comments
 (0)