Instead of appending a character for each substitution, we now prefix the substitution with the repeat count, e.g.
AbbbbB -> A5B
The same is done for known-type substitutions, e.g.
SiSiSi -> S3i
This significantly shrinks mangled names which contain large lists of the same type, like
func foo(_ x: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int))
rdar://problem/30707433
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
Recently I changed the ArchetypeBuilder is minimize requirements
in generic signatures. However substitution lists still contained
all recursively-expanded nested types.
With recursive conformances, this list becomes potentially
infinite, so we can't expand it out anymore. Also, it is just
a waste of time to have them there.
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
radar rdar://problem/28434323
SILGen has no reason to insert shadow copies for inout parameters any more. They cannot be captured. We still emit these copies. Sometimes deshadowing removes them, but sometimes it does not.
In this PR we just avoid emitting the copies and remove the deshadowing pass.
This PR chery-picked some of @dduan work and built on top of it.
The commit was reverted because of a regression in the
Prototypes/CollectionTransformers test. I believe the root
cause was an escape analysis bug, which is fixed in my
previous commit.
If the thunk's type otherwise did not involve type parameters, we
would still pass around the generic parameters from the caller's
context, which is wasteful.
Currently, ArchetypeBuilder::mapTypeOutOfContext() does not pick the
canonical representative from a same-type equivalence class. While
it should be fixed to do that, for now let's make a targeted fix
to explicitly canonicalize capture types with respect to a generic
signature when lowering capture types.
This flips the switch to have @noescape be the default semantics for
function types in argument positions, for everything except property
setters. Property setters are naturally escaping, so they keep their
escaping-by-default behavior.
Adds contentual printing, and updates the test cases.
There is some further (non-source-breaking) work to be done for
SE-0103:
- We need the withoutActuallyEscaping function
- Improve diagnostics and QoI to at least @noescape's standards
- Deprecate / drop @noescape, right now we allow it
- Update internal code completion printing to be contextual
- Add more tests to explore tricky corner cases
- Small regressions in fixits in attr/attr_availability.swift
- All parts of the compiler now use ‘P1 & P2’ syntax
- The demangler and AST printer wrap the composition in parens if it is
in a metatype lookup
- IRGen mangles compositions differently
- “protocol<>” is now “swift.Any”
- “protocol<_TP1P,_TP1Q>” is now “_TP1P&_TP1Q”
- Tests cases are updated and added to test the new syntax and mangling
There was a weird corner case with nested generic functions that
would fail in the SIL verifier with some nonsense about archetypes
out of context.
Fix this the "right" way, by re-working Sema function declaration
validation to assign generic signatures in a more principled way.
Previously, nested functions did not get an interface type unless
they themselves had generic parameters.
This was inconsistent with methods nested inside generic types,
which did get an interface type even if they themselves did not
have a generic parameter list.
There's some spill-over in SILGen from this change. Mostly it
makes things more consistent and fixes some corner cases.
We now have enough machinery in place to reference local generic
functions which have captures, to get a value of function type
that can be passed around.
Generic local functions still cannot be directly called from
function call expressions, since those go down a different
path in SILGenApply.cpp -- the next patch will add support for
this case.
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.
Modeling nonescaping captures as @inout parameters is wrong, because captures are allowed to share state, unlike 'inout' parameters, which are allowed to assume to some degree that there are no aliases during the parameter's scope. To model this, introduce a new @inout_aliasable parameter convention to indicate an indirect parameter that can be written to, not only by the current function, but by well-typed, well-synchronized aliasing accesses too. (This is unrelated to our discussions of adding a "type-unsafe-aliasable" annotation to pointer_to_address to allow for safe pointer punning.)
Now that boxes are typed and projectable, the address no longer has to be passed separately.
For now, this breaks capture promotion, DI, and debug info, which analyze uses of the address param. Will be addressed in upcoming commits:
Swift :: DebugInfo/byref-capture.swift
Swift :: DebugInfo/closure-args.swift
Swift :: DebugInfo/closure-args2.swift
Swift :: DebugInfo/inout.swift
Swift :: DebugInfo/linetable.swift
Swift :: SILPasses/capture_promotion.swift
Swift :: SILPasses/definite_init_diagnostics.swift
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
The CaptureInfo computed by Sema now records if the body of the
function uses any generic parameters from the outer context.
SIL type lowering only adds a generic signature if this is the
case, instead of unconditionally.
This might yield a marginal performance improvement in some cases,
but more interestingly will allow @convention(c) conversions from
generic context.
Swift SVN r32161
Single generic parameters are common, as are a lack of requirements, so tweak things so that generic parameter counts are mangled as (count - 1), with a special mangling for zero, and give a single generic parameter at depth zero the empty-string mangling. Most requirements are protocol constraints, so use a better mangling for them that doesn't require the 'P..._' wrapping of the general type mangling. On the other hand, dependent member types ought to mangle in the protocol of the associated type, which adds some length, but isn't too bad since the protocol will almost definitely have a substitution introduced by a preceding protocol constraint.
Swift SVN r28296
Instead of immediately creating closures for local function declarations and treating them directly as capturable values, break function captures down and transitively capture the storage necessary to invoke the captured functions. Change the way SILGen emits calls to closures and local functions so that it treats the capture list as the first curry level of an invocation, so that full applications of closure literals or nested functions don't require a partial apply at all. This allows references among local functions with captures to work within the existing confines of partial_apply, and also has the nice benefit that circular references would work without creating reference cycles (though Sema unfortunately rejects them; something we arguably ought to fix.)
This fixes rdar://problem/11266246 and improves codegen of local functions. Full applications of functions, or immediate applications of closure literals like { }(), now never need to allocate a closure.
Swift SVN r28112
In addition to being better for performance in these cases, this disables the "self."
requirement in these blocks. {}() constructs are often used to work around statements
that are not exprs in Swift, so they are reasonably important.
Fixing this takes a couple of pieces working together:
- Add a new 'extraFunctionAttrs' map to the ConstraintSystem for solution
invariant function attributes that are inferred (like @noescape).
- Teach constraint simplification of function applications to propagate
@noescape between unified function types.
- Teach CSGen of ApplyExprs to mark the callee functiontype as noescape
when it is obviously a ClosureExpr.
This is a very limited fix in some ways: you could argue that ApplyExpr should
*always* mark its callee as noescape. However, doing so would just introduce a
ton of function conversions to remove it again, so we don't do that.
Swift SVN r27723
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
rdar://problem/17198298
- Allow 'static' in protocol property and func requirements, but not 'class'.
- Allow 'static' methods in classes - they are 'class final'.
- Only allow 'class' methods in classes (or extensions of classes)
- Remove now unneeded diagnostics related to finding 'static' in previously banned places.
- Update relevant diagnostics to make the new rules clear.
Swift SVN r24260