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
[SR-11654] Optional wrapped property can't be passed to generic function #54065
Comments
Very weird. Thanks for the reduced test case! @swift-ci create |
Definitely weird! Another workaround is to define a method or a computed property on |
Test case that doesn't include Combine and throws the same error: struct User {}
@propertyWrapper struct Wrapper<T> {
var wrappedValue: T
}
class Test {
@Wrapper var user: User?
}
func genericFunc<T>(_ argument: T?) -> T? {
return argument
}
let test = Test()
genericFunc(test.user) // fail Looking into this a bit more, we're adding an additional constraint:
which is causing the solver to reject the first choice:
So for some reason, we're inferring the type of the generic parameter Seems like it has something to do with potential bindings we are generating, because I can see that in the working case, we have: $T1 potentially_incomplete involves_type_vars bindings={} @ locator@0x7fa447007250 [DeclRef@/Users/suyashsrijan/Desktop/test.swift:15:1 -> generic parameter 'T'] but in this case, we have: $T1 potentially_incomplete involves_type_vars bindings={(supertypes of) Wrapper<User?>} @ locator@0x7fa447007250 [DeclRef@/Users/suyashsrijan/Desktop/test.swift:15:1 -> generic parameter 'T'] cc @xedin who might know what's going on Also, there's another bug - the diagnostic we're suggesting is not correct i.e. we're saying to use the backing variable ( |
Comment by Michael Ozeryansky (JIRA) @theblixguy, very nice explanation. Why do you think wrapping the variable in parenthesis worked fine? i.e. `genericFunc((test.user))`. I would have assumed the compiler would remove that since, I believe, it's a parenthesized-expression and shouldn't change its type. |
The reason why it works with parenthesis is related to how constraint solver handles optionals - it would just go through a different path when for this conversion between argument is going to be `ParenType(User?)` instead of just `User?`. @theblixguy After taking a quick look at this - it seems like the reason why it's happening is related to how `simplifyRestrictedConstraintImpl` handles `ValueToOptional` vs. `OptionalToOptional`. It looks like both need to be taught how to handle existence of property wrappers. |
I can take a stab at fixing it, although I’m not sure how to go about fixing it correctly. Do we need to call matchTypes with the property wrapper type? |
@theblixguy I think first step would be to figure out how it happens that solver ends up adding `Wrapper<User?> subtype $T1`, that should give you an idea how to go about it. To make it somehow easier we know that wrapping type in parens doesn't result in that constraint. |
yeah, I am trying to figure that out. I actually put a check in |
Sounds good! It might be easier to put a break point to each place where `OptionalPayload` is added to the locator builder, there should be just a couple of places in CSSimplify.cpp |
Sure, the only place it seems to be used is |
That might be too far. I'd suggest you start in `matchCallArguments`, here - https://github.com/apple/swift/blob/master/lib/Sema/CSSimplify.cpp#L1098 that's the place where argument type is going to be matched to parameter - I think a that point we'd still have `User?` vs. `T?` but what happens next and how we get to `Wrapper<User?>` I have no idea. |
@xedin Okay,
Previously, it failed at that disjunction choice due to |
You previously said "figure out how it happens that solver ends up adding `Wrapper<User?> subtype $T1`, that should give you an idea how to go about it.", so I think we now know how this is being added. Now, the next step I guess is to figure out how do we fix this. |
@theblixguy That's something I suspected, we shouldn't really be generating any constraints in `repairFailures` but we have no choice at the moment sometimes... I think we should try to move this check up before `fixPropertyWrapperFailure` or move `fixPropertyWrapperFailure` after that check. |
Also verify that neither side is a type variable before trying to fix property wrappers. |
Comment by Michael Ozeryansky (JIRA) Thank you! |
Additional Detail from JIRA
md5: af43c2e4854ca43112ad7636efacc0ca
is duplicated by:
relates to:
Issue Description:
When I pass a property which is declared as `@Published` to a generic function, I get an error referring to the published value. It's fine anywhere else where I use the variable, just not when passing into the generic function.
Error:
Here's the playground code:
The best I have been able to do is wrap the value in parenthesis, like so:
Stackoverflow Question
The text was updated successfully, but these errors were encountered: