Variable debug info is triggered by pattern bindings, however, inside a closure
capture list, this should be avoided by setting the appropriate flag in the
initializer object.
rdar://110329894
We can probably avoid this copy in more circumstances, but make the change only for
noncopyable types for now, since that's the case where it's most semantically apparent.
rdar://109161396
A reference to an instance property in init accessor body
has to be remapped into an argument reference because all
of the properties from initialized/accesses lists are passed
to init accessors individually via arguments.
drop_deinit ultimately only affects the semantics of its
destroy_value. Avoid generating releases for destroys in which the
deinit has been dropped. Instead, individually release the members.
Pattern matching as currently implemented is consuming, but that's not
necessarily what we want to be the default behavior when borrowing pattern
matching is implemented. When a binding of noncopyable type is pattern-matched,
require it to be annotated with the `consume` operator explicitly. That way,
when we introduce borrowing pattern matching later, we have the option to make
`switch x` do the right thing without subtly changing the behavior of existing
code. rdar://110073984
Calls to getters are implicit because the compiler inserts them on a property
access, but the location is useful in backtraces so it should be preserved.
rdar://109123395
Some notes:
1. I put in both a swiftpm like test case and a library evolution test case. I
also updated the moveonly_deinit serialization swift test to show that we
actually serialize the deinit.
2. I changed when we emit the deinit table to only be when we have a type with
an actual value type destructor. Notably this doesn't include classes today so
as a side-effect, we no longer attempt to devirtualize moveonly class deinits.
This doesn't affect anything we are trying to actually do since we do not
support noncopyable classes today. With that in mind, I changed one test that
was showing that deinit devirtualization worked to use a struct with deinit
instead of a class.
rdar://109679168
The form of the AST changes slightly when a type has a read and a modify.
Specifically, we now have a load on the subscript and an inout_expr on the base.
I dealt with this by making the inout_expr something that when we look for
storage we look through and by tweaking the load lookthrough code.
Most of the time SILGen already emits these correctly without having extra
copies, but in certain situations SILGen will emit copies that we need the move
checker to eliminate (e.x.: when we generate a yield). An additional benefit is
that this also will catch places where the frontend makes a mistake.
This also removes a bunch of "copy of noncopyable" types error that showed up in
the implicit compiler generated modify.
I also added a bunch of tests that showed the behavior of subscripts/other accessors with the following combinations of semantics:
1. get only.
2. get/set.
3. get/modify.
4. read/set.
5. read/modify.
rdar://109746476
Change SILGen to emit the `debug_value` instruction using the original inout
parameter address, instead of the `mark_must_check` inserted for move-only
parameters, because code in the MoveOnlyAddressChecker did not expect to
find the debug_value anywhere but on the original address. Update move-only
diagnostics so that they pick up the declaration name for a memory location
from any debug_value instruction if there are more than one. rdar://109740281
NOTE: This does not affect normal parameters since normal parameters that are
noncopyable never have default access semantics since the user is forced to
specify either borrow or consume. This is incontrast to implicit parameters like
the newValue of a setter.
rdar://109726282
Before this change it was possible to:
1. Call mutating methods on a consume result.
2. assign into a consume (e.x.: var x = ...; (consume x) = value.
From an implementation perspective, this involved just taking the logic I
already used for the CopyExpr and reusing it for ConsumeExpr with some small
tweaks.
rdar://109479440
Some notes:
1. I implemented this as a contextual keyword that can only apply directly to
lvalues. This ensures that we can still call functions called copy, define
variables named copy, etc. I added tests for both the c++ and swift-syntax based
parsers to validate this. So there shouldn't be any source breaks.
2. I did a little bit of type checker work to ensure that we do not treat
copy_expr's result as an lvalue. Otherwise, one could call mutating functions on
it or assign to it, which we do not want since the result of copy_value is
3. As expected, by creating a specific expr, I was able to have much greater
control of the SILGen codegen and thus eliminate extraneous copies and other
weirdness than if we used a function and had to go through SILGenApply.
rdar://101862423
When opaque values are enabled, we do not need this store_borrow. This was
caught by the following tests:
Swift(macosx-x86_64) :: SILGen/opaque_values_silgen.swift
Swift(macosx-x86_64) :: SILGen/opaque_values_silgen_resilient.swift
This ensures that given a class that contains a noncopyable type that contains
another noncopyable type:
```
@_moveOnly struct S2 {}
@_moveOnly struct S { var s2: S2 }
class C { var s: S }
```
if we call a resilient function that takes C.S.S2:
```
borrowVal(c.s.s2)
```
we properly spill s2 onto the stack using a store_borrow.
Why Do This?
------------
Currently SILGenLValue treats ref_element_addr as a base that it needs to load
from for both copyable and non-copyable types. We keep a separation of concerns
and require emission of resilient functions to handle these loaded values. For
copyable types this means copying the value and storing it into a temporary
stack allocation. For noncopyable types, we never actually implemented this so
we would hit an error in SILGenApply telling us that our resilient function
expected an address argument, but we are passing an object.
To work around this, I updated how we emit borrowed lvalue arguments to in this
case to spill the value into a temporary allocation using a store_borrow. I also
included a test that validates that we properly have a read exclusivity scope
around the original loaded from memory for the entire call site so even though
we are performing a load_borrow and then spilling it, we still have read
exclusivity to the original memory for the entire region meaning that we still
preserve the semantics.
rdar://109171001
The previous code made the assumption that the ASTScope for a variable
declaration should be the one of the declaration's source location. That is not
necessarily the case, in some cases it should be an ancestor scope. This patch
introduces a map from ValueDecl -> ASTScope that is derived from querying each
ASTScope for its locals, which matches also what happens in name lookup. This
patch also fixes the nesting of SILDebugScopes created for guard statement
bodies, which are incorrectly nested in the ASTScope hierarchy.
rdar://108940570
SE-390 concluded with choosing the keyword discard rather than forget for
the statement that disables the deinit of a noncopyable type. This commit
adds parsing support for `discard self` and adds a deprecation warning for
`_forget self`.
rdar://108859077