The patch introduces a new setting instead of changing existing settings
because the generated interfaces in the IDE have slightly different
requirements; the extended type there is unconditionally not printed
qualified (even if it is ambiguous). This is likely because the
ambiguity heuristic is very weak; it doesn't even do name lookup.
Simplifying that logic would be nice, but then we'd need to update
a bunch of IDE/print* tests and end up with more more visual clutter
in the IDE.
Introducing the new setting means we can change the behavior for
swiftinterface files without affecting the behavior for IDE interfaces.
Fixes rdar://79093752.
Let's point out the associated type with a separate note, so
that we can diagnose other availability failures, such as
deprecation and OS version availability.
In @frozen structs, stored properties and property wrappers must
have inlinable initial value expressions, since they are re-emitted
into designated initializer bodies, which themselves might be
@inlinable.
However, 'lazy' properties don't follow this pattern; the
initial value expression is emitted inside the getter, which
is never @inlinable.
We need to prohibit 'lazy' properties and property wrappers from
being declared @_spi inside of a @frozen struct. Making them SPI
doesn't make sense, because these properties will be omitted from the
module interface and not taken into account when clients manipulate
values of this type.
There's no need to check for that here, because we also run
diagnoseDeclRefExportability() on declarations referenced
from inlinable code.
This changes some diagnostics; we now produce the same diagnostic
for references to SPI types in declaration signatures and for
references to non-type SPI declarations in inlinable function bodies.
Also note that the old inlinable reference diagnostic no longer has
to handle the 'public' and 'open' access levels, which previously
happened for '@_spi'; so I changed those entries in the %select to
%error.
Converting the innermost DeclContext into a Decl won't work if
the innermost DeclContext is the parent context of a VarDecl.
Instead, use the relevant bit of state from the ExportContext,
which is computed correctly.
This fixes a regression caused by an earlier commit in this PR
which our test suite did not catch.
Availability checking already knows how to check exportability for
types and conformances referenced from inlinable function signatures
and bodies.
Let's generalize this to work on non-inlinable function signatures
as well, allowing us to get rid of the ExportabilityChecker altogether.
We used to diagnose references to unavailable declarations in
two places:
- inside Exprs, right after type checking the expression
- inside TypeReprs, from resolveType()
In broad terms, resolveType() is called with TypeReprs
stored inside both Stmts and Decls.
To handle the first case, I added a new overload of
diagAvailability() that takes a Stmt, to be called from
typeCheckStmt(). This doesn't actually walk into any Exprs
stored inside the statement; this means it only walks
Patterns and such.
For the second case, a new DeclAvailabilityChecker is
now defined in TypeCheckAccess.cpp. It's structure is
analogous to the other three walkers there:
- AccessControlChecker
- UsableFromInlineChecker
- ExportabilityChecker
The new implementation of availability checking for types
introduces a lot more code than the old online logic
it replaces. However, I hope to consolidate some of the
code duplication among the four checkers that are defined
in TypeCheckAccess.cpp, and do some other cleanups that
will make the benefit of the new approach apparent.
```
@_specialize(exported: true, spi: SPIGroupName, where T == Int)
public func myFunc() { }
```
The specialized entry point is only visible for modules that import
using `_spi(SPIGroupName) import ModuleDefiningMyFunc `.
rdar://64993425
Remove the fast path skipping evaluating SPI groups for non-public
decls. This knowledge is still required to allow the use of SPI types in
the signatures of `@usableFromInline` declarations and in internal
properties of structs in non library evolution compilation.
rdar://68530659
rdar://68527580
Extensions to implementation-only types are accepted at type-checking
only if they don't define any public members. However if they declared a
conformance to a public type they were also printed in the
swiftinterface, making it unparsable because of an unknown type.
Still accept such extensions but don't print them.
rdar://problem/67516588
Print implementation-only imports in the private textual interface
only if also importing SPI. This allows to export types from
implementation-only imports in SPI and brings the private textual
interfaces in line with the binary interfaces.
This is a temporary solution as we need to better design the language
feature around this.
This feature requires passing -experimental-spi-imports to the frontend
that generates the private swiftinterface file.
The check for SPI protocol requirements needing a default implementation
should ignore requirements in a protocol that is SPI too. The protocol
can’t be conformed to without knowing of the requirement.
rdar://65286171
When emitting the private swiftinterface, the compiler prints the
attribute explicitly even when it is deduced from the context. This can
lead to unparsable private swiftinterface files.
As a narrow fix, check if the decl type is supported before printing the
attribute.
rdar://64039069
Using a SetVector fixes an issue where many source files imported the
same SPI group from the same module, the emitted private textual
interfaces superfluously repeated the `@_spi` attribute on the import.
rdar://problem/63681845