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.
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.
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.
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
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.
We can't simply emit the desugared, expanded version of the requirements
because there's no way to pretty-print the type `some ~Copyable` when
the `~Copyable`'s get replaced with the absence of `Copyable`. We'd be
left with just `some _` or need to invent a new top type so we can write
`some Top`. Thus, it's best to simply reverse the expansion of default
requirements when emitting a swiftinterface file.