- Use the name lookup table instead of adding members from a macro expansion to the parent decl context.
- Require declaration macros to specify introduced names and used the declared names to guide macro expansions lazily.
The reason to do the first is to ensure that when I enable -sil-verify-all, we
do not have errors due to a copy_value of a move only type.
The reason to do the second thing is that:
1. If we have a move only type that is no implicit copy, I am in a subsequent
commit going to emit a type checker error saying that one cannot do this. When
we implement consuming/borrowing bindings/etc, we can make this looser if it
gets into the way.
2. If we have a copyable no implicit copy type, then any structural accesses
that we may want to do that would require a destructure must be to a copyable
type which is ok to copy as long as we do the unwrap from the first thing.
rdar://104929957
Introduce SingleValueStmtExpr, which allows the
embedding of a statement in an expression context.
This then allows us to parse and type-check `if`
and `switch` statements as expressions, gated
behind the `IfSwitchExpression` experimental
feature for now. In the future,
SingleValueStmtExpr could also be used for e.g
`do` expressions.
For now, only single expression branches are
supported for producing a value from an
`if`/`switch` expression, and each branch is
type-checked independently. A multi-statement
branch may only appear if it ends with a `throw`,
and it may not `break`, `continue`, or `return`.
The placement of `if`/`switch` expressions is also
currently limited by a syntactic use diagnostic.
Currently they're only allowed in bindings,
assignments, throws, and returns. But this could
be lifted in the future if desired.
- SILPackType carries whether the elements are stored directly
in the pack, which we're not currently using in the lowering,
but it's probably something we'll want in the final ABI.
Having this also makes it clear that we're doing the right
thing with substitution and element lowering. I also toyed
with making this a scalar type, which made it necessary in
various places, although eventually I pulled back to the
design where we always use packs as addresses.
- Pack boundaries are a core ABI concept, so the lowering has
to wrap parameter pack expansions up as packs. There are huge
unimplemented holes here where the abstraction pattern will
need to tell us how many elements to gather into the pack,
but a naive approach is good enough to get things off the
ground.
- Pack conventions are related to the existing parameter and
result conventions, but they're different on enough grounds
that they deserve to be separated.
If a function body references a declaration with the `@_backDeploy(before:)` attribute and that function body will only execute on deployment targets for which the ABI version of the decl is available then it is unnecessary to thunk the reference to the decl. Function bodies that may be emitted into other modules (e.g. `@inlinable`) must always use the thunk.
Resolves rdar://90729799
Previously, `begin_borrow [lexical]` were created during SILGen for
@owned arguments. Such borrows could be deleted if trivially dead,
which was the original reason why @owned arguments were considered
lexical and could not have their destroys hoisted.
Those borrows were however important during inlining because they would
maintain the lifetime of the owned argument. Unless of course the
borrow scope was trivially dead. In which case the owned argument's
lifetime would not be maintained. And if the caller's value was
non-lexical, destroys of the value could be hoisted over deinit
barriers.
Here, during inlining, `move_value [lexical]`s are introduced during
inlining whever the caller's value is non-lexical. This maintains the
lifetime of the owned argument even after inlining.
The following program crashed when compiled with the Swift 5.7 and 5.8 compilers:
```
@available(macOS 12, *)
@_backDeploy(before: macOS 99)
public func foo<T>(_ t: __owned T) {
print("foo")
}
class C {
deinit {
print("deinit")
}
}
foo(C())
print("done")
```
```
> ./test
foo
deinit
[1] 49162 segmentation fault ./test
```
The root cause is that generated SIL for the back deployment thunk for `foo(_:)` included its own `destroy_addr` instruction for the value of `t`, but didn't copy the parameter before passing it to the real function implementation which also destroys the value. The fix is to forward ownership of the parameter values to the called function, which causes cleanup generation to be skipped.
Resolves rdar://104436515
Add support for freestanding declaration macros.
- Parse `@declaration` attribute.
- Type check and expand `MacroExpansionDecl`.
Known issues:
- Generic macros are not yet handled.
- Expansion does not work when the parent decl context is `BraceStmt`. Need to parse freestanding declaration macro expansions in `BraceStmt` as `MacroExpansionDecl`, and add expanded decls to name lookup.
When a throwing function which returns a generic (this is the simplest
example) is back deployed, it gets a back deploy thunk. This back
deploy thunk calls one of two variations of the function, depending on
availability, both which have the same signature and in particular both
return a generic. The result type of that function signature is an
unbound generic.
Previously, that result type was used as is. Consequently the success
blocks for the try_apply instructions in these thunks had arguments of
unbound generic type.
Here, that type is mapped into the context of the function being
emitted. The thunks now have the appropriate bound generic type.
Example: (_borrow f).callFunction()
This still does not support _borrow for get/set and more general accessors. That
change will be coming in a forthcoming commit.
rdar://103888591
Single expression is not going to cut it in this case because attribute
and attached declaration could have different availability, so we need
to use `if #available` to guard attribute instantiation and return `nil`
in cases where types are not available.
A new `RuntimeAttributeGenerator` is used to reference runtime
attribute generator functions synthesized by SILGen.
`#function` magic literal points to the declaration that declaration
attribute is attached to.
Each entry relates an attribute declaration to a list of all
declarations it's associated with together with a generator
function to acquire instance of the attribute value.
This attribute indicates that the given SILFunction has to be
added to "accessible functions" section and could be looked up
at runtime using a special API.
Type wrapper synthesis cannot reply on `getExecutableInit` to
determine whether initialization should use backing wrapper
call or not, it has to check whether the init expression exists.
I am adding this to make it easy to determine if a SILFunction that is not inout
aliasable is captured. This is useful when emitting certain types of
diagnostics like I need to emit with move only.