Otherwise if the member lookup gets simplified immediately and we
have a recursive dynamic member lookup we will crash since we wouldn't
have introduced the corresponding applicable function constraint.
rdar://164321858
This works around the fact that existential opening does not currently
work correctly in cases where the argument isn't resolved before the
applicable fn is solved.
Previously we would incorrectly attempt to treat a nested dynamic member
lookup for a subscript as a member reference. Fix `isSubscriptMemberRef`
such that we treat it as a subscript reference.
A read access asserts that the memory location is immutable for the duration
of the access, so it can be treated as a borrow rather than a mutable lvalue.
Doing this allows the borrow formal access scope fixes from #79084 to apply
to situations where a loadable type undergoes an accessor-based access with
indirect arguments (such as for public accessors when library evolution is
enabled for the type). Fixes rdar://143334632.
The return pointer may point into the materialized base value, so if the base needs
materialization, ensure that materialization covers any futher projection of the
value.
Type annotations for instruction operands are omitted, e.g.
```
%3 = struct $S(%1, %2)
```
Operand types are redundant anyway and were only used for sanity checking in the SIL parser.
But: operand types _are_ printed if the definition of the operand value was not printed yet.
This happens:
* if the block with the definition appears after the block where the operand's instruction is located
* if a block or instruction is printed in isolation, e.g. in a debugger
The old behavior can be restored with `-Xllvm -sil-print-types`.
This option is added to many existing test files which check for operand types in their check-lines.
KeyPath's getter/setter/hash/equals functions have their own calling
convention, which receives generic arguments and embedded indices from a
given KeyPath argument buffer.
The convention was previously implemented by:
1. Accepting an argument buffer as an UnsafeRawPointer and casting it to
indices tuple pointer in SIL.
2. Bind generic arguments info from the given argument buffer while emitting
prologue in IRGen by creating a new forwarding thunk.
This 2-phase lowering approach was not ideal, as it blocked KeyPath
projection optimization [^1], and also required having a target arch
specific signature lowering logic in SIL-level [^2].
This patch centralizes the KeyPath accessor calling convention logic to
IRGen, by introducing `@convention(keypath_accessor_XXX)` convention in
SIL and lowering it in IRGen. This change unblocks the KeyPath projection
optimization while capturing subscript indices, and also makes it easier
to support WebAssembly target.
[^1]: https://github.com/apple/swift/pull/28799
[^2]: https://forums.swift.org/t/wasm-support/16087/21
The Swift Simplification pass can do more than the old MandatoryCombine pass: simplification of more instruction types and dead code elimination.
The result is a better -Onone performance while still keeping debug info consistent.
Currently following code patterns are simplified:
* `struct` -> `struct_extract`
* `enum` -> `unchecked_enum_data`
* `partial_apply` -> `apply`
* `br` to a 1:1 related block
* `cond_br` with a constant condition
* `isConcrete` and `is_same_metadata` builtins
More simplifications can be added in the future.
rdar://96708429
rdar://104562580
The pass is already not being run during normal compilation scenarios today
since it bails on OSSA except in certain bit-rot situations where a test wasn't
updated and so was inadvertently invoking the pass. I discovered these while
originally just trying to eliminate the pass from the diagnostic pipeline. The
reason why I am doing this in one larger change is that I found there were a
bunch of sil tests inadvertently relying on guaranteed arc opts to eliminate
copy traffic. So, if I just removed this and did this in two steps, I would
basically be unoptimizing then re-optimizing the tests.
Some notes:
1. The new guaranteed arc opts is based off of SemanticARCOpts and runs only on
ossa. Specifically, in this new pass, we just perform simple
canonicalizations that do not involve any significant analysis. Some
examples: a copy_value all of whose uses are destroys. This will do what the
original pass did and more without more compile time. I did a conservative
first approximation, but we can probably tune this a bit.
2. the reason why I am doing this now is that I was trying to eliminate the
enable-ownership-stripping-after-serialization flag and discovered that the
test opaque_value_mandatory implicitly depends on this since sil-opt by
default was the only place left in the compiler with that option set to false
by default. So I am eliminating that dependency before I land the larger
change.
Failing tests that do not test mandatory combine are updated to skip
the mandatory combine pass. Othere tests are updated to use otherwise
removed values.
Fix a crash in dynamic member lookup attempting to recursively
lookup a member on the same base type.
The problem is related to `isSelfRecursiveKeyPathDynamicMemberLookup`
which failed to look through l-value wrapping base type on each side of
the comparison, that's important because it's possible to have l-value
mismatch due to the fact that implicit call always gets l-value base
type but actual subscript which triggered dynamic lookup might be r-value.
Resolves: [SR-11743](https://bugs.swift.org/browse/SR-11743)
Resolves: rdar://problem/57091169
Change the locator for the applicable fn
constraint for the inner subscript reference in an
implicit `outer[dynamicMember: \Inner.[0]]` expr
such that it uses the member locator with a
KeyPathDynamicMember element.
Then add a case to `getCalleeLocator` to handle
these locators. We also need to handle this
specially in `getArgumentInfoLocator` due to the
fact that the argument labels for the inner
subscript reference correspond to those written
by the user for the outer subscript reference.
Resolves SR-11933.
Resolves rdar://problem/57824025.
Previously we were just searching for a resolved
overload with the same component index and anchor
for the key path. However unfortunately that found
dynamic member lookup overloads in certain cases,
leading to an incorrect mutability capability.
Change the logic such that it uses the callee
locator for a given key path component, ensuring
we only match against the "direct" callee, and
not any dynamic members it might be also referring
to.
Resolves SR-11896.
Previously we were only handling IUO unwrapping in
visitKeyPathExpr, but not for callers that were
building their own property and subscript
components such as dynamic member lookup.
Move the IUO unwrapping logic into
buildKeyPath[Property/Subscript]Component,
and adjust their signatures to allow them to
append multiple components. Also add
buildKeyPathOptionalForceComponent to allow more
convenient adding of an optional force component.
Resolves SR-11893.
This only comes into play when all other choices are coming from
constrained extensions, because there is no way to determine upfront
whether any are going to match it's better to be safe and add
key path dynamic member choice to the set too.
Resolves: [SR-11465](https://bugs.swift.org/browse/SR-11465)
Resolves: rdar://problem/55314724
Since key path dynamic member depends on information from
`applicable function` constraint associated with invocation
it can't be eagerly solved during constraint generation
phase, so it has to be delayed until actual solving starts.
Subscripts used to always have at least one choice - `keypath application`,
which along with actual valid choices always formed a disjunction.
That is no longer the case since `keypath application` is added
only when it makes sense, which means delayed dynamic member
constraint has to be added to "active" list to get re-attempted.
Currently if there is a conditional conformance to a type marked
as `@dynamicMemberLookup` with member that shadows one accessible
through dynamic lookup we'd report an error if that conformance
has not been satisfied.
Better behavior would be to consider dynamic member lookup and
if that fits let the expression type-check.
Resolves: rdar://problem/52779809
This fixes an oversight related to `ReferenceWritableKeyPath` overloads
of the KeyPath dynamic member lookup. Original check filtered out only
`WritableKeyPath` if the storage is read-only, but it should check for
both `WritableKeyPath` and `ReferenceWritableKeyPath`, otherwise program
is going to crash at run time.
Resolves: rdar://problem/51456614
For example if there a structure which requires multiple implicit
dynamic member calls to get the members:
```swift
struct Point { var x, y: Int }
@dynamicMemberLookup
struct Lens<T> {
var obj: T
subscript<U>(dynamicMember member: KeyPath<T, U>) -> U {
get { return obj[keyPath: member] }
}
}
func foo(_ lens: Lens<Lens<Point>>) {
_ = lens.x
_ = lens.obj.x
_ = lens.obj.obj.x
}
_ = \Lens<Lens<Point>>.x
```