-
Notifications
You must be signed in to change notification settings - Fork 10.6k
[ConstraintSystem] More changes to key path inference #69742
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
[ConstraintSystem] More changes to key path inference #69742
Conversation
…s a key path root type
As a first step in delaying key path type until all of the members are resolved, attempt to infer a type of root based on bindings associated with key path type.
…s known Since key path root is now transitively inferred. Key path type inference can be delayed until key path is resolved enough to infer its capability. This solves multiple problems: - Inference fully controls what key path type is bound to; - KeyPath constraint simplification doesn't have to double-check the capability and attempt to re-bind key path type; - Custom logic to resolve key path type is no longer necessary; - Diagnostics are improved because capability and root/value type mismatch are diagnosed when key path is matched against the contextual type.
The capability inference is now handled by the binding inference and that makes resolved key path matching to bound type is no longer necessary.
`DerivedToBaseExpr` is inserted when key path literal is upcast to its superclass, diagnostics related to `@objc dynamic` should account for that.
…ument to non-key path parameter Produce a tailored diagnostic that omits a fully unresolved key path type (`KeyPath<_, _>`) when key path without an explicit root type is passed as an argument to non-keypath parameter type (i.e. `Int`).
… individually In general the solver attempts to gather all of the generic argument mismatches into a single fix because there could be an arbitrary number of generic arguments. This is uncessary for key path literals matching against a contextual type because they have at most two generic arguments (Root and Value), so it's better to produce fixes for root and value type individually.
|
@swift-ci please test |
|
@swift-ci please test source compatibility |
|
The main idea here is that the solver gets to infer the root transitively from the bindings associated with key path type, that allows all of the references in a key path literal to be resolved and subsequently the key path type can be determined based on the capability instead of eagerly binding it to a contextual type, this give the solver more control over key path inference and helps with diagnostics because fixes could be applied at the point where key path type is converted a contextual type (i.e. parameter type or an explicit initializer type). |
lib/Sema/CSBindings.cpp
Outdated
|
|
||
| // Functions don't have capability so we can simply add them. | ||
| if (bindingTy->is<FunctionType>()) | ||
| updatedBindings.insert(binding); |
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.
I think in this case we can form a function type that uses root/value type variables and infers parameter flags from the binding, does that make sense, @Jumhyn? If we can make it work then I can remove remaining root/value matching logic from simplifyKeyPathConstraint.
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.
Actually I think I can approach that from a different angle. I Remembered that there is a hack to eagerly bind key path type if the contextual type is a function type. I think once I remove that everything and replace function result type with key path's value type everything is going to fall into place.
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.
Sorry @xedin was out of town last week, but the current solution LGTM!
Optional chaining is related to the key path value and not the key path type itself.
…other choice If key path literal type is converted to a function type, it's always the best course of action to use such a binding and forego adding a KeyPath type binding based on capability because it would never match. This applies to invalid key pathes as well because we'd want to propagate as much contextual information from the key path literal into the context as possible.
…function type This is no longer necessary for diagnostics or anything else because inference decides the type now.
|
@swift-ci please test |
|
@swift-ci please test source compatibility |
Infer key path root bindings transitively
As a first step in delaying key path type until all of the members are
resolved, attempt to infer a type of root based on bindings associated
with key path type.
Delay key path type inference until literal capability is known
Since key path root is now transitively inferred. Key path type
inference can be delayed until key path is resolved enough to
infer its capability.
This solves multiple problems:
the capability and attempt to re-bind key path type;
mismatch are diagnosed when key path is matched against the
contextual type.
Improve contextual mismatch diagnostics related to key path literals.