Annotate all of the `Unsafe*` types and `unsafe` functions in the standard
library (including concurrency, synchronization, etc.) as `@unsafe`. Add a
few tests to ensure that we detect uses of these types in clients that
have disabled unsafe code.
The stdlib is always built with NoncopyableGenerics enabled, so `#if
$NoncopyableGenerics` guards in non-inlinable code are superfluous.
Additionally, the stdlib's interface no longer needs to support compilers
without the feature, so the guards in inlinable code can also be removed.
If the extension adds conformance to an invertible protocol, it's
confusing for people to also infer conditional requirements on the
generic parameters for those invertible protocols. This came up in the
review of SE-427.
There were two categories of problem for older compilers that consume the
stdlib `.swiftinterface`:
- The `case .some(borrowing x)` syntax isn't accepted; use `_borrowing`
- Various functions that addopted `~Copyable` generic constraints conflict with
the `@usableFromInline` ABI stubs that were left in to preserve compatibility
when the functions are printed with `~Copyable` constraints stripped. The stubs
need to have different names to get out of the way.
Resolves rdar://127132742
The new ~Copyable generalizations have changed the function signature enough that alternative definitions of `map`/`flatMap` in existing code that used to be considered to shadow the originals no longer do so. This leads to use sites becoming ambiguous — a source break.
While we consider approaches to resolve this on the compiler side, let’s try slapping a `@_disfavoredOverload` on these and see if that helps.
If an expression refers to noncopyable storage, then default to performing
a borrowing switch, where `let` bindings in patterns borrow out of the
matched value. If an expression refers to a temporary value or explicitly
uses the `consume` keyword, then perform a consuming switch, where
`let` bindings take ownership of corresponding parts of the matched value.
Allow `_borrowing` to still be used to explicitly bind a pattern variable
as a borrow, with no-implicit-copy semantics for copyable values.
- Enable BorrowingSwitch feature within the stdlib
- ExpressibleByNilLiteral: Add retroactive support for noncopyable conforming types
- Optional: draft an API surface for noncopyable payloads
[stdlib] Oops, the ExpressibleByNilLiteral conformance kept its implicit copyability
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
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.
Introduce checking of ConcurrentValue conformances:
- For structs, check that each stored property conforms to ConcurrentValue
- For enums, check that each associated value conforms to ConcurrentValue
- For classes, check that each stored property is immutable and conforms
to ConcurrentValue
Because all of the stored properties / associated values need to be
visible for this check to work, limit ConcurrentValue conformances to
be in the same source file as the type definition.
This checking can be disabled by conforming to a new marker protocol,
UnsafeConcurrentValue, that refines ConcurrentValue.
UnsafeConcurrentValue otherwise his no specific meaning. This allows
both "I know what I'm doing" for types that manage concurrent access
themselves as well as enabling retroactive conformance, both of which
are fundamentally unsafe but also quite necessary.
The bulk of this change ended up being to the standard library, because
all conformances of standard library types to the ConcurrentValue
protocol needed to be sunk down into the standard library so they
would benefit from the checking above. There were numerous little
mistakes in the initial pass through the stsandard library types that
have now been corrected.