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
[CSSolver] Use correct locator when matching function result types re… #14846
Conversation
73433a3
to
7f9dd24
Compare
fyi, i'm taking a careful look at this |
I think this seems reasonable if slightly precarious. I suspect I am going to end up substantially reworking/replacing |
@rudkx Ok, sounds good! I'll try to figure out what do we need to do to make this work in |
@rjmccall @jckarter Looks like I'd need some help from you here, it seems like I can fix up the assert at https://github.com/apple/swift/blob/master/lib/SILGen/SILGenPoly.cpp#L1880, but when I do so it fails at So I'm wondering what would be the best approach here? I guess since it's trying to convert function which returns something to function which returns nothing it could be fine to just drop the result type on the floor? |
Simpler example: struct S<T> {
init(_ a: () -> T, _ b: () -> T) {}
}
func foo() -> Int { return 42 }
func bar() -> Void {}
_ = S({ foo() }, { bar() }) |
Dropping a result isn't always an ABI-compatible function conversion if the result is returned indirectly or needs to be released. We ought to be emitting a thunk when this conversion happens. The failures you're seeing suggest to me that isn't happening. |
@jckarter Sorry if it wasn’t clear but it fails while trying to emit such a thunk, it seems like it doesn’t support converting result from something to void... |
@jckarter What is the best way to express in result planner conversion from something to void? |
If we're converting a result to void, then we need to destroy the result value(s) and produce an empty tuple. |
@jckarter Could you please elaborate where I could start to figure out how to do that? :) |
/cc @rjmccall Please take a look! I'm pretty sure I've done it incorrectly, but I tried... |
@swift-ci please smoke test |
lib/SILGen/SILGenPoly.cpp
Outdated
if (innerOrigType.isTuple()) { | ||
auto innerTuple = cast<TupleType>(innerSubstType); | ||
for (unsigned i = 0, n = innerTuple->getNumElements(); i != n; ++i) | ||
ignoreNextResult(); |
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 needs be recursive — we expand tuples recursively, so this needs to do it, too.
- This needs to follow the inner abstraction pattern, not the inner substituted type. There could be a generic type that's been substituted to a tuple.
I would suggest breaking this out as a method on the planner.
…lated to closures Currently we always use 'FunctionResult' as a path element when matching function result types, but closure result type is allowed to be implicitly converted to Void, which means we need to be careful when to use 'FunctionResult' and 'ClosureResult'. Resolves: rdar://problem/37790062
@swift-ci please test |
@swift-ci please test source compatibility |
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.
Thanks, that looks good.
…lated to closures
Currently we always use 'FunctionResult' as a path element when matching
function result types, but closure result type is allowed to be implicitly
converted to Void, which means we need to be careful when to use
'FunctionResult' and 'ClosureResult'.
Resolves: rdar://problem/37790062