The IsolatedConformances feature moves to a normal, supported feature.
Remove all of the experimental-feature flags on test cases and such.
The InferIsolatedConformances feature moves to an upcoming feature for
Swift 7. This should become an adoptable feature, adding "nonisolated"
where needed.
(cherry picked from commit 3380331e7e)
When a generic function has potentially Escapable outputs, those outputs
declare lifetime dependencies, which have no effect when substitution
leads to those types becoming `Escapable` in a concrete context.
This means that type substitution should canonically eliminate lifetime
dependencies targeting Escapable parameters or returns, and that
type checking should allow a function value with potentially-Escapable
lifetime dependencies to bind to a function type without those dependencies
when the target of the dependencies is Escapable.
Fixes rdar://147533059.
Introduce a marker protocol SendableMetatype that is used to indicate
when the metatype of a type will conform to Sendable. Specifically,
`T: SendableMetatype` implies `T.Type: Sendable`. When strict
metatype sendability is enabled, metatypes are only sendable when `T:
SendableMetatype`.
All nominal types implicitly conform to `SendableMetatype`, as do the
various builtin types, function types, etc. The `Sendable` marker
protocol now inherits from `SendableMetatype`, so that `T: Sendable`
implies `T.Type: Sendable`.
Thank you Slava for the excellent idea!
Introduce a new experimental feature StrictSendableMetatypes that stops
treating all metatypes as `Sendable`. Instead, metatypes of generic
parameters and existentials are only considered Sendable if their
corresponding instance types are guaranteed to be Sendable.
Start with enforcing this property within region isolation. Track
metatype creation instructions and put them in the task's isolation
domain, so that transferring them into another isolation domain
produces a diagnostic. As an example:
func f<T: P>(_: T.Type) {
let x: P.Type = T.self
Task.detached {
x.someStaticMethod() // oops, T.Type is not Sendable
}
}
`Builtin.FixedArray<let N: Int, T: ~Copyable & ~Escapable>` has the layout of `N` elements of type `T` laid out
sequentially in memory (with the tail padding of every element occupied by the array). This provides a primitive
on which the standard library `Vector` type can be built.
A conditional conformance to a protocol does not usually imply
a conformance to the protocol's inherited protocols, because
we have no way to guess what the conditional requirements
should be.
A carveout was added for 'Sendable', so that protocols could
inherit from 'Sendable' retroactively. However, the 'Sendable'
conformance would become conditional, which causes us to
reject a _second_ conditional conformance to such a protocol:
struct G<T> {}
protocol P: Sendable {}
protocol Q: Sendable {}
extension G: P where T: P {}
extension G: Q where T: Q {}
To make this work, tweak the code so that an implied conformance
has the same generic signature as the conforming type, that is,
we force it to be unconditional.
Fixes rdar://122754849
Fixes https://github.com/swiftlang/swift/issues/71544
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
Even if protocol is not self-conforming it should be okay to produce
a conformance based on superclass if protocol bounds of the existential
are all marker protocols.
Superclass concrete conformance is wrapped into an inherited conformance
in such cases to reference the existential.
We want a conditionally-copyable type to still be classified as trivial in cases
where it's bitwise-copyable, has a trivial deinit, and is Copyable. The previous
implementation here only checked at the declaration level whether a type was
Copyable or not; get a more accurate answer by consulting the combination
of information in the substituted type and abstraction pattern we have
available during type lowering so that we classify definitely-copyable substitutions
of a conditionally-copyable type as trivial. Should fix rdar://123654553 and
rdar://123658878.
With NoncopyableGenerics, we get a cycle involving
`SuperclassTypeRequest` with this program:
public struct RawMarkupHeader {}
final class RawMarkup: ManagedBuffer<RawMarkupHeader, RawMarkup> { }
Because we generally don't support the following kind of relationship:
class Base<T: P>: P {}
class Derived: Base<Derived> {}
This commit works around the root-cause, which is that Derived's
synthesized conformance to Copyable gets superceded by the inherited one
from Base. Instead of recording conformances in the ConformanceLookup
table at all, create builtin conformances on the fly, since classes
cannot be conditionally Copyable or Escapable.
There's a few uses of ReferenceStorageTypes being substituted for
generic parameters, at least in the test suite, such as
`Optional<@sil_unmanaged ..>` and just plain `<@sil_unowned ..>`.
Before, conformance lookup could (and did) give bogus answers when asked
if the type satisfies any conformance requirements. Now with
NoncopyableGenerics, we will interpret such conformance lookups as
being asked of the referent type, ignoring the SIL ownership wrapping
it.
I thought it might be impossible to recursively lookupConformance of
Copyable, unlike for Sendable. Turns out there are still situations
where it can happen, that aren't invalid.
This alone fixes `ClangImporter/objc_bridging_generics.swift` and will
help reveal any invalid request cycles.
I thought this would be simple to add a check for this, but it turns out
that a more complete refactoring that eliminates `isNoEscape` in favor
of `isEscapable` is most likely needed.
An unbound generic type is not something that should end up in
`isNoncopyable` or `isEscapable` queries because there are no
conformances for such a type; it's unbound!
fixes test/Constraints/closures.swift
First, "can have an absence of Copyable" is a rather confusing notion,
so the query is flipped to "can be Copyable". Next, it's more robust to
ask if a conformance exists for the TypeDecl to answer that question,
rather than trying to replicate what happens within that conformance
lookup.
Also renames `TypeDecl::isEscapable` to match.