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.
And use project_box to get to the address value.
SILGen now generates a project_box for each alloc_box.
And IRGen re-uses the address value from the alloc_box if the operand of project_box is an alloc_box.
This lets the generated code be the same as before.
Other than that most changes of this (quite large) commit are straightforward.
All refutable patterns and function parameters marked with 'var'
is now an error.
- Using explicit 'let' keyword on function parameters causes a warning.
- Don't suggest making function parameters mutable
- Remove uses in the standard library
- Update tests
rdar://problem/23378003
And include some supplementary mangling changes:
- Give the first generic param (depth=0, index=0) a single character mangling. Even after removing the self type from method declaration types, 'Self' still shows up very frequently in protocol requirement signatures.
- Fix the mangling of generic parameter counts to elide the count when there's only one parameter at the starting depth of the mangling.
Together these carve another 154KB out of a debug standard library. There's some awkwardness in demangled strings that I'll clean up in subsequent commits; since decl types now only mangle the number of generic params at their own depth, it's context-dependent what depths those represent, which we get wrong now. Currying markers are also wrong, but since free function currying is going away, we can mangle the partial application thunks in different ways.
Swift SVN r32896
'Ss' appears in manglings tens of thousands of times in the standard library and is also incredibly frequent in other modules. This alone is enough to shrink the standard library by 59KB.
Swift SVN r32409
With the test case included in this commit we were first hitting an
assert due to a cast<FuncDecl>(decl) that failed because the supplied
decl was for a constructor, and after fixing this we failed verification
due to using the wrong result type for the generated thunk.
The result should have the same kind of 'optionalness' as the base-class
method's result, but if the type is some kind of optional it should be
wrapping the same type as the thunked-to function.
Fixes at least part of rdar://problem/20663080. I need to go back and
patch an older toolset to see if this completely resolves the issue.
Swift SVN r28289
Two pieces to this:
- Peephole OptionalEvaluationExpr(InjectOptionalExpr(BindOptionalExpr(X))) to bitcast x to the result type.
- Enhance OptionalEvaluationExpr to delete the failure block if not needed.
This is the same as r28150, but it includes a fix for the case when a non-address-only type
is initializing a contextally-provided-and-addressible buffer, tested by the new
testContextualInitOfNonAddrOnlyType testcase.
Swift SVN r28153
Two pieces to this:
- Peephole OptionalEvaluationExpr(InjectOptionalExpr(BindOptionalExpr(X))) to
bitcast x to the result type.
- Enhance OptionalEvaluationExpr to delete the failure block if not needed.
This is the same as r28111, except that we finalize the initialization in the
address-only case. A reduced testcase for the specific issue is added to
optional-casts.swift.
Swift SVN r28150
and r28105: "implement <rdar://problem/17013042> T! <-> T? conversions should not produce a diamond"
r28111 broke the stdlib build. I also reverted r28105, because r28111 fixes regressions introduced in r2805.
Swift SVN r28114
Two pieces to this:
- Peephole InjectOptionalExpr(BindOptionalExpr(X)) to bitcast x to the result type.
- Enhance OptionalEvaluationExpr to delete the failure block if not needed.
Swift SVN r28105
to not drop optionals in memory all the time. We now generate a lot better code
for them in many cases. This makes generated SIL more readable and should help
-O0 perf.
This is progress towards <rdar://problem/20642198> SILGen shouldn't be dropping optionals into memory all the time
Swift SVN r28102
We no longer need or use it since we can always refer to the same bit on
the applied function when deciding whether to inline during mandatory
inlining.
Resolves rdar://problem/19478366.
Swift SVN r26534
Most tests were using %swift or similar substitutions, which did not
include the target triple and SDK. The driver was defaulting to the
host OS. Thus, we could not run the tests when the standard library was
not built for OS X.
Swift SVN r24504