Textual SIL was sometimes ambiguous when SILDeclRefs were used, because the textual representation of SILDeclRefs was the same for functions that have the same name, but different signatures.
There's a class of errors in Serialization called "circularity
issues", where declaration A in file A.swift depends on declaration B
in file B.swift, and B also depends on A. In some cases we can manage
to type-check each of these files individually due to the laziness of
'validateDecl', but then fail to merge the "partial modules" generated
from A.swift and B.swift to form a single swiftmodule for the library
(because deserialization is a little less lazy for some things). A
common case of this is when at least one of the declarations is
nested, in which case a lookup to find that declaration needs to load
all the members of the parent type. This gets even worse when the
nested type is defined in an extension.
This commit sidesteps that issue specifically for nested types by
creating a top-level, per-file table of nested types in the "partial
modules". When a type is in the same module, we can then look it up
/without/ importing all other members of the parent type.
The long-term solution is to allow accessing any members of a type
without having to load them all, something we should support not just
for module-merging while building a single target but when reading
from imported modules as well. This should improve both compile time
and memory usage, though I'm not sure to what extent. (Unfortunately,
too many things still depend on the whole members list being loaded.)
Because this is a new code path, I put in a switch to turn it off:
frontend flag -disable-serialization-nested-type-lookup-table
https://bugs.swift.org/browse/SR-3707 (and possibly others)
Textual SIL was sometimes ambiguous when SILDeclRefs were used, because the textual representation of SILDeclRefs was the same for functions that have the same name, but different signatures.
Piggybacks some resilience diagnostics onto the availability
checking code.
Public and versioned functions with inlineable bodies can only
reference other public and internal entities, since the SIL code
for the function body is serialized and stored as part of the
module.
This includes @_transparent functions, @_inlineable functions,
accessors for @_inlineable storage, @inline(__always) functions,
and in Swift 4 mode, default argument expressions.
The new checks are a source-breaking change, however we don't
guarantee source compatibility for underscored attributes.
The new ABI and tests for the default argument model will come in
subsequent commits.
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
This ensures that we can write FileCheck patterns that match the end of sil
functions. Just using a FileCheck pattern against a brace is not sufficient in
the context of checking the SIL emitted by SILGen. This is because we could match a
different function's body and match the closing brace against the other
function's end brace.
With this change, one can be specific by checking:
// CHECK: } {{.*}} end sil function '<mangled name>'
The inspiration for this change is rdar://28685236. While updating SILGen tests
for that I have found many instances of SILGen tests pattern matching against
the wrong function bodies. This change will allow me to eliminate these problems
robustly.
rdar://29077869
Quiz: What does @_transparent on an extension actually *do*?
1) Make all members @_transparent?
2) Allow your members to be @_transparent?
3) Some other magical effect that has nothing to do with members?
The correct answer is 1), however a few places in the stdlib defined
a @_transparent extension and then proceeded to make some or all members
also @_transparent, and in a couple of places we defined a @_transparent
extension with no members at all.
To avoid cargo culting and confusion, remove the ability to make
@_transparent extensions altogether, and force usages to be explicit.
It's the same thing as for alloc_ref: the optional [tail_elems ...] attribute specify the tail elements to allocate.
For details see docs/SIL.rst
This feature is needed so that we can allocate a MangedBuffer with alloc_ref_dynamic.
The ManagedBuffer.create() function uses the dynamic self type to create the buffer instance.
Those builtins are: allocWithTailElems_<n>, getTailAddr and projectTailElems
Also rename the "gep" builtin, which indexes raw bytes, to "gepRaw" and add a new "gep" builtin to index in a typed array.
The new instructions are: ref_tail_addr, tail_addr and a new attribute [ tail_elems ] for alloc_ref.
For details see docs/SIL.rst
As these new instructions are not generated so far, this is a NFC.
Those builtins are: allocWithTailElems_<n>, getTailAddr and projectTailElems
Also rename the "gep" builtin, which indexes raw bytes, to "gepRaw" and add a new "gep" builtin to index in a typed array.
The new instructions are: ref_tail_addr, tail_addr and a new attribute [ tail_elems ] for alloc_ref.
For details see docs/SIL.rst
As these new instructions are not generated so far, this is a NFC.
The presence of a generic signature in a XREF means that we should only find the result in a (further-constrained) extension with that generic signature. The absence of a generic signature in a XREF means that we should not find the result in a constrained extension. We implemented the former but not the latter, which would lead to deserialization failures if one had both constrained and unconstrained extensions with the same property in them. Methods/initializers weren’t a problem because the generic signature is (redundantly) encoded in their interface type.
One minor revision: this lifts the proposed restriction against
overriding a non-open method with an open one. On reflection,
that was inconsistent with the existing rule permitting non-public
methods to be overridden with public ones. The restriction on
subclassing a non-open class with an open class remains, and is
in fact consistent with the existing access rule.
What I've implemented here deviates from the current proposal text
in the following ways:
- I had to introduce a FunctionArrowPrecedence to capture the parsing
of -> in expression contexts.
- I found it convenient to continue to model the assignment property
explicitly.
- The comparison and casting operators have historically been
non-associative; I have chosen to preserve that, since I don't
think this proposal intended to change it.
- This uses the precedence group names and higherThan/lowerThan
as agreed in discussion.
- 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
This commit defines the ‘Any’ keyword, implements parsing for composing
types with an infix ‘&’, and provides a fixit to convert ‘protocol<>’
- Updated tests & stdlib for new composition syntax
- Provide errors when compositions used in inheritance.
Any is treated as a contextual keyword. The name ‘Any’
is used emit the empty composition type. We have to
stop user declaring top level types spelled ‘Any’ too.
My earlier patch started serializing SIL basic blocks using the RPOT order. While it works, changing the existing order of BBs during the serialization may be very surprising for users. After all, serialization is not supposed to transform the code.
Therefore, this patch follows a different approach. It uses the existing order of BBs during the serialization. When it deserializes SIL and detects a use of an opened archetype before its definition, it basically introduced a forward definition of this opened archetype. Later on, when the actual definition of the opened archetype is found, it replaces the forward definition. There is a correctness check at the end of a SIL function deserialization, which verifies that there are no forward definitions of opened archetypes left unresoved.
Strict aliasing only applies to memory operations that use strict
addresses. The optimizer needs to be aware of this flag. Uses of raw
addresses should not have their address substituted with a strict
address.
Also add Builtin.LoadRaw which will be used by raw pointer loads.
Serialize SIL basic blocks in the RPOT order to make sure that instructions defining open archetypes are serialized before instructions using those opened archetypes.
change includes both the necessary protocol updates and the deprecation
warnings
suitable for migration. A future patch will remove the renamings and
make this
a hard error.
...with a better message than the generic "older version of the
compiler" one, when we know it's actually a different version of
Swift proper.
This still uses the same internal module version numbers to check
if the module is compatible; the presentation of language versions
is a diagnostic thing only.
Speaking of module version numbers, this deliberately does NOT
increment VERSION_MINOR; it's implemented in a backwards-compatible
way.
This will only work going forwards, of course; all existing modules
don't have a short version string, and I don't feel comfortable
assuming all older modules we might encounter are "Swift 2.2".
rdar://problem/25680392
The original bug here about not serializing base protocol conformances
is unlikely to return, but I think this still captures the spirit of
the original test: rely on a base protocol conformance without the
model type ever referring to it.
rdar://problem/25125727
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.