For example, if an internal type conforms to a public protocol, the witness table should get internal linkage.
Previously we only considered the visibility of the protocol.
Fragile witness tables still have to get public symbol linkage. This is now handled in IRGen (like we do it for functions).
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
This helps when we end up re-typechecking an expression, which we seem
to be doing with 'lazy'. Specifically, it was causing type inference
for lazy variables to fail, but the same issue would have come up in
other contexts as well. Note that we also set function reference kinds
of DeclRefExprs and related in the process.
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.
Having a separate address and container value returned from alloc_stack is not really needed in SIL.
Even if they differ we have both addresses available during IRGen, because a dealloc_stack is always dominated by the corresponding alloc_stack in the same function.
Although this commit quite large, most changes are trivial. The largest non-trivial change is in IRGenSIL.
This commit is a NFC regarding the generated code. Even the generated SIL is the same (except removed #0, #1 and @local_storage).
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
SILPrinter was printing uses for all SIL values, except for SIL basic blocks arguments. Fill the gap and print uses for BB arguments as well. This makes reading and analyzing SIL easier.
Basic blocks may have multiple arguments, therefore print uses of each BB argument on separate lines - one line per BB argument.
The comment containing information about uses of a BB argument is printed on the line just above the basic block name, following the approach used for function_ref and other kinds of instructions, which have additional information printed on the line above the actual instruction.
The output now looks like:
// %0 // user: %3
// %1 // user: %9
bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<UnsafeMutablePointer<Int8>>):
rdar://23336589
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
Canonical dependent member types are always based from a generic parameter, so we can use a more optimal mangling that assumes this. We can also introduce substitutions for AssociatedTypeDecls, and when a generic parameter in a signature is constrained by a single protocol, we can leave that protocol qualification out of the unsubstituted associated type mangling. These optimizations together shrink the standard library by 117KB, and bring the length of the longest Swift symbol in the stdlib down from 578 to 334 characters, shorter than the longest C++ symbol in the stdlib.
Swift SVN r32786
A microoptimization; since the module is likely to come up often in the subsequent mangling, we want to make it more likely to get the coveted S_ substitution.
Swift SVN r32784
'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
r31072 (<rdar://21836671>).
Passes the primary test suite; I'm still working on giving it
proper tests, but since time is of the essence, we can
streamline this process by doing a few things in parallel.
The test suite change here is interesting: we're no longer
emitting materializeForSet entrypoints for storage in
protocol extensions, because they were only getting emitted
lazily and we're no longer using them at all. I think
that's fine because, well, we're no longer using them at
all.
Swift SVN r31192
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
This bug triggered when three pre-conditions held:
- A protocol requirement method signature involves archetypes built
from associated types
- A protocol extension provides a default implementation of this method
- The method is called from another method in the same extension,
with a parameter of the associated type
In this case, the archetypes in the signature would match exactly
and we would end up picking the extension method over the protocol
method, which would not even be considered. As a result, the
extension method would be dispatch statically instead of using
witness method dispatch, which is wrong.
Hopefully one day we can model default implementations as real
overrides and not overloads.
Note that the test is a SILGen test even though the bug is in Sema,
since its easier to detect the problem at the SIL level.
Fixes <rdar://problem/21995666>.
Swift SVN r30847
When extending a protocol where the 'Self' type is a subclass of some
known class type, initializers within the protocol extension can
delegate to required initializers of that superclass bound. Correctly
adjust the 'self' we produce in SILGen to the superclass type.
Fixes rdar://problem/21370992.
Swift SVN r30584
Since each override of a subscript protocol requirement provides
its own materializeForSet, there is no need to do dynamic dispatch,
a peer call to the setter suffices. However, since CodeSynthesis
runs at the AST level, it would create a SubscriptExpr which
overload resolution would later bind to the protocol requirement
subscript rather than the static witness in the extension.
This triggered an assertion. Solve the problem by binding the
actual ConcreteDeclRef of the SubscriptExpr at synthesis time,
and modifying CSGen to special-case SubscriptExprs that already
have a ConcreteDeclRef set.
Fixes <rdar://problem/21370629>.
Swift SVN r29906
This makes it clearer that expressions like "foo.myType.init()" are creating new objects, instead of invoking a weird-looking method. The last part of rdar://problem/21375845.
Swift SVN r29375
Constrained and protocol extensions should always include the extension context in their mangling, since they are never equivalent to definitions in the original type context. Have them use the extension mangling, and include the generic signature of the extension in its mangling, which is necessary to disambiguate properties and other definitions that are defined with the same name and type in differently constrained extensions. Fixes rdar://problem/21027215.
Swift SVN r29209
In @objc protocols, the initializing entry point is witnessed (as an -init method) rather than the allocating entry point, so the extension initializer needs to allocate the object and delegate to the initializing constructor.
Swift SVN r27940
It's still appropriate to use emitValueConstructor to emit a class protocol extension initializer, since the witnessed delegatee initializer handles the full object initialization.
Swift SVN r27903
For the most part, this just involves spot fixes to make sure protocol inits follow the same paths as value type initializers would, with the extra wrinkle that we have to ensure we forward the correct metatype from the delegating initializer to the delegatee, in case the initializer is invoked with a different dynamic type from the static Self type. This should handle non-@objc delegations; @objc will need some additional work.
Swift SVN r27900
The rule changes are as follows:
* All functions (introduced with the 'func' keyword) have argument
labels for arguments beyond the first, by default. Methods are no
longer special in this regard.
* The presence of a default argument no longer implies an argument
label.
The actual changes to the parser and printer are fairly simple; the
rest of the noise is updating the standard library, overlays, tests,
etc.
With the standard library, this change is intended to be API neutral:
I've added/removed #'s and _'s as appropriate to keep the user
interface the same. If we want to separately consider using argument
labels for more free functions now that the defaults in the language
have shifted, we can tackle that separately.
Fixes rdar://problem/17218256.
Swift SVN r27704
The only caveat is that:
1. We do not properly recognize when we have a let binding and we
perform a guaranteed dynamic call. In such a case, we add an extra
retain, release pair around the call. In order to get that case I will
need to refactor some code in Callee. I want to make this change, but
not at the expense of getting the rest of this work in.
2. Some of the protocol witness thunks generated have unnecessary
retains or releases in a similar manner.
But this is a good first step.
I am going to send a large follow up email with all of the relevant results, so
I can let the bots chew on this a little bit.
rdar://19933044
Swift SVN r27241
Consistently open all references into existentials into
opened-existential archetypes within the constraint solver. Then,
during constraint application, use OpenExistentialExprs to record in
the AST where an existential is opened into an archetype, then use
that archetype throughout the subexpression. This simplifies the
overall representation, since we don't end up with a mix of operations
on existentials and operations on archetypes; it's all archetypes,
which tend to have better support down the line in SILGen already.
Start simplifying the code in SILGen by taking away the existential
paths that are no longer needed. I suspect there are more
simplifications to be had here.
The rules for placing OpenExistentialExprs are still a bit ad hoc;
this will get cleaned up later so that we can centralize that
information. Indeed, the one regression in the compiler-crasher suite
is because we're not closing out an open existential along an error
path.
Swift SVN r27230
Try to emit the existential as a guaranteed value, and if we succeed, only +1 the bound opaque value if it's needed as a consumed value. This lets us avoid retaining or copying the existential if the existential can be produced and its contained value consumed at +0.
Swift SVN r27200
This isn't the right solution; we should be folding open-existentials
into the LValue machinery rather than subverting it. However, the test
cases are useful for we do get the right solution in place.
Swift SVN r27103
To properly deal with mutating methods on protocol extensions accessed through an existential (such as a property or subscript setter), open the existential as an lvalue so that its value can be mutated.
As part of this, make sure we form any OpenExistentialExprs at the top level of the expression if we didn't manage to build them sooner. This is a fairly ad hoc approach that I am not happy with (these could probably be placed better with a post-pass), but the cost of opening too early is fairly minimal.
Swift SVN r27068