Commit Graph

632 Commits

Author SHA1 Message Date
Erik Eckstein 7ea1b1b23e SIL: add a flag [projection] to index_addr
The `projection` flag indicates that `index_addr` projects an element address from an array base address, as opposed to being used for general pointer arithmetic.
When this flag is set, the result address can only reach the single element at the given index — it is not possible to chain multiple `index_addr` instructions to reach other array elements from the result.
Without this flag, the result may be used as the base of another `index_addr`, allowing arithmetic across element boundaries (e.g. an `index_addr` with index 1 followed by an `index_addr` with index 2 reaches the element at offset 3).

An `index_addr [projection]` is mandatory to go from an array base address to an element - even if it's the first element, i.e. the index is zero.
This means that the optimizer must not remove `index_addr [projection]` with a zero index.
2026-06-09 16:17:53 +02:00
Joe Groff 097b0d3400 SIL: Split unchecked_*_enum_data_addr according to ownership and effects.
We cannot use spare bits or other overlapping storage layout tricks with fundamentally
address-only enums, and we can take advantage of this to do borrowing switches or other
in-place projections without copying the value. However, for resilient enums, the
implementation may use spare bit packing, but the type must be handled address-only
outside of its defining module, and we didn't have a way to express that with
borrowing switch. Optimization passes have also been running into problems with the
complexity that we were using `unchecked_take_enum_data_addr` sometimes as a pure
operation. This patch splits the instruction into three:

- `unchecked_inplace_enum_data_addr` represents a nondestructive in-place enum
  projection. It is only allowed for enums whose projection operation is
  nondestructive.
- `unchecked_take_enum_data_addr` represents a destructive enum projection,
  invalidating the enum and leaving the payload to be further consumed.
  This matches the current instruction's semantics.
- `unchecked_borrow_enum_data_addr` represents a borrowing enum projection.
  The instruction takes a second operand for "scratch" space, which the
  enum representation may be copied into in order to avoid invalidating the
  enum value, so the result is dependent on the lifetime of both the
  original enum and the scratch buffer. This allows for borrowing switches
  over resilient enums.

`unchecked_borrow_enum_data_addr` is implemented by taking advantage of the
"address-only enums can't do spare bit optimization" property at runtime.
We inspect the operand type's bitwise-borrowability from its metadata. If
the type is bitwise-borrowable, then we are allowed to bitwise-copy the
enum to the scratch space and apply the projection to the scratch space,
preserving the original value. If the type is not bitwise-borrowable, then
we cannot use spare bit optimization in its layout, so we apply the
projection in-place.

Fixes rdar://174952822.
2026-04-27 15:40:37 -07:00
Aidan Hall eac68b5283 LifetimeDependence: Closure lifetimes tests 2026-04-24 16:14:25 +01:00
Doug Gregor 22ba5f693d Diagnose the use of actor without _Concurrency imported 2026-03-23 22:25:29 -07:00
Aidan Hall 5f0d531d6e [Serialization] Test static method lifetime serialization 2026-03-04 17:08:20 +00:00
Meghana Gupta 88ede1f057 [NFC] Add ~Copyable versions to the borrow/mutate protocol tests 2026-01-20 11:44:22 -08:00
Meghana Gupta 07e945fe9e [NFC] Add serialization tests for get/set requirements satisfied by borrow/mutate accessors 2026-01-20 11:44:21 -08:00
Meghana Gupta 907fa198d7 [NFC] Add serialization tests for borrow/mutate protocol requirements 2026-01-20 11:44:20 -08:00
Slava Pestov 27097430cc Serialization: Lazily deserialize OpaqueTypeDecl's underlying substitutions
We need to serialize the underlying type substitution map for an
inlinable function. However, there is no reason to deserialize it
eagerly, since doing so can lead to cycles. It is better for
correctness and performance to only deserialize it when needed.

Technically this fixes a regression from #84299, but the actual
problem was there all along, it was just exposed by my change
on a specific project.

Fixes rdar://163301203.
2025-11-20 18:13:50 -05:00
Adrian Prantl c91211a5d2 Serialize explicit module dependencies in swift module files
For clients, such as the debugger, who do not have access the full
output of the dependency scanner, it is a huger performance and
correctness improvement if each explicitly built Swift module not just
serialized all its Clang .pcm dependencies (via the serialized Clang
compiler invocation) but also its direct Swift module dependencies.

This patch changes the Swift module format to store the absolute path
or cas cache key for each dependency in the INPUT block, and makes
sure the deserialization makes these available to the ESML.

rdar://150969755
2025-10-21 09:08:58 -07:00
Meghana Gupta 479b5a02f5 Fix serialization of mutate accessors 2025-10-08 19:33:18 -07:00
Alejandro Alonso dd006e073a Serialize isAddressable on param decls 2025-10-01 11:07:48 -07:00
Arnold Schwaighofer 7853ba0a7f Merge pull request #84178 from aschwaighofer/inline_always
Add experimental feature `@inline(always)`
2025-10-01 07:23:24 -07:00
Arnold Schwaighofer 25a071efc8 Add experimental feature @inline(always)
The intent for `@inline(always)` is to act as an optimization control.
The user can rely on inlining to happen or the compiler will emit an error
message.

Because function values can be dynamic (closures, protocol/class lookup)
this guarantee can only be upheld for direct function references.

In cases where the optimizer can resolve dynamic function values the
attribute shall be respected.

rdar://148608854
2025-09-30 08:36:26 -07:00
Gabor Horvath f26749245b [SILGen] Fix the type of closure thunks that are passed const reference structs
This PR is another attempt at landing #76903. The changes compared to
the original PR:
* Instead of increasing the size of SILDeclRef, store the necessary type
  information in a side channel using withClosureTypeInfo.
* Rely on SGFContext to get the right ClangType
* Extend BridgingConversion with an AbstractionPattern to store the
  original clang type.
* The PR above introduced a crash during indexing system modules that
  references foreign types coming from modules imported as
  implementation only. These entities are implementation details so they
  do not need to be included during serialization. This PR adds a test
  and adds logic to exclude such clang types in the serialization
  process.

rdar://131321096&141786724
2025-09-09 12:07:52 +01:00
Meghana Gupta 7a6078cba7 [NFC] Add tests 2025-06-23 13:42:54 -07:00
Meghana Gupta 44e05fa858 [NFC] Update tests and diagnostics 2025-06-07 12:49:01 -07:00
Meghana Gupta dbe548d4e1 Fix use-after-free on substituting function type involving conditional ~Escapable with Escapable type 2025-05-21 15:40:49 -07:00
Michael Gottesman 20d7a6c4c4 [sil] Update tests for witness table ABI verification. 2025-05-15 14:04:34 -07:00
Erik Eckstein a38db6439a SIL: add the vector_base_addr instruction
It derives the address of the first element of a vector, i.e. a `Builtin.FixedArray`, from the address of the vector itself.
Addresses of other vector elements can then be derived with `index_addr`.
2025-05-12 19:24:31 +02:00
Doug Gregor f09cdc2893 Fix deserialization assertion involving isolated conformances 2025-04-13 15:42:00 -07:00
Pavel Yaskevich 07ff063ae3 [AST/ASTGen/Sema/Serialization] Remove @execution attribute
Complete the transition from `@execution` to `@concurrent` and `nonisolated(nonsending)`
2025-04-11 15:59:25 -07:00
Pavel Yaskevich 4b8c8e7d72 [AST/Sema] Replace @execution(concurrent) with @concurrent 2025-04-11 12:08:29 -07:00
Meghana Gupta ef1e94577f Revert "Merge pull request #80540 from swiftlang/revert-80452-lifetimeinout"
This reverts commit 6eaa07a880, reversing
changes made to e75ee3f4cf.
2025-04-04 09:50:13 -07:00
Artem Chikin 39e1791b67 Revert "Add support for inout lifetime dependence" 2025-04-04 09:00:09 -07:00
Meghana Gupta 364338283b [NFC] Update tests 2025-04-03 17:32:02 -07:00
Andrew Trick 64a48d08e1 Update tests for strict @lifetime type checking 2025-03-19 11:59:04 -07:00
Doug Gregor 0e873e723c [Isolated conformances] Change syntax to @<global actor type> P
Instead of using the `isolated P` syntax, switch to specifying the
global actor type directly, e.g.,

   class MyClass: @MainActor MyProto { ... }

No functionality change at this point
2025-03-12 23:18:10 -07:00
Michael Gottesman 1fc836c564 [concurrency] Persist caller isolation inheriting through serialization.
rdar://142790023
2025-02-12 12:36:13 -08:00
Erik Eckstein e0b4f71af6 SIL: remove the alloc_vector instruction
It's not needed anymore, because the "FixedArray" experimental feature is replaced by inline-arrays.
2025-02-12 10:51:14 +01:00
Usama Hameed 203f906364 Serialize/Deserialize source locations for instructions (#77281)
This commit adds support for serializing and deserializing source locations for instructions.
2024-12-12 16:15:44 +05:00
Allan Shortlidge b97e27279e Sema: Fix opaque type accessors with inactive availability conditions.
Opaque type metadata accessor functions could be miscompiled for functions that
contain `if #available` checks for inactive platforms. For example, this
function will always return `A` when compiled for macOS, but the opaque type
accessor would instead return the type metadata for `B`:

```
func f() -> some P {
  if #available(iOS 99, *) {
    return A() // Returns an A on macOS
  } else {
    return B()
  }
}
```

Resolves rdar://139487970.
2024-11-10 09:23:39 -08:00
Usama Hameed 305ac20716 Serialize and Deserialize Debug Scopes (#76934)
This patch adds support for serialization and deserialization of
debug scopes.

Debug scopes are serialized in post order and enablement is 
controlled through the experimental-serialize-debug-info flag which
is turned off by default. Functions only referred to by these debug
scopes are deserialized as zombie functions directly.
2024-11-05 11:01:35 -08:00
Akira Hatanaka f73c2e51bd Revert "[SILGen] Fix the type of closure thunks that are passed const reference structs (#76903)" (#77309)
This reverts commit 9c44b79189.

The commit caused swift's deserialization code to crash.

rdar://138726860
2024-10-31 15:16:00 -07:00
Meghana Gupta 4df55a12cd Merge pull request #76834 from meg-gupta/lifetimedepmultiple
Replace dependsOn with @lifetime
2024-10-09 10:17:43 -07:00
Akira Hatanaka 9c44b79189 [SILGen] Fix the type of closure thunks that are passed const reference structs (#76903)
The thunk's parameter needs the @in_guaranteed convention if it's a
const reference parameter. However, that convention wasn't being used
because clang importer was removing the const reference from the
type and SILGen was computing the type of the parameter based on the
type without const reference.

This commit fixes the bug by passing the clang function type to
SILDeclRef so that it can be used to compute the correct thunk type.

This fixes a crash when a closure is passed to a C function taking a
pointer to a function that has a const reference struct parameter.

This recommits e074426 with fixes to
serialization/deserialization of function types. The fixes prevent clang
types of functions from being dropped during serialization.

rdar://131321096
2024-10-08 23:44:49 -07:00
Meghana Gupta 008431c3b4 Update some dependsOn tests to @lifetime 2024-10-08 15:12:13 -07:00
Erik Eckstein 5502373018 SIL: rename AssociatedTypeProtocolWitness -> AssociatedConformanceWitness in SILWitnessTable
To be consistent with the naming convention in the AST
2024-10-02 07:10:30 +02:00
Becca Royal-Gordon 94ec99c7f0 Avoid invalidating @_objcImplementation
In #69257, we modified `ObjCReason` to carry a pointer to the @implementation attribute for the `MemberOfObjCImplementationExtension` kind. This made it mark the @implementation attribute as invalid, suppressing diagnostics from the ObjCImplementationChecker.

However, invalidating the attribute *also* causes it to be skipped by serialization. That isn’t a problem if the diagnostics are errors, since we’ll never emit the serialized module, but #74135 softened these diagnostics to warnings for early adopters.

The upshot was that if Swift emitted one of these warnings when it compiled a library, clients of that library would see the objcImpl extension as a normal extension instead. This would cause various kinds of mischief: ambiguous name lookups because implementations weren’t being excluded, overrides failing because an implementation was `public` instead of `open`, asserts and crashes in SILGen and IRGen because stored properties were found in seemingly normal extensions, etc.

Fix this by setting a separate bit on ObjCImplementationAttr, rather than the invalid bit, and modifying the implementation checker to manually suppress many diagnostics when that bit is set.

Fixes rdar://134730183.
2024-09-05 17:55:12 -07:00
Kavon Farvardin 5230b19ef6 Test: replace '@_moveOnly' with '~Copyable' 2024-07-23 11:05:33 -07:00
Allan Shortlidge 9e5a9b963f AST: Remove NoncopyableGenerics feature suppression.
It is no longer necessary to produce `.swiftinterface` files the support older
compilers that lack support for the NoncopyableGenerics feature. Cleaning this
up makes the stdlib `.swiftinterface` far more readable.
2024-07-08 17:44:24 -07:00
Michael Gottesman 112071e57d [sending] Remove transferring.
Out of an abundance of caution, we:

1. Left in parsing support for transferring but internally made it rely on the
internals of sending.

2. Added a warning to tell people that transferring was going to
be removed very soon.

Now that we have given people some time, remove support for parsing
transferring.

rdar://130253724
2024-06-21 16:03:21 -07:00
Kavon Farvardin ec4a125f3e NCGenerics: ext's might not infer invertible req's
If the extension adds conformance to an invertible protocol, it's
confusing for people to also infer conditional requirements on the
generic parameters for those invertible protocols. This came up in the
review of SE-427.
2024-06-12 14:44:22 -07:00
Meghana Gupta c14559173d Add dependsOn(immortal) 2024-06-11 11:18:10 -07:00
Alejandro Alonso 324cb2df1f Merge pull request #73955 from Azoy/show-me-those-moves
[IRGen] Add option for raw layout to move as its like type
2024-05-30 20:32:49 -07:00
Alejandro Alonso a9da08ccb6 Add option for raw layout to move as its like type 2024-05-28 14:34:22 -07:00
Andrew Trick b5b0c75ccd Remove diagnostic: lifetime_dependence_on_bitwise_copyable
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.
2024-05-22 17:10:56 -07:00
Michael Gottesman 7592842ee1 [sending] Rename some tests from transferring -> sending.
I am doing this after the main transformation to ease commit by commit
understanding of the change.

rdar://128216574
2024-05-16 21:43:50 -07:00
Michael Gottesman b780ff6696 [sending] Begin parsing 'sending' while still accepting 'transferring'.
A few things:

1. Internally except for in the parser and the clang importer, we only represent
'sending'. This means that it will be easy to remove 'transferring' once enough
time has passed.

2. I included a warning that suggested to the user to change 'transferring' ->
'sending'.

3. I duplicated the parsing diagnostics for 'sending' so both will still get
different sets of diagnostics for parsing issues... but anywhere below parsing,
I have just changed 'transferring' to 'sending' since transferring isn't
represented at those lower levels.

4. Since SendingArgsAndResults is always enabled when TransferringArgsAndResults
is enabled (NOTE not vis-a-versa), we know that we can always parse sending. So
we import "transferring" as "sending". This means that even if one marks a
function with "transferring", the compiler will guard it behind a
SendingArgsAndResults -D flag and in the imported header print out sending.

rdar://128216574
2024-05-16 21:43:50 -07:00
Slava Pestov 0838e4fcdb Add test case for rdar://123335873
I didn't realize it at the time, but this was actually fixed by
bc85d66b96.
2024-04-03 14:10:36 -04:00