To guard the new UnsafeMutablePointer.mutableSpan APIs.
This allows older compilers to ignore the new APIs. Otherwise, the type checker
will crash on the synthesized _read accessor for a non-Escapable type:
error: cannot infer lifetime dependence on the '_read' accessor because 'self'
is BitwiseCopyable, specify '@lifetime(borrow self)'
I don't know why the _read is synthesized in these cases, but apparently it's
always been that way.
Fixes: rdar://153773093 ([nonescapable] add a compiler feature to guard
~Escapable accessors when self is trivial)
Correctly generate dependency tracking for functions that return a non-Escapable
existential, such as:
func getMutableSpanWithOpaqueReturn(_ array: inout [Int]) -> any PAny & ~Copyable & ~Escapable
Previously, dependency insertion assumed that @out storage always initialized an
alloc_stack. But existentials are always boxed.
First, add a diagnostic to catch any missing dependency insertions now that
we're past the bootstrapping phase.
Then, generalize handling of dependency insertion to handle any access base as
long as it has a recognizable address source.
Fixes rdar://150388126 (Missing mark_dependence for opaque lifetime dependent
value)
As specified by the SE-0446 acceptance, extensions that declare a type's
conditional `Copyable` or `Escapable` ability must reiterate explicitly all
of the `Copyable` and/or `Escapable` requirements, whether required or not
required (by e.g. `~Copyable`) that were suppressed in the original
type declaration.
Diagnostics are suppressed when parsing swiftinterface files, since the
warnings emitted from compiling the swiftinterface of a dependency would just
be a nuisance. It follows that warnings generated when parsing the arguments in
a swiftinterface file should also be suppressed, but that wasn't happening
because the diagnostic engine of the main compile was used for parsing. Pass
the diagnostic engine of the compiler subinstance instead, and proactively
suppress warnings before parsing begins.
Resolves rdar://142814164.
When serializing the module interface path of an interface that
is part of the SDK, we serialize relative to the SDK path. During
deserialization we need to know if a path was serialized relative
to the SDK or not. The existing logic assumes any relative path
has been serialized relative to the SDK, which makes it impossible
to compile modules from relative swiftinterface paths that are not
part of the SDK.
Update the swiftmodule file to include an attribute to show if the
path was serialized relative to the SDK or not, which is used
during deserialization to correctly reconstruct the interface path.
When compiling the swiftmodule from the textual swift interface, ensure
that we re-serialise the static or dynamic nature of the module. This is
required for proper code generation where the static and dynamic linking
is material to symbolic references. This also opens the possibility of
optimizations on other platforms via internalisation of the symbols.
Fixes: #77756
Previously, the opaque types in patterns were printed using their full stable
reference which cannot be resolved when parsing a swiftinterface.
Resolves rdar://127771885.
The reverse-condfail workaround needs to be removed, and this is the
first step to allowing the stdlib to build with conditionally escapable
types.
resolves rdar://132453000
A generic signature's `getInnermostGenericParams` will find the generic
parameters in the innermost scope. That's not quite right for printing
inverses, since we don't want to print an inverse for `T` when emitting
the generic signature of `f` below:
```swift
struct S<T: ~Copyable, E> {
func f() where E == Never {}
}
```
Since `f` has its own generic signature, but doesn't define any generic
parameters, it shouldn't have an inverse emitted. The solution here is
to filter inverses by depth of the generic parameter.
We also want to print _all_ of the inverses in other situations, rather
than just the innermost ones. This aids in debugging and other
tools like the API digester.
resolves rdar://130179698
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.
Allow lifetime depenendence on types that are BitwiseCopyable & Escapable.
This is unsafe in the sense that the compiler will not diagnose any use of the
dependent value outside of the lexcial scope of the source value. But, in
practice, dependence on an UnsafePointer is often needed. In that case, the
programmer should have already taken responsibility for ensuring the lifetime of the
pointer over all dependent uses. Typically, an unsafe pointer is valid for the
duration of a closure. Lifetime dependence prevents the dependent value from
being returned by the closure, so common usage is safe by default.
Typical example:
func decode(_ bufferRef: Span<Int>) { /*...*/ }
extension UnsafeBufferPointer {
// The client must ensure the lifetime of the buffer across the invocation of `body`.
// The client must ensure that no code modifies the buffer during the invocation of `body`.
func withUnsafeSpan<Result>(_ body: (Span<Element>) throws -> Result) rethrows -> Result {
// Construct Span using its internal, unsafe API.
try body(Span(unsafePointer: baseAddress!, count: count))
}
}
func decodeArrayAsUBP(array: [Int]) {
array.withUnsafeBufferPointer { buffer in
buffer.withUnsafeSpan {
decode($0)
}
}
}
In the future, we may add SILGen support for tracking the lexical scope of
BitwiseCopyable values. That would allow them to have the same dependence
behavior as other source values.
The basic inheritance clause emission in ASTPrinter operates on
InheritedEntry's, but does not canonicalize types. It's been
designed to consider an entire composition unprintable because one
member is unprintable (e.g., the protocol is not public).
This rejection is what was causing `~Copyable` in some compositions to
be missing from interface files (rdar://126090425). Fixing that is the
purpose of this patch.
What happens, then, if you mix public and nonpublic protocols in a
composition? A second facility called the InheritedProtocolCollector
later does find the public protocols, and emits extensions at the end of
the interface file to declare the additional conformances the ininitial
declaration printer missed.
We can't generally emit `~Copyable` on an extension, so the fix can't
happening there. Refactoring things so there's one source of truth about
the protocols being printed is a sizable refactoring that I will defer
for another time.
resolves rdar://126090425
With the generalization of Optional to support noncopyable types, our
feature-guarding in swiftinterface files would double-print functions
that simply refer to the Optional type.
Since NoncopyableGenerics is a suppressible feature, by default
a second version of Optional and UnsafePointer are emitted into
swiftinterface files, where the ~Copyable generalization is stripped
away.
We can rely on that to avoid double-printing the function, if the types
substituted for the generic parameters are all Copyable.
We need a bit more checking for when
`@_disallowFeatureSuppression(NoncopyableGenerics)` is used, since this
trick relies on there always being a definition of the type we refer to,
whether the feature is enabled or not.
resolves rdar://127389991
It doesn't really make sense for a conditional conformance requirement
for `Copyable` to depend on any other requirement other than other
`Copyable` conformance requirements.
resolves rdar://124967739
When printing declarations with `NoncopyableGenerics2` suppressed we must avoid
printing the `@_preInverseGenerics` attribute and any `borrowing` or
`consuming` parameter ownership modifiers.
Pitch - https://github.com/apple/swift-evolution/pull/2305
Changes highlights:
dependsOn(paramName) and dependsOn(scoped argName) syntax
dependsOn(paramName) -> copy lifetime dependence for all parameters/self except
when we have Escapable parameters/self, we assign scope
lifetime dependence.
Allow lifetime dependence on parameters without ownership modifier.
Always infer copy lifetime dependence except when we have
Escapable parameters/self, we infer scope lifetime dependence.
Allow lifetime dependence inference on parameters without ownership modifier.
Due to the mapping of iOS platform availability to tvOS platform availability,
we were ending up inferring an availability attribute `@available(tvOS)` for
an associated type, which does not parse properly. Suppress the creation
of inferred availability attributes when they convey no information
(e.g., because they have no introduced/deprecated/obsoleted/etc. in them).
Fixes rdar://123545422.
Nested types with inverse requirements on generic parameters would
sometimes print incorrectly. We only print the inverses on outer generic
parameters for extensions.
fixes rdar://123281976
We want extensions to introduce default Copyable/Escapable just like
other generic contexts, so that once Optional adopts ~Copyable,
an `extension Optional` actually adds `Wrapped: Copyable` by default.
In cases where the generic parameter is class-constrained,
`GenericSignature::requiresProtocol` will not contain `Copyable` or
`Escapable` because GenericSignature minimization will recognize that
the class already requires them.
Thus, because classes always require those protocols, we can
simply ask if the generic parameter is required to be a class to
determine if it had any inverses.
Swift generates implicit constructors for inherited designated initializers in
case some implicit initialization (such as running property initializer
expressions) needs to run after calling the initializer on the superclass.
These implicit initializers are printed in .swiftinterfaces and previously they
could cause the interface to fail to typecheck when one of the parameters is
declared to be unavailable-in-Swift. These initializers need to be generated
because they may be called from Objective-C where the unavailable-in-Swift
designation is irrelevant. To account for this possibility, relax availability
checking to allow this narrow exception only in .swiftinterfaces.
Another possible but more complicated solution would be to print the
initializers with an attribute that indicates that the initializer is inherited
and implicit. This would allow the typechecking exception to be more precise
but seems unnecessarily complicated given that the exception is only needed in
.swiftinterfaces, which are already compiler generated.
Resolves rdar://77221357