We inadvertantly allowed this in the past, so continue to do so when
compiling in Swift 3/4 mode to avoid suddenly breaking existing code.
The diagnostic here is pretty bad, and I've opened issues for that as
well as providing some kind of deprecation warning for this so that
even under Swift 3/4 mode we alert users that this is unsupported.
rdar://problem/39802797
`AbstractStorageDecl::isSettable` by itself doesn't account for access control, so we need to check `isSetterAccessibleFrom` as well. Furthermore, key paths should not get the special context-sensitive privileges direct accesses do, such as initializers being able to assign into `let` properties. Fix the type checking logic here to only create a statically writable KeyPath value when the referenced declaration has a setter visible independent of current context. Fixes SR-6667 | rdar://problem/36257266.
When testing KeyPathApplication constraints, we would keep going after rejecting a concrete KeyPath application by trying PartialKeyPath and AnyKeyPath, even though that's not what we want, since any key path application expression can type check with an AnyKeyPath. We would then miscompile by building the AST such that we applied the mismatched key path expression directly to the base. We also didn't handle expressions where the base was a subtype of the key path's base type correctly—the conversion means the base can't be written through in this situation, and we hardcoded the concrete-to-existential case instead of handling general conversions. Fix these problems, and add an AST verifier for KeyPathApplicationExprs to help catch problems in the future. Fixes SR-6300 | rdar://problem/35368903.
We can wind up in a situation where the base of a keypath
application is concrete but is being applied to a keypath
with an existential source type. Coerce the base to the
intended type if necessary when building the final subscript
expression.
Resolves SR-5878.
We want the type of a KeyPathExpr to be the specific *KeyPath<T, U> subclass appropriate for the literal, with upcasts to a more general contextual type, since we rely on that invariant elsewhere to extract the base and projected value types. Fixes SR-5008 | rdar://problem/32395076.
Add an explicit argument label to the subscript declarations used in the
tests so that x[keyPath:] refers to the subscript rather than the
keypath.
Update test output accordingly.
When this score kind was added, the marker for the last score kind was
not updated. As a result, increasing the score for SK_KeyPathSubscript
was not actually having an effect.
Add tests that include a type with subscripts that also take the key
paths as their argument with an identical argument label ("keyPath").
These tests show that we're actually falling back on the keypath
application in many cases despite the score kind specific to keypath
application. I'll open a couple new JIRAs to investigate this
behavior.
The update to SK_LastScoreKind results in fixing a crash in these tests
that happens as a result of an assumption in CSRanking.cpp that if we're
comparing two solutions we end up with decls for overloads to compare,
which isn't the case here due to the keypath application.
And make an attempt to use the constraint system's contextualType to bind type information; this makes things better but doesn't seem to be a complete solution for contextually typing key paths.
It's particularly likely someone will try to type `\(foo)`, which looks like a string interpolation segment, outside of a string literal, so give that case a special diagnostic. Fixes rdar://problem/32315365.
This is a bit more robust and user-friendly than hoping more brittle recovery in SILGen or IRGen for unsupported components kicks in. rdar://problem/32200714
We had an inconsistency in the handling of ConstraintKind::Equal in that
we would take
$T1 Equal $T2
where $T2 was previously bound to a type, and bind the RValue type of
$T2's type to $T1. That does not allow for us to later attempt to bind
the LValue type of that type to $T1 (as might happen in simplifying an
OptionalObject constraint).
Instead, if $T1 can be bound to an LValue and $T2 is not an LValue,
we'll defer simplifying the Equal constraint until after $T1 is bound
through some other type variable binding or constraint simplification.
Fixes rdar://problem/31724272.
The delcared type was incorrect here as opposed to the type checker
incorrectly diagnosing a problem. Fix the test and add another test
without a subscript operation to ensure that it works.
This introduces a few unfortunate things because the syntax is awkward.
In particular, the period and following token in \.[a], \.? and \.! are
token sequences that don't appear anywhere else in Swift, and so need
special handling. This is somewhat compounded by \foo.bar.baz possibly
being \(foo).bar.baz or \(foo.bar).baz (parens around the type), and,
furthermore, needing to distinguish \Foo?.bar from \Foo.?bar.
rdar://problem/31724243
TODO:
- Select the KeyPath subclass corresponding to the write capability of the key path components
- Figure out an issue with unresolved solutions being chosen with contextually-typed keypaths
- Diagnostic QoI
Implement the Objective-C #keyPath expression, which maps a sequence
of @objc property accesses to a key-path suitable for use with
Cocoa[Touch]. The implementation handles @objc properties of types
that are either @objc or can be bridged to Objective-C, including the
collections that work with key-value coding (Array/NSArray,
Dictionary/NSDictionary, Set/NSSet).
Still to come: code completion support and Fix-Its to migrate string
literal keypaths to #keyPath.
Implements the bulk of SR-1237 / rdar://problem/25710611.