Commit Graph

46 Commits

Author SHA1 Message Date
Doug Gregor 14bc0baecf Introduce the notion of an "effective" code generation model
The code generation model for a particular declaration or conformance
can be defined explicitly with `@export(interface)`,
`@export(implementation)`, or `@inlinable` (for declarations),
indicating where the definition will occur.

Embedded Swift also has some limitations on what can be emitted into
IR. For example, a generic function cannot be `@export(interface)`
because Embedded Swift does not support unspecialized generics.

Compute the effective code generation model based on what was
explicitly specified, the limitations of the model, and the default
code generation model for the given module, which defaults to
"inlinable" but can be made "implementation" by the DeferredCodeGen
feature. Use the effective code generation model for IR- and SIL-level
determinations of linkage and where to emit symbols.
[WIP] Start computing and using the "effective" code generation model

FIXUP linkage of the alias symbol
2026-05-20 08:35:11 -07:00
Doug Gregor 86febb3a3e Merge pull request #88979 from DougGregor/export-interface-types-and-conformances
[Embedded] Extend @export(interface) to non-generic types and protocol conformances
2026-05-11 11:25:10 -07:00
Doug Gregor f6f379daab [Embedded] Extend @export(interface) to protocol conformances
Protocol conformances normally have shared linkage in Embedded Swift.
However, allow the use of @export(interface) on conformances (by way
of their enclosing nominal type or extension), which will emit the
witness tables for those conformances as strong symbols in the owning
module, and references to these symbols from other modules.
2026-05-08 16:25:46 -07:00
Doug Gregor 4934c6af3d [Embedded] Witness tables should always have shared linkage in embedded mode
At the SIL level, ensure that witness tables always have shared linked
when building Embedded Swift. This is the correct starting point, to be
revised for @export(interface).
2026-05-08 15:14:23 -07:00
Kavon Farvardin 21b2ebff12 Sema: infer inverses in opaque return types
Opaque return types are special type declarations that have it
own nested generic signature. Thus, given this:
```
  protocol P<A> { associatedtype A: ~Copyable }
  func f<T: ~Copyable>() -> some P<T> {}
```
The generic signature for f is <T where T Escapable>, and
for the opaque return type, its nested signature ends up as
```
  <X where X: P, X.A == T>
```
With SE-503, we will now also expand a default for the suppressed
primary associated type, so the signature after expansion becomes
```
  <X where X: P, X.A == T, X.A: Copyable>
```
It would be smarter to effectively have this rule
```
  X.A == T, T: ~Copyable
  ----------------------
     X.A: ~Copyable
```
where we infer the inverse on X.A to cancel-out the
expanded default X.A: Copyable. We already do this for
two in-scope type parameters, and it would be better if
we did it if one side was out-of-scope, but that would
be source-breaking to do in general.

In the case of opaque return types, the fact that
it has a nested generic signature seems more an
artifact of the implementation. There also is little
risk of source break, as the only kinds of same-type
requirements that can appear are from parameterized
protocol type.

The experimental suppressed associated types prior to
SE-503 wouldn't be broken by this change, as they do
not infer defaults that need suppression, and we only
filter-out requirements from defaults expansion, rather
than explicitly-written ones.

rdar://175500824
2026-05-04 14:49:34 -07:00
Kavon Farvardin 6651cb6389 NFC: refactor the applyInverses bool
There's a need for more control over how default requirements
for conformance to Copyable/Escapable are expanded, and
subsequently how inverses are applied or inferred to cancel-out
those defaults.

The pattern of `/*applyInverses*/BOOL` is insufficient, so this
is a refactoring to grow that into a proper type that carries
an option that can be used in some future scenario about inferring
inverses for opaque return types.
2026-04-29 16:56:00 -07:00
Arnold Schwaighofer 72bd56de5b [cmo] [aggresive] Don't attach the usableFromInline attribute
in the CMO pass in aggressive mode

Changing the AST mid-pipeline is probably not a good idea.

rdar://173172456
2026-03-23 14:11:02 -07:00
Arnold Schwaighofer fa55d2367c Use SILDeclRef::declHasNonUniqueDefinition to determine when to change the decl's linkage 2026-02-25 09:15:54 -08:00
Arnold Schwaighofer 34325f8abb [embedded] Don't change AST decls with markUsableFromInline in embedded
The current approach of changing the AST mid compiler pipeline (in the
CMO pass) is not tenable/maintainable imo. We can't get different answers
throughout the compilation process about AST properties -- there is no
way about reasoning what things mean.

Instead, we treat internal and lower linkages as public for the purposes of
symbol visibility for linkage reasons in SIL/IRGen.

rdar://171083081
2026-02-25 08:11:53 -08:00
Slava Pestov 819738c83e AST: Rename mapTypeIntoContext() => mapTypeIntoEnvironment(), mapTypeOutOfContext() => mapTypeOutOfEnvironment() 2025-11-12 14:48:19 -05:00
Kavon Farvardin 3bb8fa848a nfc: !isNoncopyable() -> isCopyable() 2025-08-28 12:13:21 -07:00
John McCall 46be95847b Extract TypeLowering's recursive type properties into a header, add
functions to compute them directly without a TypeLowering object, and
change a lot of getTypeLowering call sites to just use that.

There is one subtle change here that I think is okay: SILBuilder used to
use different TypeExpansionContexts when inserting into a global:
- getTypeLowering() always used a minimal context when inserting into
  a global
- getTypeExpansionContext() always returned a maximal context for the
  module scope
The latter seems more correct, as AFAIK global initializers are never
inlinable. If they are, we probably need to configure the builder with
an actual context properly rather than making global assumptions.

This is incremental progress towards computing this for most types
without a TypeLowering, and hopefully eventually removing TL entirely.
2025-08-01 15:00:57 -04:00
Joe Groff 22eb7e62d9 SILGen: Emit property descriptors for conditionally Copyable and Escapable types.
Key paths can't reference non-escapable or non-copyable storage declarations,
so we don't need to refer to them resiliently, and can elide their property
descriptors.

However, declarations may still be conditionally Copyable and Escapable, and
if so, then they still need a property descriptor for resilient key path
references. When a property or subscript can be used in a context where it
is fully Copyable and Escapable, emit the property descriptor in a generic
environment constrained by the necessary conditional constraints.

Fixes rdar://151628396.
2025-05-27 09:35:40 -07:00
Amritpan Kaur 4de2486ad9 [SILGen] Emit property descriptors for protocol extensions
but not for protocol requirements.
2025-02-09 10:19:44 -08:00
Amritpan Kaur 6066418340 Merge pull request #73242 from amritpan/metatype-kp-implementation 2024-09-28 02:46:15 -07:00
Amritpan Kaur ef96728148 [SIL] Prevent emitting descriptors for static properties in protocol extensions. 2024-09-25 12:54:52 -07:00
Amritpan Kaur c7109506c1 [SIL] Remove check preventing static keypaths in SIL. 2024-09-25 12:54:52 -07:00
Erik Eckstein 2950e4521e SIL: representation for specialized witness tables
The main change here is to associate a witness table with a `ProtocolConformance` instead of a `RootProtocolConformance`.
A `ProtocolConformance` is the base class and can be a `RootProtocolConformance` or a `SpecializedProtocolConformance`.
2024-09-25 19:32:08 +02:00
Tim Kientzle 1d961ba22d Add #include "swift/Basic/Assertions.h" to a lot of source files
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
2024-06-05 19:37:30 -07:00
Pavel Yaskevich d3540b4838 Merge pull request #71376 from simanerush/pack-argument-fix
SIL: Adjust `isTypeMetadataForLayoutAccessible()` to visit more lowered positions
2024-03-27 13:44:22 -07:00
Slava Pestov 368721ef5c SIL: Adjust isTypeMetadataForLayoutAccessible() to visit more lowered positions
Fixes part of https://github.com/apple/swift/issues/67645, rdar://119267393
2024-02-07 17:13:33 -08:00
Ellie Shin 72a7760027 Support package SIL linkage.
Decls with a package access level are currently set to public SIL
linkages. This limits the ability to have more fine-grained control
and optimize around resilience and serialization.
This PR introduces a separate SIL linkage and FormalLinkage for
package decls, pipes them down to IRGen, and updates linkage checks
at call sites to include package linkage.

Resolves rdar://121409846
2024-02-06 01:23:14 -08:00
Doug Gregor 97ea19d191 Introduce a builtin and API for getting the local actor from a distributed one
When an actual instance of a distributed actor is on the local node, it is
has the capabilities of `Actor`. This isn't expressible directly in the type
system, because not all `DistributedActor`s are `Actor`s, nor is the
opposite true.

Instead, provide an API `DistributedActor.asLocalActor` that can only
be executed when the distributed actor is known to be local (because
this API is not itself `distributed`), and produces an existential
`any Actor` referencing that actor. The resulting existential value
carries with it a special witness table that adapts any type
conforming to the DistributedActor protocol into a type that conforms
to the Actor protocol. It is "as if" one had written something like this:

    extension DistributedActor: Actor { }

which, of course, is not permitted in the language. Nonetheless, we
lovingly craft such a witness table:

* The "type" being extended is represented as an extension context,
rather than as a type context. This hasn't been done before, all Swift
runtimes support it uniformly.

* A special witness is provided in the Distributed library to implement
the `Actor.unownedExecutor` operation. This witness back-deploys to the
Swift version were distributed actors were introduced (5.7). On Swift
5.9 runtimes (and newer), it will use
`DistributedActor.unownedExecutor` to support custom executors.

* The conformance of `Self: DistributedActor` is represented as a
conditional requirement, which gets satisfied by the witness table
that makes the type a `DistributedActor`. This makes the special
witness work.

* The witness table is *not* visible via any of the normal runtime
lookup tables, because doing so would allow any
`DistributedActor`-conforming type to conform to `Actor`, which would
break the safety model.

* The witness table is emitted on demand in any client that needs it.
In back-deployment configurations, there may be several witness tables
for the same concrete distributed actor conforming to `Actor`.
However, this duplication can only be observed under fairly extreme
circumstances (where one is opening the returned existential and
instantiating generic types with the distributed actor type as an
`Actor`, then performing dynamic type equivalence checks), and will
not be present with a new Swift runtime.

All of these tricks together mean that we need no runtime changes, and
`asLocalActor` back-deploys as far as distributed actors, allowing it's
use in `#isolation` and the async for...in loop.
2024-01-22 17:27:31 -08:00
Slava Pestov 79d4260ae2 SIL: Remove the incorrect old getTypeLinkage() 2024-01-03 14:45:29 -05:00
Slava Pestov 05dcc4b27c SIL: Don't need a GenericEnvironment in isUnsupportedKeyPathValueType() 2024-01-02 15:41:13 -05:00
Kavon Farvardin d80719827c [NCGenerics] fix missing contextual type 2023-12-18 18:55:56 -08:00
Kavon Farvardin f1142d5da4 [nfc] rename or eliminate isPureMoveOnly APIs
I think from SIL's perspective, it should only worry about whether the
type is move-only. That includes MoveOnlyWrapped SILTypes and regular
types that cannot be copied.

Most of the code querying `SILType::isPureMoveOnly` is in SILGen, where
it's very likely that the original AST type is sitting around already.
In such cases, I think it's fine to ask the AST type if it is
noncopyable. The clarity of only asking the ASTType if it's noncopyable
is beneficial, I think.
2023-09-20 15:23:17 -07:00
Slava Pestov 1b8e9a2964 SIL: Fixes for tuple conformances 2023-08-09 17:42:25 -04:00
Slava Pestov fff8a4ae96 SIL: Don't attempt to emit keypath descriptors with unsupported reabstraction thunks 2023-07-19 12:40:28 -04:00
Joe Groff 024efd2a4e SILGen: Don't emit key path property descriptors for properties in or of noncopyable types.
Key paths don't support them yet, and the current component representation is inadequate to
handle them without requiring internal copying in all cases, so let's avoid generating
invalid property descriptors for them today. rdar://111171284
2023-06-22 11:10:32 -07:00
John McCall d25a8aec8b Add explicit lowering for value packs and pack expansions.
- SILPackType carries whether the elements are stored directly
  in the pack, which we're not currently using in the lowering,
  but it's probably something we'll want in the final ABI.
  Having this also makes it clear that we're doing the right
  thing with substitution and element lowering.  I also toyed
  with making this a scalar type, which made it necessary in
  various places, although eventually I pulled back to the
  design where we always use packs as addresses.

- Pack boundaries are a core ABI concept, so the lowering has
  to wrap parameter pack expansions up as packs.  There are huge
  unimplemented holes here where the abstraction pattern will
  need to tell us how many elements to gather into the pack,
  but a naive approach is good enough to get things off the
  ground.

- Pack conventions are related to the existing parameter and
  result conventions, but they're different on enough grounds
  that they deserve to be separated.
2023-01-29 03:29:06 -05:00
Ellie Shin 1c66d02f92 Add package access level to enum AccessLevel
Resolves rdar://104198440
2023-01-19 15:54:18 -08:00
Becca Royal-Gordon ba1ec90419 Generate IR for @_objcImpls
This commit begins to generate correct metadata for @_objcImplementation extensions:

• Swift-specific metadata and symbols are not generated.
• For main-class @_objcImpls, we visit the class to emit metadata, but visit the extension’s members.
• Includes both IR tests and executable tests, including coverage of same-module @objc subclasses, different-module @objc subclasses, and clang subclasses.

The test cases do not yet cover stored properties.
2022-10-18 17:21:56 -07:00
Holly Borla 38a2c8218b [Requirement] Rename RequirementKind::SameCount to SameShape. 2022-10-06 20:48:40 -07:00
Slava Pestov 5c32f2136e AST: Introduce RequirementKind::SameCount 2022-08-23 11:12:00 -04:00
Slava Pestov 9d96ed940f AST: Rename 'canonical wrt. generic signature' to 'reduced'
We had two notions of canonical types, one is the structural property
where it doesn't contain sugared types, the other one where it does
not contain reducible type parameters with respect to a generic
signature.

Rename the second one to a 'reduced type'.
2022-08-09 12:46:31 -04:00
John McCall 0cde2dde05 Provide a version of getTypeLinkage that works.
Smaller values of FormalLinkage are actually wider scopes,
so std::min'ing with PublicUnique actually just gives you
a result that's always PublicUnique.  And we need to start
with PublicNonUnique because even things derived solely
from uniquely-emitted types are not themselves generally
unique.

I don't want to immediately open the can of worms that fixing
this for everyone would entail, so I'm just adding the new
version in parallel and moving new clients to it gradually.
2022-04-11 22:15:21 -04:00
John McCall fb6883d0bb [NFC] Add a utility to compute formal linkage for a generic signature 2022-04-11 22:15:16 -04:00
Erik Eckstein 6a020f8f15 Stabilize and simplify SIL linkage and serialization
The main point of this change is to make sure that a shared function always has a body: both, in the optimizer pipeline and in the swiftmodule file.
This is important because the compiler always needs to emit code for a shared function. Shared functions cannot be referenced from outside the module.
In several corner cases we missed to maintain this invariant which resulted in unresolved-symbol linker errors.

As side-effect of this change we can drop the shared_external SIL linkage and the IsSerializable flag, which simplifies the serialization and linkage concept.
2022-03-09 15:28:05 +01:00
Erik Eckstein 30a74f6284 SIL: remove the private_external SILLinkage
This was a relict from the -sil-serialize-all days. This linkage doesn't make any sense because a private function cannot be referenced from another module (or file, in case of non-wmo compilation).
2021-10-10 19:52:40 +02:00
Arnold Schwaighofer d5de496c05 IRGen: Private opaque result types from another TU are not ABI accessible
rdar://76416817
2021-08-13 10:32:45 -07:00
Joe Groff 92f56e7ec8 Allow conversions from actor-bound sync function type to unbound async function type.
For `async` function types, an actor constraint can be enforced by the callee by hopping executors,
unlike with `sync` functions, so doesn't need to influence the outward type of the function.

rdar://76248452
2021-05-21 14:17:50 -07:00
Alejandro Alonso 424802fb34 Revert SE-0283 (#34492)
Reverted despite build failures.
2020-10-29 17:32:06 -07:00
Azoy e60ef84bd2 Implement Tuple Equatable Conformance 2020-10-22 18:24:28 -04:00
Hamish Knight 2d9b63ed11 A SILModule Always Has An Associated Context
Now that the integrated REPL has been removed,
there is always an associated decl context, and
we can assert as such.
2020-05-10 19:56:12 -07:00
Michael Gottesman e1a19e4173 [sil] Split library into subfolders, while still building as a single library still.
Specifically, I split it into 3 initial categories: IR, Utils, Verifier. I just
did this quickly, we can always split it more later if we want.

I followed the model that we use in SILOptimizer: ./lib/SIL/CMakeLists.txt vends
 a macro (sil_register_sources) to the sub-folders that register the sources of
 the subdirectory with a global state variable that ./lib/SIL/CMakeLists.txt
 defines. Then after including those subdirs, the parent cmake declares the SIL
 library. So the output is the same, but we have the flexibility of having
 subdirectories to categorize source files.
2020-03-30 11:01:00 -07:00