Instead of caching the collection of visible Clang modules in the 'TypePrinter', compute and cache them in the 'ModuleDecl'. When printing a textual interface, the compiler will instantiate many new instances of 'TypePrinter', which means caching them there is not useful.
If a protocol provides a deprecated default implementation for a requirement
that is not deprecated, the compiler should emit a warning so the programmer
can provide an explicit implementation of the requirement. This is helpful
for staging in new protocol requirements that should be implemented in
conforming types.
Distributed actors can be treated as actors by accessing the `asLocalActor`
property. When lowering `#isolation` in a distributed actor initializer,
use a separate builtin `flowSensitiveDistributedSelfIsolation` to
capture the conformance to `DistributedActor`, and have Definite
Initialization introduce the call to the `asLocalActor` getter when
needed.
Actor initializers have a flow-sensitive property where they are isolated
to the actor being initialized only after the actor instance itself is
fully-initialized. However, this behavior was not being reflected in
the expansion of `#isolation`, which was always expanding to `self`,
even before `self` is fully formed.
This led to a source compatibility issue with code that used the async
for..in loop within an actor initializer *prior* to the point where the
actor was fully initialized, because the type checker is introducing
the `#isolation` (SE-0421) but Definite Initialization properly rejects
the use of `self` before it is initialized.
Address this issue by delaying the expansion of `#isolation` until
after the actor is fully initialized. In SILGen, we introduce a new
builtin for this case (and *just* this case) called
`flowSensitiveSelfIsolation`, which takes in `self` as its argument
and produces an `(any Actor)?`. Definite initialization does not treat
this as a use of `self`. Rather, it tracks these builtins and
replaces them either with `self` (if it is fully-initialized at this
point) or `nil` (if it is not fully-initialized at this point),
mirroring the flow-sensitive isolation semantics described in SE-0327.
Fixes rdar://127080037.
Removing the old, ad-hoc diagnostics code improves the diagnostics we
emit, since the existing diagnostics for missing conformances is already
pretty good.
rdar://127369509
There are a number of implicit conversions in Swift, such as to Optional
and to an existential, which are now possible for noncopyable types.
But all type casts are consuming operations for noncopyable types. So
it's confusing when a function that takes a borrowed argument of
optional type appears to be consuming:
```
func f(_ x: borrowing NC?) { ... }
let x = NC()
f(x)
f(x) // error!
```
So, rather than for people to write `x as T?` around all implicit
conversions, require them to write `consume x` around expressions
that will consume some lvalue. Since that makes it much more clear what
the consequences will be.
Expressions like `f(g())`, where you're passing an rvalue to the callee,
are not confusing. And those are exactly the expressions you're not
allowed to write `consume` for, anyway.
fixes rdar://127450418
We are leaving this as an open part of the design space. In the mean time if
people need a +0 parameter, they can use __shared with sending.
rdar://129116182
We want to ensure that functions/methods themselves do not have sending mangled
into their names, but we do want sending mangled in non-top level positions. For
example: we do not want to mangle sending into a function like the following:
```swift
// We don't want to mangle this.
func test(_ x: sending NonSendableKlass) -> ()
```
But when it comes to actually storing functions into memory, we do want to
distinguish in between function values that use sending vs those that do not
since we do not want to allow for them to alias. Thus we want to mangle sending
into things like the following:
```swift
// We want to distinguish in between Array<(sending T) -> ()> and
// Array((T) -> ()>
let a = Array<(sending T) -> ()>
// We want to distinguish in between a global contianing (sending T) -> () and a
// global containing (T) -> ().
var global: (sending T) -> ()
```
This commit achieves that by making changes to the ASTMangler in getDeclType
which causes getDeclType to set a flag that says that we have not yet recursed
through the system and thus should suppress the printing of sendable. Once we
get further into the system and recurse, that flag is by default set to true, so
we get the old sending parameter without having to update large amounts of code.
rdar://127383107
Teach dependency scanner to report all the module canImport check result
to swift-frontend, so swift-frontend doesn't need to parse swiftmodule
or parse TBD file to determine the versions. This ensures dependency
scanner and swift-frontend will have the same resolution for all
canImport checks.
This also fixes two related issues:
* Previously, in order to get consistant results between scanner and
frontend, scanner will request building the module in canImport check
even it is not imported later. This slightly alters the definition of
the canImport to only succeed when the module can be found AND be
built. This also can affect the auto-link in such cases.
* For caching build, the location of the clang module is abstracted away
so swift-frontend cannot locate the TBD file to resolve
underlyingVersion.
rdar://128067152
This isn't fully implemented yet so it would crash eventually, so instead of
letting the compiler crash put up a proper diagnostic indicating this isn't
yet implemented. rdar://129034189
The computation that determined whether an access to a `let` instance
property within a constructor should be an initialization conflated the
cases of "we don't have a base expression" and "the base expression is
not something that could be `self`", and incorrectly identified rvalue
bases as being "initializable". Make the interface properly separate
out these cases, so we don't turn an lvalue into an rvalue access.
Fixes rdar://128661833.
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.