When the Swift module is not available, we'll synthesize the
Copyable/Escapable decls into the Builtin module.
In the future, it might be nice to just do this always, and define
typealiases for those types in the stdlib to refer to the ones in the
builtin module.
It's harmless to have the protocol defined in the swiftinterface for
older compilers and removing the gating permits the gating to be omitted
from conformances
Adopt typed throws for the `map` operation to propagate thrown error
types through the `map` API. This is done in a manner that is backward
compatible for almost all cases:
* The new typed-throws entrypoint is `@_alwaysEmitIntoClient` so it
can back-deploy all the way back.
* The old `rethrows` entrypoint is left in place, using
`@usableFromInline` with `internal` so it is part of the ABI but not
the public interface, and `@_disfavoredOverload` so the type checker
avoids it while building the standard library itself. The old
entrypoint is implemented in terms of the new one.
Note that the implementation details for the existential collection
"box" classes rely on method overriding of `_map` operations, and the
types are frozen, so we don't get to change their signatures. However,
these are only implementations, not API: the actual API `map`
functions can be upgraded to typed throws.
Note that this code makes use of a known hole in `rethrows` checking
to allow calling between `rethrows` and typed throws. We'll need to do
something about this for source-compatibility reasons, but I'll follow
up with that separately.
When building the stdlib with noncopyable generics enabled,
requirements for Copyable and Escapable end up being inferred on the
protocols Copyable and Escapable, themselves. So we need to opt-out
Copyable from requiring Escapable, and vice versa.
Adopt typed throws for the `map` operation to propagate thrown error
types through the `map` API. This is done in a manner that is backward
compatible for almost all cases:
* The new typed-throws entrypoint is `@_alwaysEmitIntoClient` so it
can back-deploy all the way back.
* The old `rethrows` entrypoint is left in place, using
`@usableFromInline` with `internal` so it is part of the ABI but not
the public interface, and `@_disfavoredOverload` so the type checker
avoids it while building the standard library itself. The old
entrypoint is implemented in terms of the new one.
Note that the implementation details for the existential collection
"box" classes rely on method overriding of `_map` operations, and the
types are frozen, so we don't get to change their signatures. However,
these are only implementations, not API: the actual API `map`
functions can be upgraded to typed throws.
Note that this code makes use of a known hole in `rethrows` checking
to allow calling between `rethrows` and typed throws. We'll need to do
something about this for source-compatibility reasons, but I'll follow
up with that separately.
This isn't a "complete" port of the standard library for embedded Swift, but
something that should serve as a starting point for further iterations on the
stdlib.
- General CMake logic for building a library as ".swiftmodule only" (ONLY_SWIFTMODULE).
- CMake logic in stdlib/public/core/CMakeLists.txt to start building the embedded stdlib for a handful of hardcoded target triples.
- Lots of annotations throughout the standard library to make types, functions, protocols unavailable in embedded Swift (@_unavailableInEmbedded).
- Mainly this is about stdlib functionality that relies on existentials, type erasure, metatypes, reflection, string interpolations.
- We rely on function body removal of unavailable functions to eliminate the actual problematic SIL code (existentials).
- Many .swift files are not included in the compilation of embedded stdlib at all, to simplify the scope of the annotations.
- EmbeddedStubs.swift is used to stub out (as unavailable and fatalError'd) the missing functionality.
The _Copyable constraint was implemented as a marker protocol.
That protocol is part of the KnownProtocol's in the compiler.
When `ASTContext::getProtocol(KnownProtocolKind kind)` tries
to find the ProtocolDecl for Copyable, it will look in the
stdlib module (i.e., Swift module), which is where I initially
planned to put it.
That created problems initially when some regression tests
use `-parse-stdlib` failed to do that protocol lookup, which is
essential for adding the constraint (given the current implementation).
That led to believe we need to pull Copyable out of the stdlib, but that's
wrong. In fact, when building the Swift module itself, we do `-parse-stdlib`
but we also include `-module-name Swift`. This causes the _Copyable protocol
defined in the Stdlib to be correctly discovered while building the stdlib
itself (see the test case in this commit). So, the only downside of
having the Copyable protocol in the Stdlib is that `-parse-stdlib` tests
in the compiler can't use move-only types correctly, as they'll be
allowed in generic contexts. No real program would build like this.
Until I have time to do a further refactoring, this is an acceptable trade-off.
fixes rdar://104898230
Since values of generic type are currently assumed to always
support copying, we need to prevent move-only types from
being substituted for generic type parameters.
This approach leans on a `_Copyable` marker protocol to which
all generic type parameters implicitly must conform.
A few other changes in this initial implementation:
- Now every concrete type that can conform to Copyable will do so. This fixes issues with conforming to a protocol that requires Copyable.
- Narrowly ban writing a concrete type `[T]` when `T` is move-only.
To be able to constant fold string interpolation, the right semantic attributes must be in place.
Also, the interpolation's write function must be inlinable.
For the _typeName constant folding, a semantic attribute is required.
If a key path literal appears in a generic context with an existing context descriptor, this will allow us to
save some code size by not having to emit a separate GenericEnvironment descriptor.
This can be used by compiler-generated code as a size optimization for metadata access, using a
mangled name instead of possibly many open-coded metadata calls. It can also allow reflection
libraries outside of the standard library to turn type reference strings into in-process metadata
pointers in a robust way. rdar://problem/46451849
Always use mangled type names to represent type metadata in keypath patterns.
For generic types, use the generic environment to pull substituted types
from the instantiation arguments.
Finishes the type metadata part of rdar://problem/38038799.
Simplify the signature of the internal _getTypeByMangledName() used by the
standard library to what we actually (currently) use. Drop it as a
compatibility override, because it’s not a useful place to introduce
customization.
Refactor and rename _StringGutsSlice, apply NFC-aware fast paths to a
new buffered iterator.
Also, fix bug in _typeName which used to assume ASCIIness and better
SIL optimizations on StringObject.
Streamline internal String creation. Previously, everything funneled
into a single generic function, however, every single call of the
generic funnel had relevant specific information that could be used
for a more efficient algorithm.
In preparation for efficiently forming small strings, refactor this
logic into a handful of more specialized subroutines to preserve more
specific information from the callers.