This is like '@inlinable', except that the symbol does not have a public
entry point in the generated binary at all; it is deserialized and a copy
is always emitted into the client binary, with shared linkage.
Just like '@inlinable', if you apply this to an internal declaration it
becomes '@usableFromInline' automatically.
This uses the same mechanism as default arguments ever since Swift 4, so
it should work reasonably well, but there are rough edges with diagnostics
and such. Don't use this if you are not the standard library.
Fixes <rdar://problem/33767512>, <https://bugs.swift.org/browse/SR-5646>.
This patch mainly consolidates the functions used to check accessors vs.
other decls, and makes sure we check setter access as well as regular
decl access.
rdar://45217648
Static properties are not subject to the same restrictions as properties
whose initializers are exposed to clients in @_fixed_layout types.
rdar://45080912
- Treat protocol requirements just like associated types in how they
inherit usable-from-inline-ness, rather than special-casing them in
the check for inlinable code.
- Enum elements are already treated this way, so we can remove a
redundant check for that.
- Finally, start enforcing that 'dynamic' declarations need to be
'@usableFromInline' to be used in inlinable functions...in Swift 5
mode or resilient code. I didn't even add a warning in Swift 4/4.2
because it was illegal to use '@usableFromInline' on a 'dynamic'
declaration in Swift 4.2. (Oops.)
This has three principal advantages:
- It gives some additional type-safety when working
with known accessors.
- It makes it significantly easier to test whether a declaration
is an accessor and encourages the use of a common idiom.
- It saves a small amount of memory in both FuncDecl and its
serialized form.
We want stored property initializers of fixed layout structs to be
inlinable, so that inlinable initializers can be fully eliminated
by the optimizer.
This is the first step in fixing <rdar://problem/36454839>.
Now that struct initializers "just" fall into the delegating case when
they're made inlinable, the only interesting case is class
initializers, which can be checked in a more direct way than what we
were doing before.
(and when the struct in question is non-fixed-layout, which was
already implemented)
This ensures that these initializers are never fieldwise in Swift 5
mode, which makes it safe for library authors to add new fields.
The -enable-testing flag makes ValueDecl::getEffectiveAccess()
say that internal declarations are public.
This would lead us to emit spurious diagnostics if a default
argument of an internal function referenced a private symbol,
for example, which is something we actually want to allow.
This is a second revision of the patch -- instead of changing
getEffectiveAccess() to take an extra parameter, this changes
getFormalAccessScope() instead.
Fixes <rdar://problem/32592973>.
The -enable-testing flag makes ValueDecl::getEffectiveAccess()
say that internal declarations are public.
This would lead us to emit spurious diagnostics if a default
argument of an internal function referenced a private symbol,
for example, which is something we actually want to allow.
Hack around this by adding a new 'forLinkage' parameter to
getEffectiveAccess(). When this is false, we ignore the
-enable-testing flag, and only look for the @_versioned
attribute.
I'm not very happy with the fix, because it only compliates
the subtle behaviors of getFormalAccess(), getEffectiveAccess()
and getFormalAccessScope() further. But refactoring this is
a bigger change than I'm willing to put into swift-4.0-branch.
Fixes <rdar://problem/32592973>.
The root cause is that NormalProtocolConformance::forEachValueWitness()
needs to skip protocol members that are not requirements.
Otherwise we end up passing such a non-requirement member down to
NormalProtocolConformance::getWitness() and hit an assert when we
cannot find it.
It looks like this code path was only ever hit from SourceKit.
The fix moves TypeChecker::isRequirement() to a method on ValueDecl,
and calls it in the right places.
Fixes <https://bugs.swift.org/browse/SR-3815>.
Value type initializers must initialize stored properties directly
if they do not delegate to another initializer via self.init().
Since direct stored property access is not permitted for resilient
value types from outside their resilience domain, this means that
such initializers are prohibited in two cases:
- If the initializer is defined in an extension from outside the
value type's resilience domain
- If the initializer is public and @_inlineable, since it might get
inlined outside the value type's resilience domain
Right now, such initializers cannot *assign* to self either;
I filed <https://bugs.swift.org/browse/SR-3686> to track the issue.
Protocol members can be directly referenced from protocol extensions
and generic functions. Since protocol members do not have accessibility
distinct from the protocol itself, ignore them, since they won't carry
the @_versioned attribute.
While workign on this I uncovered an interesting bug where we allow
members of protocol extensions to be more accessible than the protocol
itself, but then we give the symbols hidden visibility at the SIL level
anyway.
I filed <https://bugs.swift.org/browse/SR-3684> to track this issue.
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.