We're not quite ready to commit to the flow-sensitive check that would
allow a concurrent function to read from a mutable local capture so
long as the captured variable wasn't changed after the point of
capture. Put it behind a flag and implement the more restrictive rule
(no access to mutable local captures in concurrent code). We can relax
it later.
When referring to an actor-isolated declaration from outside of the
actor, ensure that the types involved conform to the `ConcurrentValue`
protocol. Otherwise, produce a diagnostic stating that it is unsafe to
pass such types across actors.
Apply the same rule to local captures within concurrent code.
Previously, the name of the entry point function was always main. Here,
a new frontend flag is added to enable an arbitrary name to be
specified.
rdar://58275758
This follows the design of how we handled this with
sil-verify-all. Specifically, the default behavior is to run only in asserts
builds, but one can use the two flags: enable-ast-verifier and
disable-ast-verifier to override the default behavior.
The reason why this is interesting is that this means that when compiling
normally, we will not run the verifier, so we won't have a perf hit. But we can
now ask the user to run with this flag (or in a future maybe a re-run in the
driver would do this for them), saving us time when screening bugs by avoiding
the need to build an asserts compiler to triage if the ASTVerifier would catch
the bug.
-enable-subst-sil-function-types-for-function-values
-enable-large-loadable-types
These defaulted to on, and there were no corresponding flags for
turning them off, so the flags had no effect.
Passing the frontend flag -Rmodule-loading makes the compiler emit
remarks with the path of every module loaded. The path for Swift modules
is either the swiftinterface file for modules built with library
evolution or the binary swiftmodule otherwise. The path for clangmodules
is always in the cache which could be improved as it may be less useful.
Here's an extract of the output for a simple SwiftUI app:
<unknown>:0: remark: loaded module from
/Users/xymus/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/2VJP7CNCGWRF0/SwiftShims-18ZF6992O9H75.pcm
<unknown>:0: remark: loaded module from
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.2.sdk/usr/lib/swift/Swift.swiftmodule/x86_64-apple-ios-simulator.swiftinterface
<unknown>:0: remark: loaded module from
/Users/xymus/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/2VJP7CNCGWRF0/os-1HVC6DNXVU37C.pcm
<unknown>:0: remark: loaded module from
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.2.sdk/usr/lib/swift/os.swiftmodule/x86_64-apple-ios-simulator.swiftinterface
<unknown>:0: remark: loaded module from
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.2.sdk/System/Library/Frameworks/SwiftUI.framework/Modules/SwiftUI.swiftmodule/x86_64-apple-ios-simulator.swiftinterface
Adds a new frontend option
"-experimental-allow-module-with-compiler-errors". If any compilation
errors occur while generating the .swiftmodule, this mode will skip SIL
entirely and only serialize the (likey invalid) AST.
This existence of this option during generation is serialized into the
resulting .swiftmodule. Errors found in deserialization are only allowed
if it is set.
Primarily intended for IDE requests (eg. indexing and code completion)
to ensure robust cross-module results, despite possible errors.
Resolves rdar://69815975
Adds a new flag "-experimental-skip-all-function-bodies" that skips
typechecking and SIL generation for all function bodies (where
possible).
`didSet` functions are still typechecked and have SIL generated as their
body is checked for the `oldValue` parameter, but are not serialized.
Parsing will generally be skipped as well, but this isn't necessarily
the case since other flags (eg. "-verify-syntax-tree") may force delayed
parsing off.
If a conformance is defined in an extension, we now look for
references to the conformance in types and expressions and
respect's the extension's availability (or deprecation, etc).
The conformance checker itself still needs to check conformance
availability of associated conformances and the like; that will
be a separate change.
Note that conformances defined on types don't require any
special handling, since they are as available as the
intersection of the conforming type and the protocol.
By default, we diagnose conformance availability violations
where the OS version is not sufficiently new as warnings, to
avoid breaking source compatibility. Stricter behavior where
these violations are diagnosed as errors is enabled by passing
the -enable-conformance-availability-errors flag. There are
test cases that run both with and without this flag. In the
future, we hope to make the stricter behavior the default,
since after all, violations here can result in link errors and
runtime crashes.
Uses of completely unavailable conformances are still always
diagnosed as errors, even when this flag is not passed in.
Progress on <rdar://problem/35158274>.
Introduce availability macros defined by a frontend flag.
This feature makes it possible to set the availability
versions at the moment of compilation instead of having
it hard coded in the sources. It can be used by projects
with a need to change the availability depending on the
compilation context while using the same sources.
The availability macro is defined with the `-define-availability` flag:
swift MyLib.swift -define-availability "_iOS8Aligned:macOS 10.10, iOS 8.0" ..
The macro can be used in code instead of a platform name and version:
@available(_iOS8Aligned, *)
public func foo() {}
rdar://problem/65612624
We need ClangImporterOptions to be persistent for several scenarios: (1)
when creating a sub-ASTContext to build Swift modules from interfaces; and
(2) when creating a new Clang instance to invoke Clang dependencies scanner.
This change is NFC.
In theory, we shouldn't need to deserialize @_implementationOnly dependencies. However,
potential decl recovery issues may bring down lldb if we insist on not importing these
dependencies, resulting in bad user experience as a result. This patch adds an internal
option to allow importing them and it should only be set by lldb and other tools.
rdar://65570721
Add `async` to the type system. `async` can be written as part of a
function type or function declaration, following the parameter list, e.g.,
func doSomeWork() async { ... }
`async` functions are distinct from non-`async` functions and there
are no conversions amongst them. At present, `async` functions do not
*do* anything, but this commit fully supports them as a distinct kind
of function throughout:
* Parsing of `async`
* AST representation of `async` in declarations and types
* Syntactic type representation of `async`
* (De-/re-)mangling of function types involving 'async'
* Runtime type representation and reconstruction of function types
involving `async`.
* Dynamic casting restrictions for `async` function types
* (De-)serialization of `async` function types
* Disabling overriding, witness matching, and conversions with
differing `async`
We have landed support for serialization Clang function types, but there is
still work to be done here.
Moreover, we should use a consistent style with `[(FIXME|TODO|NOTE): label]`,
instead of using different styles throughout the code.
Introduce 'TypeCheckSingleASTNode' mode that only type checks single body
element and dependent necessities (i.e. referencing ValueDecls and their
dependencies).
Renamed swift::typeCheckAbstractFunctionBodyAtLoc() to
swift::typeCheckASTNodeAtLoc(DeclContext *, SourceLoc). That type checks
innermost 'ASTNode' at the location. Also, 'TypeCheckSingleASTNode' mode
skips type checking any "body" of the node (i.e. BraceStmt elements for
function body, if statement body, closure body, etc.)
Added on-demand type checking using it:
- VarDecl in TapExpr
- ParamDecl in ClosureExpr
- Return type of ClosureExpr
- Binding value in control statements
(e.g. ForEachStmt, SwitchStmt, DoCatchStmt, etc.)
rdar://problem/63932852
Introsuce a new "forward" algorithm for trailing closures where
the unlabeled trailing closure argument matches the next parameter in
the parameter list that can accept an unlabeled trailing closure.
The "can accept an unlabeled trailing closure" criteria looks at the
parameter itself. The parameter accepts an unlabeled trailing closure
if all of the following are true:
* The parameter is not 'inout'
* The adjusted type of the parameter (defined below) is a function type
The adjusted type of the parameter is the parameter's type as
declared, after performing two adjustments:
* If the parameter is an @autoclosure, use the result type of the
parameter's declared (function) type, before performing the second
adjustment.
* Remove all outer "optional" types.
For example, the following function illustrates both adjustments to
determine that the parameter "body" accepts an unlabeled trailing
closure:
func doSomething(body: @autoclosure () -> (((Int) -> String)?))
This is a source-breaking change. However, there is a "fuzzy" matching
rule that that addresses the source break we've observed in practice,
where a defaulted closure parameter precedes a non-defaulted closure
parameter:
func doSomethingElse(
onError: ((Error) -> Void)? = nil,
onCompletion: (Int) -> Void
) { }
doSomethingElse { x in
print(x)
}
With the existing "backward" scan rule, the trailing closure matches
onCompletion, and onError is given the default of "nil". With the
forward scanning rule, the trailing closure matches onError, and there
is no "onCompletion" argument, so the call fails.
The fuzzy matching rule proceeds as follows:
* if the call has a single, unlabeled trailing closure argument, and
* the parameter that would match the unlabeled trailing closure
argument has a default, and
* there are parameters *after* that parameter that require an argument
(i.e., they are not variadic and do not have a default argument)
then the forward scan skips this parameter and considers the next
parameter that could accept the unlabeled trailing closure.
Note that APIs like doSomethingElse(onError:onCompletion:) above
should probably be reworked to put the defaulted parameters at the
end, which works better with the forward scan and with multiple
trailing closures:
func doSomethingElseBetter(
onCompletion: (Int) -> Void,
onError: ((Error) -> Void)? = nil
) { }
doSomethingElseBetter { x in
print(x)
}
doSomethingElseBetter { x in
print(x)
} onError: { error in
throw error
}
Introduce a new frontend flag -enable-volatile-modules to trigger
loading swiftmodule files as volatile and avoid using mmap. Revert the
default behavior to using mmap.
-enable-experimental-private-intransitive-dependencies -> -enable-direct-intramodule-dependencies
-disable-experimental-private-intransitive-dependencies -> -disable-direct-intramodule-dependencies
While we're here, rename DependencyCollector::Mode's constants and clean
up the documentation.
"Private Intransitive Dependencies" differ from the status quo by no
longer requiring the concept of a "cascading dependency edge". This is
because the request evaluator automatically tracks, records, and replays
the names looked up while a given file is being processed by the
frontend. To remove transitivity from the swiftdeps files, each
primary file processed by the Swift frontend is charged for *all* name
lookups that occur while it is being processed. Further, because of
the replay step, lookups hidden behind cached requests are now entirely
visible to the dependency tracking code.
The net result is that all formerly implicit transitivity in the
dependency graph has been made completely explicit and direct. This
establishes a tighter overall dependency structure for each individual
file, and results in a remarkable decrease in the amount of
files that are rebuilt for any particular change.
This feature can be disabled via
-disable-experimental-private-intransitive-dependencies, which will
cause a return to the cascading status quo.
Lift the `DisablePoundIfEvaluation` parsing option
into `LangOptions` to subsume the need for the
`EvaluateConditionals` parameter, and sink the
computation of `CanDelayBodies` down into
`createSourceFileForMainModule`.
Introduce an experimental mode (behind the flag
`experimental-one-way-closure-params`) that places one-way
constraints between closure parameter types and references to those
parameters within the body of the closure. The intent here is to
break up constraint systems further, potentially improving type
checking performance and making way for larger closure bodies to be
supported.
This is a source-breaking change when the body of a single-expression
closure is used to determine the parameter types. One obvious example
is when there is no contextual type, e.g.,
let _ = { $0 + 1 }
this type-checks today because `1` becomes `Int`, which matches the
`+` overload with the type `(Int, Int) -> Int`, determining the
parameter type `Int` for the closure. Such code would not type-check
with one-way constraints.
While refactoring in 48805b1, I accidentally added the computation of this bit before CompilerInstance::setupInputs is called. This means that the compiler currently does not have any knowledge of any primary input buffers, and thus the check for whole module mode is trivially true. As a consequence, this bit has been true ever since.
Since we seem to have got on just fine without computing this correctly, just inline that truthiness everywhere.
Whoops