-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Sema] Don't look through CoerceExprs in markDirectCallee #27085
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Sema] Don't look through CoerceExprs in markDirectCallee #27085
Conversation
Doing so prevented the coercion of a function with argument labels to a user-written function type, as the latter cannot contain argument labels. This commit changes the behaviour such that the referenced function is considered to be unapplied, meaning it has its argument labels stripped, therefore allowing the coercion. Resolves SR-11429.
@swift-ci please test |
@swift-ci please test source compatibility |
Build failed |
@swift-ci please test OS X platform |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems right to me but @xedin would be a better person to check with. I think someone from the core team should probably say this is okay but it does seem obviously correct. That comment about disambiguation does seem possible, though.
@jrose-apple I believe the comment about disambiguation was made back when function types could have argument labels, so you could do things like: func foo(x: Int) {}
func foo(y: Int) {}
(foo as (x: Int) -> Void)(x: 5)
(foo as (y: Int) -> Void)(y: 5) But AFAIK it's no longer possible to perform such disambiguation using an intermediate coercion. |
I thought it's still potentially relevant for things like func foo(x: Int8) {}
func foo(x: UInt8) {}
(foo as (Int8) -> Void)(5) …except that that already doesn't work
and you'll note I left out the label
So maybe we're in the clear. |
@jrose-apple Yeah, because we mark (overloaded) decl ref |
Function types with argument labels are definitely not meant to be part of the type system, and it's mostly a historical artifact that this can be represented at all. |
I wonder if rdar://36209605 is related:
|
@slavapestov That's indeed a similar issue, though an We ought to be treating it as struct S {
static func foo(_ x: Int) -> S! { S() }
}
let s: S = .foo(_:)(5) Unless we change the rules such that IUO unwraps are allowed through compound references which are otherwise directly applied. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does seem reasonable to me and I'm be fine breaking the case mentioned in the description to make the behavior consistent, but I think we still need a core team sign-off on that. @DougGregor could you please take a look as well?
Sorry for the delay; I'll bring this up with the core team |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Core Team discussed this today and has approved the change. Thanks for your patience!
@swift-ci please test |
Build failed |
Build failed |
@swift-ci please smoke test |
Worth mentioning in the CHANGELOG, since it both fixes a source-level issue and breaks obscure code? |
@jrose-apple Sure thing! I'll try and open a PR tomorrow. |
Doing so prevented the coercion of a function with argument labels to a user-written function type, as the reference would keep its argument labels due to being marked as "directly applied", but this would then prevent its coercion as the written function type cannot contain argument labels:
This PR changes the behaviour such that the referenced function is considered to be unapplied, meaning it has its argument labels stripped, therefore allowing the coercion.
I'm unsure if this change requires any Swift evolution discussion – it is technically source breaking, as it's currently possible to use a generic type alias to make the compiler infer a function type with argument labels:
But I would hope nobody is actually writing code like this, and I can't think of any other compelling examples that would break because of this change.
Resolves SR-11429.