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.
All non-trivial values which correspond to `VarDecl`s must be marked
appropriately so that they can be found by the relevant checker. Here,
values with none ownership are marked.
The current IUO design always forms a disjunction
at the overload reference, for both:
- An IUO property `T!`, forming `$T := T? or T`
- An IUO-returning function `() -> T!`, forming `$T := () -> T? or () -> T`
This is simple in concept, however it's suboptimal
for the latter case of IUO-returning functions for
a couple of reasons:
- The arguments cannot be matched independently of
the disjunction
- There's some awkwardness when it comes e.g wrapping
the overload type in an outer layer of optionality
such as `(() -> T!)?`:
- The binding logic has to "adjust" the correct
reference type after forming the disjunction.
- The applicable fn solving logic needs a special
case to handle such functions.
- The CSApply logic needs various hacks such as
ImplicitlyUnwrappedFunctionConversionExpr to
make up for the fact that there's no function
conversion for IUO functions, we can only force
unwrap the function result.
- This lead to various crashes in cases where
we we'd fail to detect the expr and peephole
the force unwrap.
- This also lead to crashes where the solver
would have a different view of the world than
CSApply, as the former would consider an
unwrapped IUO function to be of type `() -> T`
whereas CSApply would correctly see the overload
as being of type `() -> T?`.
To remedy these issues, IUO-returning functions no
longer have their disjunction formed at the overload
reference. Instead, a disjunction is formed when
matching result types for the applicable fn
constraint, using the callee locator to determine
if there's an IUO return to consider. CSApply then
consults the callee locator when finishing up
applies, and inserts the force unwraps as needed,
eliminating ImplicitlyUnwrappedFunctionConversionExpr.
This means that now all IUO disjunctions are of the
form `$T := T? or T`. This will hopefully allow a
further refactoring away from using disjunctions
and instead using type variable binding logic to
apply the correct unwrapping.
Fixes SR-10492.
It can already only accept values with none ownership and the merging of
ownership around ownership phis ensure that if we phi this with a partial_apply
or the like, we get the appropriate ownership on any such ownership phi values.
We are now out of SILGen emitting fewer destroy_value unnecessarily on
thin_to_thick functions. This changed some codegen and also forced me to update
some tests/fix AutoDiff.
I also deleted the DebugInfo test mandatoryinlining-wrongdebugscope.swift since:
1. It was depending on these destroys being there.
2. Given the need to improve the test @aprantl suggested I just eliminate it
solving the test failure for me.
This does not eliminate the entrypoints on SILBuilder yet. I want to do this in
two parts so that it is functionally easier to disentangle changing the APIs
above SILBuilder and changing the underlying instruction itself.
rdar://33440767
The SILGen testsuite consists of valid Swift code covering most language
features. We use these tests to verify that no unknown nodes are in the
file's libSyntax tree. That way we will (hopefully) catch any future
changes or additions to the language which are not implemented in
libSyntax.
I am going to leave in the infrastructure around this just in case. But there is
no reason to keep this in the tests themselves. I can always just revert this
and I don't think merge conflicts are likely due to previous work I did around
the tooling for this.
Otherwise, the plus_zero_* tests will have plus_zero_* as a module name, causing
massive FileCheck problems.
The reason why I am doing it with the main tests is so that I can use it when
syncing branches/etc.
radar://34222540
Stop creating ImplicitlyUnwrappedOptional<T> so that we can remove it
from the type system.
Enable the code that generates disjunctions for Optional<T> and
rewrites expressions based on the original declared type being 'T!'.
Most of the changes supporting this were previously merged to master,
but some things were difficult to merge to master without actually
removing IUOs from the type system:
- Dynamic member lookup and dynamic subscripting
- Changes to ensure the bridging peephole still works
Past commits have attempted to retain as much fidelity with how we
were printing things as possible. There are some cases where we still
are not printing things the same way:
- In diagnostics we will print '?' rather than '!'
- Some SourceKit and Code Completion output where we print a Type
rather than Decl.
Things like module printing via swift-ide-test attempt to print '!'
any place that we now have Optional types that were declared as IUOs.
There are some diagnostics regressions related to the fact that we can
no longer "look through" IUOs. For the same reason some output and
functionality changes in Code Completion. I have an idea of how we can
restore these, and have opened a bug to investigate doing so.
There are some small source compatibility breaks that result from
this change:
- Results of dynamic lookup that are themselves declared IUO can in
rare circumstances be inferred differently. This shows up in
test/ClangImporter/objc_parse.swift, where we have
var optStr = obj.nsstringProperty
Rather than inferring optStr to be 'String!?', we now infer this to
be 'String??', which is in line with the expectations of SE-0054.
The fact that we were only inferring the outermost IUO to be an
Optional in Swift 4 was a result of the incomplete implementation of
SE-0054 as opposed to a particular design. This should rarely cause
problems since in the common-case of actually using the property rather
than just assigning it to a value with inferred type, we will behave
the same way.
- Overloading functions with inout parameters strictly by a difference
in optionality (i.e. Optional<T> vs. ImplicitlyUnwrappedOptional<T>)
will result in an error rather than the diagnostic that was added
in Swift 4.1.
- Any place where '!' was being used where it wasn't supposed to be
allowed by SE-0054 will now treat the '!' as if it were '?'.
Swift 4.1 generates warnings for these saying that putting '!'
in that location is deprecated. These locations include for example
typealiases or any place where '!' is nested in another type like
`Int!?` or `[Int!]`.
This commit effectively means ImplicitlyUnwrappedOptional<T> is no
longer part of the type system, although I haven't actually removed
all of the code dealing with it yet.
ImplicitlyUnwrappedOptional<T> is is dead, long live implicitly
unwrapped Optional<T>!
Resolves rdar://problem/33272674.
This is the first in a series of changes to make SILGen always emit switch_enums
such that payloads are always passed as an arguments to the destination blocks.
This is important since switch_enum today in SILGen is modeled as a consuming
operation. Thus if we follow the model today where we reuse in the destination
blocks the switched upon value, we have created either a use after free or a
double consuming (depending on how the value is used).
There is no reason why we should use a default case here for these optional enums.
rdar://29791263
We limit Optional-to-IUO as an implicit conversion to avoid making
common expressions ambiguous. However, this runs into trouble with
function-to-function conversions, which always look for a "Subtype"
relationship for their inputs and outputs. This is a conservative way
for Sema to avoid emitting conversions that SILGen cannot handle.
The problem case here is converting a closure with type '(Any!) ->
Void' to a value of type '(Any?) -> Void':
let f: ((Any?) -> Void) = { (arg: Any!) in }
This is clearly a safe conversion, since 'Any!' and 'Any?' have the
same representation at run time, but historically we've disallowed it
because of the above rules. However, in Swift 3.0 this particular case
was permitted, with the type checker deciding that the 'Any?' argument
to 'f' could first itself be put into an 'Any', then /that/ value
could go through a value-to-optional conversion to make 'Any!'.
Fortunately the emitted code didn't follow this incorrect conversion
path.
This patch doesn't even try to emulate the old behavior. Instead, it
just weakens the restriction on Optional-to-IUO via a new type
matching flag that only applies within the context of matching
function types.
We can consider opening up function conversions in Swift 4 to anything
that supports conversion---not just subtyping---now that SILGen knows
how to automatically reabstract most such things. But whether we do or
not, Optional/IUO is a special case.
https://bugs.swift.org/browse/SR-3758
Officially kick SILBoxType over to be "nominal" in its layout, with generic layouts structurally parameterized only by formal types. Change SIL to lower a capture to a nongeneric box when possible, or a box capturing the enclosing generic context when necessary.
Use a syntax that declares the layout's generic parameters and fields,
followed by the generic arguments to apply to the layout:
{ var Int, let String } // A concrete box layout with a mutable Int
// and immutable String field
<T, U> { var T, let U } <Int, String> // A generic box layout,
// applied to Int and String
// arguments
Keep in mind that these are approximations that will not impact correctness
since in all cases I ensured that the SIL will be the same after the
OwnershipModelEliminator has run. The cases that I was unsure of I commented
with SEMANTIC ARC TODO. Once we have the verifier any confusion that may have
occurred here will be dealt with.
rdar://28685236
This ensures that ownership is properly propagated forward through the use-def
graph.
This was the work that was stymied by issues relating to SILBuilder performing
local ARC dataflow. I ripped out that local dataflow in 6f4e2ab and added a
cheap ARC guaranteed dataflow pass that performs the same optimization.
Also in the process of doing this work, I found that there were many SILGen
tests that were either pattern matching in the wrong functions or had wrong
CHECK lines (for instance CHECK_NEXT). I fixed all of these issues and also
expanded many of the tests so that they verify ownership. The only work I left
for a future PR is that there are certain places in tests where we are using the
projection from an original value, instead of a copy. I marked those with a
message SEMANTIC ARC TODO so that they are easy to find.
rdar://28685236
Being generic, the '_unwrapped' intrinsics force trafficking through memory, and while they're transparent so always get inlined, we don't do memory promotion in -Onone. Emitting the branch inline lets loadable optionals stay values leading to better -Onone codegen. (It also lets us throw away a surprising amount of support code for these optional intrinsics.)
This is a squash of the following commits:
* [SE-0054] Import function pointer arg, return types, typedefs as optional
IUOs are only allowed on function decl arguments and return types, so
don't import typedefs or function pointer args or return types as IUO.
* [SE-0054] Only allow IUOs in function arg and result type.
When validating a TypeRepr, raise a diagnostic if an IUO is found
anywhere other thn the top level or as a function parameter or return
tpye.
* [SE-0054] Disable inference of IUOs by default
When considering a constraint of the form '$T1 is convertible to T!',
generate potential bindings 'T' and 'T?' for $T1, but not 'T!'. This
prevents variables without explicit type information from ending up with
IUO type. It also prevents implicit instantiation of functions and types
with IUO type arguments.
* [SE-0054] Remove the -disable-infer-iuos flag.
* Add nonnull annotations to ObjectiveCTests.h in benchmark suite.
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.