Serialize the module's SILMoveOnlyDeinit table. So that client modules can de-virtualize deinits.
So far this only worked for public non-copyable types.
This is especially important for embedded swift.
rdar://166051414
During explicit module build, teach dependency scanner to emit the
module trace file instead of each following compile job command. This
reduces the duplicated info, and allows supporting fully cached build
that only loads module from CAS thus cannot produce the path to the
original module file on disk.
rdar://170007480
Non-Escapable 'inout' arguments have a default self-dependency, regardless of
any other annotations. For example:
@_lifetime(dest: copy source)
/* DEFAULT: @_lifetime(dest: copy dest, copy source) */
func foo<T: ~Escapable>(dest: inout T, source: T)
An immortal lifetime specifier now suppresses that default. For example:
@_lifetime(dest: immortal, copy source)
/* DEFAULT: @_lifetime(dest: copy source) */
func foo<T: ~Escapable>(dest: inout T, source: T)
This is necessary because there is otherwise no other way to suppress the
default lifetime.
Fixes rdar://170016708 ([nonescapable] Support @_lifetime(immortal) to suppress
the usual inout default self-dependency)
Modify relevant portions of the type-checker and parser to allow, when the 'LiteralExpressions' experimental feature is enabled, for arbitrary integer-typed expressions in enum raw value specifiers. These expressions will be type-checked and constant-folded into an integer literal expression, keeping the current interface of 'EnumElementDecl' consistent for clients.
Previously, 'EnumRawValuesRequest' had two different "modes" which were discerned based on typechecking stage (structural | interface), where the former had the request compute all raw values, both user-specified literal expressions and computing increment-derived values as well; the latter would also type-check the user-specified expressions and compute their types.
- With the need to have enum case raw values support arbitrary integer expressions, the request ('EnumRawValuesRequest') has been refactored and simplified to *always* both compute all case raw values and perform type-checking of user-specified raw value expressions. This is done in order to allow the AST-based constant-folding infrastructure ('ConstantFoldExpression' request) to run on the expressions. Constant folding is invoked during the evaluation of 'EnumRawValuesRequest' on all user-specified raw value expressions, in order to be able to compute subsequent increment values and ensure the expressions are foldable. If they are not, i.e. if constant folding fails, a relevant diagnostic will be emitted.
- 'EnumElementDecl' continues to store the raw value expression, which is no longer a 'LiteralExpr' but rather an 'Expr'; however, the getter ('getRawValueExpr') continues to return a 'LiteralExpr' by invoking the constant-folding request on the stored value, which is guaranteed to return a cached result from a prior invocation in 'EnumRawValuesRequest', assuming it succeeded.
- Furthermore, the 'structural' request kind was previously not cached, whereas now because the request must always do the complete type-checking work, it is always cached.
Resolves rdar://168005520
This is not a possible code path in the Swift compiler, but LLDB has error paths
where ClangImporter could be null, and it has (for testing mostly) a setting to
disable ClangImporter entirely. When importing a Module with a header dependency
this crashes LLDB.
rdar://170007373
Extend support for proper errors on broken modularization to type
members, previously only top-level declarations were reported as error.
This change raises errors with relevant context if a type member is
referenced from a swiftmodule file but at reading the member is not
found or changed shape.
It doesn't report moves between modules like we do for top-level
declarations. This is less likely to happen at the member level as the
check is already applied at the top-level for the same reference. We may
still see such issues when using `SWIFT_NAME` to assign a top-level
declaration to a type from a different module.
The isFromAnnotation flag is set if and only if the lifetime originates from a
@lifetime or @_lifetime annotation in the source program.
isFromAnnotation==false means that the lifetime dependence checker would infer
the same lifetime if the Swift type or decl was printed without an annotation
for that dependency. More specifically, it means that the depenence was inferred
by the lifetime dependence checker.
Some dependencies on imported C/C++ decls are "inferred", but they either
correspond to explicit lifetime information in the source (smart pointers,
lifetimebound attribute) or are likely to differ from what the dependence
checker would infer. As such, we set the flag to true for all of them.
A protocol that's been reparented declares it
by writing `@reparented` in its inheirtance clause
for each new parent. You can introduce a `@reparented`
parent to a pre-existing ABI-stable protocol's
inheritance hierarchy.
Only protocols declared to be `@reparentable` can be
used to reparent other protocols. Adding or removing
the `@reparentable` attribute is ABI-breaking, as it
effects the type metadata layout. Thus, reparentable
protocols must be born as such to use them with
protocols that are already ABI-stable.
This set of changes does not include the actual
implementation of ABI-stable reparenting.
Since after address lowering, `Borrow` can remain loadable with a known-
layout address-only referent, we need instructions that handle three
forms:
- borrow and referent are both loadable values
- borrow is a value, but referent is address-only
- borrow and referent are both address-only
This new OSSA invariant simplifies many optimizations because they don't have to take care of the corner case of incomplete lifetimes in dead-end blocks.
The implementation basically consists of these changes:
* add the lifetime completion utility
* add a flag in SILFunction which tells optimization that they need to run the lifetime completion utility
* let all optimizations complete lifetimes if necessary
* enable the ownership verifier to check complete lifetimes
These two new invariants eliminate corner cases which caused bugs if optimization didn't handle them.
Also, it will significantly simplify lifetime completion.
The implementation basically consists of these changes:
* add a flag in SILFunction which tells optimization if they need to take care of infinite loops
* add a utility to break infinite loops
* let all optimizations remove unreachable blocks and break infinite loops if necessary
* add verification to check the new SIL invariants
The new `breakIfniniteLoops` utility breaks infinite loops in the control flow by inserting an "artificial" loop exit to a new dead-end block with an `unreachable`.
It inserts a `cond_br` with a `builtin "infinite_loop_true_condition"`:
```
bb0:
br bb1
bb1:
br bb1 // back-end branch
```
->
```
bb0:
br bb1
bb1:
%1 = builtin "infinite_loop_true_condition"() // always true, but the compiler doesn't know
cond_br %1, bb2, bb3
bb2: // new back-end block
br bb1
bb3: // new dead-end block
unreachable
```
Introduce a new optional flag on the alloc_box SIL instruction to mark boxes as
inferred immutable, indicating that static analysis has proven they are never
written to despite having a mutable type.
The flag is preserved through serialization/deserialization and properly printed/parsed in textual SIL format.
I am doing this to prepare for treating these boxes as being Sendable when they
contain a sendable weak reference.
Introduce a new optional inferred-immutable flag on SILFunctionArgument to mark
closure-captured box parameters that are never written to despite being mutable.
This flag will enable in future commits:
- Marking captured mutable boxes as immutable when interprocedural analysis
proves they are never modified
- Treating these captures as Sendable when they contain Sendable types
- Improving region-based isolation analysis for concurrent code
This complements the inferred-immutable flag on alloc_box by allowing
immutability information to flow through closure boundaries.
When a function type refers to a Swift declaration we get a crash during
deserialization. This patch prevents serializing the problematic clang
function types to avoid this crash.
rdar://166359524
Looking up serialized extensions for a nested nominal type requires
computing its mangled name, which may kick semantic requests. Ensure
we don't do this for nominals in parsed SourceFiles such that we
don't end up kicking this during extension binding.
This updates a large number of internal symbols, function names,
and types to match the final approved terminology. Matching the
surface language terminology and the compiler internals should
make the code easier for people to understand into the future.
We got LLDB crash logs where `importer` is dereferenced. In the same crash log
the parent frame correctly checks for nullptr, so this would fix the immediate
crash. In LLDB it is not guaranteed that a ClangImporter is installed at all
times.
Ideally this function should be converted to return `llvm::Expected<ModuleDecl &>`.
rdar://166224928
Store the original VarDecl in the same map we use for tracking the
original wrapper var for property wrappers. This will allow us to
use the same logic to determine the original var for both.
When a custom domain is described on the command line, there is no
backing declaration for it. Serialize such custom domains by
identifier and look them up globally at the point of deserialization.
When that fails, warn and drop the annotation.
This is all a stopgap until we have a way to spell custom availability
domains in the Swift language itself.