Similarly to how we've always handled parameter types, we
now recursively expand tuples in result types and separately
determine a result convention for each result.
The most important code-generation change here is that
indirect results are now returned separately from each
other and from any direct results. It is generally far
better, when receiving an indirect result, to receive it
as an independent result; the caller is much more likely
to be able to directly receive the result in the address
they want to initialize, rather than having to receive it
in temporary memory and then copy parts of it into the
target.
The most important conceptual change here that clients and
producers of SIL must be aware of is the new distinction
between a SILFunctionType's *parameters* and its *argument
list*. The former is just the formal parameters, derived
purely from the parameter types of the original function;
indirect results are no longer in this list. The latter
includes the indirect result arguments; as always, all
the indirect results strictly precede the parameters.
Apply instructions and entry block arguments follow the
argument list, not the parameter list.
A relatively minor change is that there can now be multiple
direct results, each with its own result convention.
This is a minor change because I've chosen to leave
return instructions as taking a single operand and
apply instructions as producing a single result; when
the type describes multiple results, they are implicitly
bound up in a tuple. It might make sense to split these
up and allow e.g. return instructions to take a list
of operands; however, it's not clear what to do on the
caller side, and this would be a major change that can
be separated out from this already over-large patch.
Unsurprisingly, the most invasive changes here are in
SILGen; this requires substantial reworking of both call
emission and reabstraction. It also proved important
to switch several SILGen operations over to work with
RValue instead of ManagedValue, since otherwise they
would be forced to spuriously "implode" buffers.
_BridgedNSError conformances can affect the runtime behavior of
dynamic casts (e.g. 'is'). Unfortunately, the conformance is not
always emitted, in an effort to save space when not used. This change
forces the conformance witness tables to be emitted when we can detect
a dynamic cast to an _BridgedNSError conforming enum.
Test cases included, as well as a note about a potentially erroneous
path that is not currently handled: when the dynamic cast occurs in a
generic function to a generic type (and thus we are unsure which
conformances we need to pull in).
As there are no instructions left which produce multiple result values, this is a NFC regarding the generated SIL and generated code.
Although this commit is large, most changes are straightforward adoptions to the changes in the ValueBase and SILValue classes.
We need to keep the AST formal type of the base around when building up
lvalues.
When the getter or setter involves an accessor call, we would use the
lowered type of the self argument to form the call. However, it might be
at the wrong level of abstraction, causing a @thin -vs- @thick metatype
mismatch. Using the formal type instead allows SILGenApply logic to emit
a thin to thick metatype conversion if necessary.
Fixes <rdar://problem/21358641>.
Swift SVN r30913
And fix some bugs in the switch implementation I ran into on the way:
- Make getManagedSubobject(CopyOnSuccess) really produce a CopyOnSuccess ConsumableManagedValue;
- Avoid invalidating address-only enums when they can't be unconditionally taken by copying the enum before projecting it. Ideally there'd be a copy_enum_data_addr instruction to do this more efficiently.
Swift SVN r29817
I didn't add anything to the table, just made use of what was already there.
We have plenty of additional calls to getIdentifier that could probably benefit
from this kind of easy access as well.
This commit also removes FOUNDATION_MODULE_NAME and OBJC_MODULE_NAME from
Strings.h. Neither of these is likely to change in the future, and both
already have KnownIdentifiers equivalents in use.
No intended functionality change.
Swift SVN r29292
Failure paths need to maintain a consistent view of the cleanup state, so we can't just branch to a common exit point and fixup the cleanup state later. Fixes rdar://problem/21087371.
Swift SVN r29287
This simplifies the cleanup juggling we have to do, making it easier to get to the fix for rdar://problem/21087371. NFC yet (since emitting casts one at a time is equivalent to pretending we emit them simultaneously like we were).
Swift SVN r29277
checked_cast_br promises to maintain RC identity, but a cast from an ErrorType-conforming class to NSError may change the RC identity by bridging. Make sure that potential class-to-NSError casts go through the indirect cast entry points for now. The runtime implementation still needs to be fixed to handle the class-to-NSError case, but this is part of rdar://problem/21116814.
Swift SVN r29089
- Enable 'catch is NSError' and 'catch let e as NSError {' patterns to
a) work, and b) be considered to be exhaustive catches. This enables
people to catch an error and *use* it as an NSError directly, instead
of having to do boiler-platey cases. This is particularly important
for the migrator.
- Do not warn about non-noop coersion casts (like "_ as NSError" when
matching an ErrorType), since they provide useful type adjustment to
the subpattern. Still warn on noop ones.
- Simplify CatchStmt::isSyntacticallyExhaustive to use
Pattern::isRefutablePattern. Add a FIXME, because the parser is guiding
closure "throws" inference before the pattern is type checked, which means
that it is incorrect (but only in subtle cases).
- When diagnosing pointless 'as' patterns like:
switch 4 {
case _ as Int: break
say "'as' test is always true" instead of "'is' test is always true".
Swift SVN r28774
- Implement SILGen for conditional multi-pattern PBD's.
- Have the type checker check where clauses on PBDs.
- Change the AST to represent complex if/let PBD's with
composed PBDs instead of breaking them down. For example,
represent:
if let x? = foo(), y? = bar() where x == y {
as a single PBD in a StmtCondition instead of representing
it as three entries in the condition.
The later change is good for AST/source fidelity as well as providing
a cheap way to exercise all the logic I'm building.
Swift SVN r26959
Previously some parts of the compiler referred to them as "fields",
and most referred to them as "elements". Use the more generic 'elements'
nomenclature because that's what we refer to other things in the compiler
(e.g. the elements of a bracestmt).
At the same time, make the API better by providing "getElement" consistently
and using it, instead of getElements()[i].
NFC.
Swift SVN r26894
(containing just an uncond branch) when a shared block isn't actually shared.
This is a revised version of r26676 that makes sure to emit the cleanups for a
case pattern as soon as possible. Extending the lifetime of the case value
across the body of the switch caused extra copies of COW types.
Swift SVN r26685
This patch introduces a new kind of pattern for matching bool literals, i.e. true and false. Essentially, it is very similar to a pattern for matching enum elements, but simpler. Most of the code is just a boiler plate code copy/pasted from the code for enum element patterns. The only different thing is the emitBoolDispatch function, which emits a SIL code for matching bools.
With this patch, we don't get any false non-exhaustive switch diagnostics for switches on bools anymore. And we have a lot of radars complaining about it. For example rdar://16514545 and rdar://20130240.
Note, that this patch fixes the non-exhaustive switch diagnostics without changing the internal representation of bools. Implementing bool as an enum would have the same effect when it comes to these diagnostics and we would get this diagnostics fix for free, i.e. without any code committed here. But implementing bools-as-enums is an ongoing work and I'm investigating its performance implications. If we become confident that bool-as-enum does not have a negative impact on performance and decide to merge it, then we can revert this patch as it would not be necessary anymore. But if we decide to skip the enum-as-bool approach to its performance issues, then we would have at least fixed the false non-exhaustive diagnostics for bools by means of this patch.
Swift SVN r26650
This change permits SILGen to make smarter decisions about
block placement by keeping related blocks together instead
of always inserting to the end to the function. The
flipside is that SILGen needs to be somewhat careful to
create blocks in the right order. Counter-intuitively,
that order is the reverse of the order in which the blocks
should be laid out, since blocks created later will be
inserted before blocks created earlier. Note, however,
that this produces the right results for recursive
emission.
To that end, adjust a couple of places in SILGen to
create blocks in properly nested order.
All of the block-order differences in the tests seem
to be desirable; several of them even had confused
comments wondering how on earth a block got injected
where it did.
Also, fix the implementation of SILBuilder::moveBlockTo,
and fix a latent bug in epilogue emission where epilogBB
was erased from its parent (deleting it) and then
queried multiple times (!).
Swift SVN r26428
This patch also introduces some SILGen infrastructure for
dividing the function into "ordinary" and "postmatter"
sections, with error-handling-like stuff going into the
final section. Currently, this is largely undermined by
SILBuilder, but I'm going to fix that in a follow-up.
Swift SVN r26422
Previously, a multi-pattern var/let decl like:
var x = 4, y = 17
would produce two pattern binding decls (one for x=4 one for y=17). This is convenient
in some ways, but is bad for source reproducibility from the ASTs (see, e.g. the improvements
in test/IDE/structure.swift and test/decl/inherit/initializer.swift).
The hardest part of this change was to get parseDeclVar to set up the AST in a way
compatible with our existing assumptions. I ended up with an approach that forms PBDs in
more erroneous cases than before. One downside of this is that we now produce a spurious
"type annotation missing in pattern"
diagnostic in some cases. I'll take care of that in a follow-on patch.
Swift SVN r26224