There are a few places in the AST where we use `uint64_t` as
`ArrayRef`'s size type. Even though of these `uint64_t` size fields are
actually defined as bitfields with a maximum value of 32, but
unfortunately it's not taken into account and clang complains about
the implicit cast.
The same attempt was made in 073905b573,
but several new places were added since then.
Since availability scopes may be built at arbitrary times, the builder may
encounter ASTs where SequenceExprs still exist and have not been folded, or it
may encounter folded SequenceExprs that have not been removed from the AST.
To avoid a double visit, track whether a SequenceExpr is folded and then
customize how ASTVisitor handles folded sequences.
Resolves rdar://142824799 and https://github.com/swiftlang/swift/issues/78567.
Introduce an `unsafe` expression akin to `try` and `await` that notes
that there are unsafe constructs in the expression to the right-hand
side. Extend the effects checker to also check for unsafety along with
throwing and async operations. This will result in diagnostics like
the following:
10 | func sum() -> Int {
11 | withUnsafeBufferPointer { buffer in
12 | let value = buffer[0]
| | `- note: reference to unsafe subscript 'subscript(_:)'
| |- warning: expression uses unsafe constructs but is not marked with 'unsafe'
| `- note: reference to parameter 'buffer' involves unsafe type 'UnsafeBufferPointer<Int>'
13 | tryWithP(X())
14 | return fastAdd(buffer.baseAddress, buffer.count)
These will come with a Fix-It that inserts `unsafe` into the proper
place. There's also a warning that appears when `unsafe` doesn't cover
any unsafe code, making it easier to clean up extraneous `unsafe`.
This approach requires that `@unsafe` be present on any declaration
that involves unsafe constructs within its signature. Outside of the
signature, the `unsafe` expression is used to identify unsafe code.
Put AvailabilityRange into its own header with very few dependencies so that it
can be included freely in other headers that need to use it as a complete type.
NFC.
`UnsafeCastExpr` - A special kind of conversion that performs an unsafe
bitcast from one type to the other.
Note that this is an unsafe operation and type-checker is allowed to
use this only in a limited number of cases like: `any Sendable` -> `Any`
conversions in some positions, covariant conversions of function and
function result types.
There are a bunch of AST nodes that can have
associated DeclNameLocs, make sure we cover them
all. I don't think this makes a difference for
`unwrapPropertyWrapperParameterTypes` since the
extra cases should be invalid, but for cursor info
it ensures we handle UnresolvedMemberExprs.
Now that IUOs are supported for compound function
references, we can properly set the compound bit
here.
This is a source breaking change since this used
to be legal:
```swift
struct S {
static func foo(x: Int) -> Self { .init() }
}
let _: S = .foo(x:)(x: 0)
```
However I somewhat doubt anyone is intentionally
writing code like that.
FunctionRefKind was originally designed to represent
the handling needed for argument labels on function
references, in which the unapplied and compound cases
are effectively the same. However it has since been
adopted in a bunch of other places where the
spelling of the function reference is entirely
orthogonal to the application level.
Split out the application level from the
"is compound" bit. Should be NFC. I've left some
FIXMEs for non-NFC changes that I'll address in a
follow-up.
This problem comes up with the following example:
```swift
class A {
var description = ""
}
class B {
let a = A()
func b() {
let asdf = ""
Task { @MainActor in
a.description = asdf // Sending 'asdf' risks causing data races
}
}
}
```
The specific issue is that the closure we generate actually includes an
implicit(any) parameter at the SIL level which occurs after the callee operand
but before the captures. This caused the captured variable index from the AST
and the one we compute from the partial_apply to differ by 1. So we need to
subtract 1 in such a case. That is why we used to print 'asdf' instead of 'a'
above.
DISCUSSION: This shows an interesting difference between SIL applied arg indices
and AST indices. SIL applied arg indices would include the implicit(any)
parameter since it is a parameter in the SIL function type. In contrast, this
doesn't show up in the formal AST parameters or captures. To make it easier to
reason about this, I added a new API to ApplySite called
ApplySite::getASTAppliedArgIndex and added large comments to
getASTAppliedArgIndex and getAppliedArgIndex that explains the issue.
rdar://136593706
https://github.com/swiftlang/swift/issues/76648
Add the necessary compiler-side logic to allow
the regex parsing library to hand back a set of
features for a regex literal, which can then be
diagnosed by ExprAvailabilityWalker if the
availability context isn't sufficient. No tests
as this only adds the necessary infrastructure,
we don't yet hand back the features from the regex
parsing library.
Instead of doing the pattern parsing in both the
C++ parser and ASTGen, factor out the parsing into
a request that returns the pattern to emit, regex
type, and version. This can then be lazily run
during type-checking.
Also rename it to `getExplicitReturnStmts` for clarity and have it
take a `SmallVector` out parameter instead as a small optimization and
to discourage use of this new method as an alternative to
`AnyFunctionRef::bodyHasExplicitReturnStmt`.
`participatesInInference` is now always true for
a non-empty body, remove it along with the separate
type-checking logic such that empty bodies are
type-checked together with the context.
Some requirement machine work
Rename requirement to Value
Rename more things to Value
Fix integer checking for requirement
some docs and parser changes
Minor fixes
This is an important information for closures because the compiler
might need to emit dynamic actor isolation checks in some circumstances
(i.e. when a closure is isolated and passed to a not fully concurrency
checked API).
Consider the following piece of code and what the isolation is of the closure
literal passed to doSomething():
```swift
func doSomething(_ f: sending () -> ()) { ... }
@MyCustomActor
func foo() async {
doSomething {
// What is the isolation here?
}
}
```
In this case, the isolation of the closure is @MyCustomActor. This is because
non-Sendable closures are by default isolated to their current context (in this
case @MyCustomActor since foo is @MyCustomActor isolated). This is a problem
since
1. Our closure is a synchronous function that does not have the ability to hop
to MyCustomActor to run said code. This could result in a concurrency hole
caused by running the closure in doSomething() without hopping to
MyCustomActor's executor.
2. In Region Based Isolation, a closure that is actor isolated cannot be sent,
so we would immediately hit a region isolation error.
To fix this issue, by default, if a closure literal is passed as a sending
parameter, we make its isolation nonisolated. This ensures that it is
disconnected and can be transferred safely.
In the case of an async closure literal, we follow the same semantics, but we
add an additional wrinkle: we keep support of inheritActorIsolation. If one
marks an async closure literal with inheritActorIsolation, we allow for it to be
passed as a sendable parameter since it is actually Sendable under the hood.
We now compute captures of functions and default arguments
lazily, instead of as a side effect of primary file checking.
Captures of closures are computed as part of the enclosing
context, not lazily, because the type checking of a single
closure body is not lazy.
This fixes a specific issue with the `-experimental-skip-*` flags,
where functions declared after a top-level `guard` statement are
considered to have local captures, but nothing was forcing these
captures to be computed.
Fixes rdar://problem/125981663.
To be used in situations when a global actor isolation is stripped
from a function type in argument positions and could be extended in
the future to cover more if needed.
This models the conversion from an uninhabited
value to any type, and allows us to get rid of
a couple of places where we'd attempt to drop
the return statement instead.
Remove this bit from function decls and closures.
Instead, for closures, infer it from the presence
of a single return or single expression AST node
in the body, which ought to be equivalent, and
automatically takes result builders into
consideration. We can also completely drop this
query from AbstractFunctionDecl, replacing it
instead with a bit on ReturnStmt.
This commit makes it so that we treat values captured by an actor isolated
closure as being transferred to that closure. I also introduced a new diagnostic
for these warnings that puts the main warning on the capture point of the value
so the user is able to see the actual capture that causes the transfer to occur:
```swift
nonisolated func testLocal2() async {
let l = NonSendableKlass()
// This is not safe since we use l later.
self.assumeIsolated { isolatedSelf in
isolatedSelf.ns = l
}
useValue(l) // expected-note {{access here could race}}
}
```
```
test.swift:74:14: warning: main actor-isolated closure captures value of non-Sendable type 'NonSendableKlass' from nonisolated context; later accesses to value could race
useValue(x) // expected-warning {{main actor-isolated closure captures value of non-Sendable type 'NonSendableKlass' from nonisolated context; later accesses to value could race}}
^
test.swift:76:12: note: access here could race
useValue(x) // expected-note {{access here could race}}
^
```
One thing to keep in mind is that if we have a function argument being captured
in this way, we still emit the "call site passes `self`" error. I am going to
begin cleaning that up in the next commit in this PR so that we emit a better
error here. But it makes sense to split these into two separate commits since
they are doing different things.
rdar://121345525
It's not clear that its worth keeping this as a
base class for SerializedAbstractClosure and
SerializedTopLevelCodeDecl, most clients are
interested in the concrete kinds, not only whether
the context is serialized.
Introduce a new expression macro that produces an value of type
`(any AnyActor)?` that describes the current actor isolation. This
isolation will be `nil` in non-isolated code, and refer to either the
actor instance of shared global actor in other cases.
This is currently behind the experimental feature flag
OptionalIsolatedParameters.
Due to the duality between the expression and declaration forms of
freestanding macros, we could end up assigning two different discriminators
to what is effectively the same freestanding macro expansion. Across
different source files, this could lead to inconsistent discriminators in
different translation units. Unify the storage of the discriminator to
avoid this issue.
Fixes rdar://116259748