Open mbrandonw opened 5 years ago
Hi @jckarter! We ran into this one today. It has a pretty simple repro.
I wouldn't expect IUO forcing to "win" the type check here. cc @rudkx @xedin
@jckarter Looks like There is only one solution we find in this case which requires `currencyCode` to be force unwrapped, because `set` function type is - (WriableKeyPath\<T, U>, U)` and we attempt `String` first based on type of `code`. `String?` could be attempted in this case but only if `String` where to fail, but it doesn't because there is a IUO involved.
Unfortunately it doesn't seem like we could do much in this case from type-checker perspective, @rudkx Any ideas?
It seems like this ought to work and the fact that it doesn't today is an artifact of some implementation choices.
I took a quick look yesterday and it appeared that we were only attempting `String` for the type, but it seems like it would be reasonable to defer binding the type for the type variable until after we've selected a type for `Root` and determined the type of `currencyCode`.
@rudkx Yes, it seems like there is an ordering problem for this example but I'm not sure what the sane rule for changing it might be:
($T1 involves_type_vars bindings={(supertypes of) NumberFormatter})
($T2 involves_type_vars bindings={(supertypes of) String})
($T6 involves_type_vars bindings={(subtypes of) WritableKeyPath<$T1, $T2>})
Initial bindings: $T1 := NumberFormatter
(attempting type variable $T1 := NumberFormatter
($T2 involves_type_vars bindings={(supertypes of) String})
($T6 involves_type_vars bindings={(subtypes of) WritableKeyPath<NumberFormatter, $T2>})
Initial bindings: $T2 := String
(attempting type variable $T2 := String
($T6 bindings={(subtypes of) WritableKeyPath<NumberFormatter, String>})
Initial bindings: $T6 := WritableKeyPath<NumberFormatter, String>
(attempting type variable $T6 := WritableKeyPath<NumberFormatter, String>
(overload set choice binding $T4 := @lvalue String?)
($T4 involves_type_vars bindings={(subtypes of) String})
(attempting disjunction choice $T4 bind @lvalue String? [[locator@0x7fbe391cad28 [KeyPath@<REPL Input>:1:5 -> key path component #​0 -> implicitly unwrapped disjunction choice]]];
(failed constraint $T4 equal $T5 [[locator@0x7fbe391ca628 [KeyPath@<REPL Input>:1:5]]];)
)
(attempting disjunction choice $T4 bind @lvalue String [[locator@0x7fbe391cad28 [KeyPath@<REPL Input>:1:5 -> key path component #​0 -> implicitly unwrapped disjunction choice]]];
(increasing score due to force of an implicitly unwrapped optional)
(found solution 0 0 1 0 0 0 0 0 0 0 0)
)
)
)
)
In this case $T6 is worse than either $T1 and $T2. If we had a disjunction associated with $T4 earlier that would have helped, but is that possible?
Environment
Xcode 10.1 (10B61) Swift 4.2Additional Detail from JIRA
| | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: 615ff1c11387ed7d548c7b719f700cc6Issue Description:
The following code crashes:
with the stack trace:
Two different things will fix it:
or