Commit Graph

3653 Commits

Author SHA1 Message Date
Paul Passeron 425cd0ebd7 [experimental] Infrastructure for derived conformances via macros (#89419)
**Overview**:
This PR introduces the basic infrastructure needed to eventually migrate
derived macros generation from hand-crafted AST nodes to macros. No
conformance have been migrated yet.

**Motivation**:
Derived conformances (e.g. `Equatable`, `Hashable`, `Codable`, ...) are
currently implemented as a special case in the compiler, producing
synthetic AST nodes directly. Migrating this to macros will hopefully
unify the code path with the existing macro expansion infrastructure,
make conformance synthesis easier to extend and test as well as reducing
the amount of special cases in the compiler.

**Changes**:
- New experimental feature flag `DeriveConformancesViaMacros`:
Introduces the flag that will eventually gate the new derived
conformance code paths. It does not control any behaviour for the moment
as none have been migrated yet but this enables future changes to be
built incrementally.
- New GeneratedSourceInfo and SourceFile kinds `SyntheticMacro`:
Introduces new GSI and SourceFile kinds named `SyntheticMacro` to
represent macros synthesized by the compiler. Since macros need a real
buffer to expand, this is the kind of source file and GSI associated
with those buffers.
- Conformance derivation via macros API:
Introduces the `deriveRequirementViaMacro` function that produces the
required witness via macro expansion.

See https://github.com/swiftlang/llvm-project/pull/13124 for
llvm-related changes.

**Next steps**:
- Macros do not contain any semantic information, especially regarding
types. Therefore it is necessary to provide them with type information
as an argument so they can eventually derive the conformances. A
separate PR is being created to generate this type information as
strings containing swift-parsable code for easy parsing on the macro
end.
- Implement derived conformance synthesis for individual protocols using
the new infrastructure, like `Equatable` or `Hashable` for starters.
- Wire the experimental flag to gate the new path once an implementation
exists

---------

Co-authored-by: Hamish Knight <hamish_knight@apple.com>
2026-06-08 14:23:58 +01:00
Aviva da97db70c8 Merge pull request #89668 from a-viv-a/consider-concurrent-explicit-isolation
[Concurrency] add '@concurrent' to hasExplicitIsolationAttribute (noop?)
2026-06-05 12:57:15 -07:00
alhafram 2055bc3e76 Fix circular reference when property wrapper references CodingKeys (#88477)
### **Explanation:**
When a property wrapper's initializer references the enclosing type's
CodingKeys enum (e.g. @Wrapper(key: CodingKeys.bar)), the compiler
enters a dependency cycle: StoredPropertiesRequest →
PropertyWrapperBackingPropertyTypeRequest → ResolveImplicitMemberRequest
(resolve CodingKeys) → ResolveValueWitnessesRequest (Codable
conformance) → StoredPropertiesRequest (cycle).

### **Scope:**
Codable synthesis, property wrappers

### **Issues:**
Fixes #88459

### **Original PRs:**
N/A

### **Risk:**
Low. The change only affects the ResolveCodingKeys path in
ResolveImplicitMemberRequest and is guarded by two conditions: (1)
StoredPropertiesRequest must be active for the same type, and (2) the
user must have explicitly defined a CodingKeys enum. All 74 existing
Codable synthesis tests pass.


### **Testing:**
Added
test/decl/protocol/special/coding/struct_codable_property_wrapper_codingkeys.swift
with 5 test cases: simple wrappers with CodingKeys, custom key mappings,
mixed wrapped/unwrapped properties, Decodable-only, Encodable-only. All
74 Codable tests pass. Runtime encode/decode verified.

### **Reviewers:**
2026-06-04 19:06:48 -07:00
Michael Gottesman 62f2643e92 Merge pull request #89586 from gottesmm/pr-af9e176772b91ce9109960777f60201b063ee068
[concurrency] Inherit actor isolation for lazy property initializer closures
2026-06-03 15:36:05 -07:00
Aviva Ruben 37606f0106 [Concurrency] add '@concurrent' to hasExplicitIsolationAttribute (noop?)
This commit adds a check for the '@concurrent' attribute as part
of hasExplicitIsolationAttribute. Concurrent is an isolation
attribute, so we should consider it for this check. This change
should not change behavior in any existing consumer, since a
concurrent function is already an async function; it's only used in
contextRequiresStrictConcurrencyChecking, which will also return true
for async function. However, I was surprised this check didn't include
@concurrent when I tried to use it for file-level default isolation, and
I think leaving it like this could lead to a bug in the future?

The test added by this commit would pass without this change, since the
function is also async.
2026-06-03 13:16:19 -07:00
Michael Gottesman c67df0d929 [concurrency] Inherit actor isolation for lazy property initializer closures
The initializer of a 'lazy' stored property is type-checked as 'nonisolated'
even when the property (and its enclosing context) is actor-isolated, because
getActorIsolationOfContext reports the lazy var's PatternBindingInitializer as
having unspecified isolation. Closures in the initializer therefore inherit
nonisolated isolation, and region-based isolation flags calls inside them as
crossing into the actor, emitting spurious cross-isolation data-race
diagnostics, e.g.:

    @MainActor class Picker {
      var variants: [AnyObject] = []
      lazy var allViews = variants.map { item in process(item) } // spurious warning
      func process(_ item: AnyObject) -> Int { 0 }
    }

Unlike an ordinary stored-property default value -- whose required isolation is
computed and validated separately, and is intentionally reported as unspecified
here (e.g. under IsolatedDefaultValues) -- a 'lazy' property's initializer is
emitted into the property's synthesized getter, which is isolated to the
property. The initializer, and any closures within it, genuinely run with the
lazy variable's actor isolation.

Fix getActorIsolationOfContext to report a lazy var's initializer context as
isolated to the lazy variable (when the variable is actor-isolated). The
existing closure-isolation machinery (determineClosureIsolation /
computeClosureIsolationFromParent) then makes the initializer's closures inherit
that isolation, including nested and immediately-invoked ('{ ... }()') closures.
Closures that are isolation inference boundaries -- '@Sendable' closures or
closures passed to a 'sending' parameter -- still do not inherit, because that
check runs before the parent isolation is applied; so a lazy initializer now
behaves exactly like an equivalent computed-property getter.

A regression test verifies the isolation of the initializer's closures across
classes/structs, final/non-final, MainActor and a custom global actor,
property-only isolation, explicit type annotations, IIFE/nested closures, and
the '@Sendable' / 'sending' boundary cases.

rdar://178533556
2026-06-02 10:21:58 -07:00
Egor Zhdan b9e1b2e742 [cxx-interop] Fix assertion failure for macros in bridging header
When `MemberImportVisibility` upcoming feature is enabled, the typechecker tries to determine the owning module of C/C++ macros used in Swift.

That logic didn't handle bridging headers correctly, and triggered an assertion failure:
```
Assertion failed: (Node.getAsMacroInfo()), function getClangOwningModule, file ClangImporter.cpp, line 3612.
```

rdar://178264720
2026-06-02 17:01:13 +01:00
Allan Shortlidge e1a0343c65 AST: Account for the types enclosing an extended nominal in access scopes.
`getAccessScopeForFormalAccess` walks a declaration's own DeclContext
chain to find enclosing types whose formal access should restrict its
own. For a member declared in an extension, that chain steps directly
from the extension to file scope, so any types enclosing the extended
nominal were silently skipped. As a result, members of an extension of
a nested type were treated as having the formal access of the
immediately extended type, ignoring the types that contain it.

For example, the public method below was treated as truly public, even
though `Outer` is internal and so the effective access of any member
of an extension of `Inner` is internal:

```
struct Outer {
  public struct Inner { }
}

internal struct InternalType { }

extension Outer.Inner {
  public func f(x: InternalType) { }
}
```

This incorrect access scope could cause a range of misbehavior, from
spurious access-control diagnostics to incorrect SIL linkage decisions.

Refactor the walk to use a helper that handles nominals and extensions
uniformly, and have the extension branch chain through into the
extended nominal's enclosing types. Don't redirect `resultDC` itself,
since `fileprivate` and `private` scopes must continue to resolve to
the file containing the declaration, which may differ from the file
containing the extended type.

Resolves rdar://150448686.
2026-05-30 20:47:34 -07:00
Slava Pestov 7962240f31 Merge pull request #89484 from slavapestov/existential-layout-is-broken
Remove a few usages of ExistentialLayout::getSuperclass()
2026-05-28 20:35:28 -04:00
Doug Gregor 9746331662 Merge pull request #89445 from DougGregor/export-interface-fixes
Fix `@export(interface)` for synthesized members and generic functions
2026-05-28 00:05:38 -07:00
Slava Pestov 5e1cb391f4 AST: Remove from ExistentialLayout::getSuperclass() call from getDynamicMemberParamTypeAsKeyPathType() 2026-05-27 23:06:47 -04:00
Doug Gregor 4b69cd4e5b Walk back the inheriting code generation model from enclosing extension/type
We might not actually want this inference rule. For now, narrow the
rule to only cover public synthesized members within that extension/type.
2026-05-26 14:10:37 -07:00
Doug Gregor 93c147f78c [Embedded] Prohibit @export(interface) on generic functions
Somehow we had missed this restriction before, but it's crucial to
prevent IR generation from trying to emit unspecialized generics.

Fixes rdar://177755296.
2026-05-26 13:42:18 -07:00
Doug Gregor e79cdc4a32 Members of @export(interface) types and extensions inherit it when possible
Ensure that this also covers synthesized members for, e.g.,
conformances. Part of rdar://177755296
2026-05-26 13:42:17 -07:00
John Hui fd4e511519 [cxx-interop] Mark synthesized user-facing Clang members as synthesized
Without doing so, they will not appear in the output of
swift-synthesize-interface.
2026-05-22 15:31:20 -07:00
Doug Gregor 92dcbd17c6 [SIL] Explicitly keep the code generation model in SILGlobalVariable
Just like we do with SILFunction, allow a code generation model to be
specified on a SILGlobalVariable and maintain that through the printed
and serialized forms.
2026-05-20 08:35:22 -07:00
Doug Gregor ae942071ae @export(interface|implementation) on a property affects its accessors 2026-05-20 08:35:22 -07:00
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
Slava Pestov 6b84857d6f AST: Remove useDC parameter from getDynamicMemberLookupKind() 2026-05-08 15:46:20 -04:00
Slava Pestov 29768061ef Sema: Remove useDC parameter from DynamicMemberLookupSubscriptRequest 2026-05-08 15:46:18 -04:00
Slava Pestov 8f5ab7f8e8 Sema: Change assert() to ASSERT() 2026-05-08 15:46:18 -04:00
Slava Pestov 4926234b54 Sema: Remove SubscriptDecl::isValidDynamicMemberLookupSubscript() 2026-05-08 15:46:18 -04:00
Slava Pestov b062b8a285 Convert SubscriptDecl @dynamicMemberLookup checking to request
Adds a new DynamicMemberLookupSubscriptRequest type for evaluating and
caching the validity of a `SubscriptDecl`'s usage to fulfill a
`@dynamicMemberLookup` requirement for a specific usage.
2026-05-08 15:46:17 -04:00
Itai Ferber c191d4994c Cache SubscriptDecl @dynamicMemberLookup eligibility
`SubscriptDecl`s may get checked multiple times for eligibility in
fulfilling `@dynamicMemberLookup` requirements; since the checks are
non-trivial and the result doesn't change, this eligibility can be
cached in the decl's `Bits`.
2026-05-08 15:46:17 -04:00
Doug Gregor f8df6ea1ff Merge pull request #87869 from calda/cal--body-macro-computed-properties
Add support for body macros on variables and accessors
2026-05-03 21:35:34 -07:00
Cal Stephens a2c82139d3 Update check 2026-04-29 16:32:39 -07:00
Hamish Knight 3d09efb607 [AST] NFC: Factor out isMacroExpansionInContext 2026-04-29 23:23:08 +01:00
Pavel Yaskevich eb47ad8d7d [Concurrency] Always set @concurrent isolation on async declarations/closures
Use `@concurrent` regardless of feature flags and explicit `@concurrent` attribute
to make the semantics and diagnostics consistent in all modes.
2026-04-28 09:21:46 -07:00
Konrad Malawski 384a02d980 [Tests] NFC: Update nonisolated -> @concurrent on async declarations 2026-04-28 09:21:23 -07:00
Konrad Malawski 4e4769de49 Rename stale CallerIsolated to NonisolatedNonsending 2026-04-28 09:21:23 -07:00
Konrad Malawski 003028c17c more rename followups for isNonisolated and the enum change 2026-04-28 09:21:23 -07:00
Konrad Malawski 77ac31d946 Rename to ActorIsolation::Kind::Nonisolated*Concurrent* 2026-04-28 09:21:23 -07:00
Konrad Malawski 3beefe5bd8 Rename CallerIsolationInheriting -> NonisolatedNonsending 2026-04-28 09:21:23 -07:00
Cal Stephens 2812f937cb Clean up 2026-04-21 10:43:21 -07:00
Cal Stephens 35b5d0969c Handle sending AccessorDeclSyntax via plugin message 2026-04-21 10:43:20 -07:00
Cal Stephens 45fef8a8af Support body macros on computed properties 2026-04-21 10:43:20 -07:00
Konrad Malawski bfe8dbca59 [Concurrency] Warn about un-used throwing unstructured tasks
Pending swift evolution discussion: https://github.com/swiftlang/swift-evolution/pull/3133

replaces #87171

update new error message according to proposal

also handle untyped throws in _nonDiscardableWhenThrowing attr

Rename the internal attr _nonDiscardableWhenThrowingOperation
2026-04-21 23:53:56 +09:00
Tim Kientzle c46cabde95 Merge pull request #88504 from tbkka/tbkka-yielding-in-swiftinterface
Write `yielding` accessor names to swiftinterface files
2026-04-19 13:35:54 -07:00
Hamish Knight 9cc084e290 Merge pull request #88515 from hamishknight/outer-order
[AST] Use `getOutermostParentSourceFile` in `getAccessScopeForFormalAccess`
2026-04-17 21:22:39 +01:00
Hamish Knight a4f2b0b904 [AST] Use getOutermostParentSourceFile in getAccessScopeForFormalAccess
A fileprivate access scope should always be rooted in the outermost
SourceFile since macros do not introduce their own file access scopes.

rdar://174872704
2026-04-17 11:10:38 +01:00
Doug Gregor 8713c13bef Centralize computation of the "code generation model" for object code & SIL
For a given function, we might end up emitting it's definition as
object code, serialized SIL, or both. The @export, @inlinable, and
@inline(always) attributes provide control of this behavior at the
declaration level.

Centralize the query function that will look for each of these
attributes and map down to a specific "code generation model", whose 3
options follow the naming from SE-0497: interface, inlinable, and
implementation. Use this one computation to back the queries for
"always emit into client", "never emit into client", and "inlinable"
so we can't get inconsistent results from places that are doing
one-off checks for these attributes.
2026-04-15 13:03:55 -07:00
Tim Kientzle c85ebdaed5 Write yielding accessor names to swiftinterface files
Back in January, I updated the swiftinterface _reading_ code to accept either
`read`/`modify` or `yielding borrow`/`yielding mutate`.  That update has been
around for long enough that we can now switch over the swiftinterface _writing_
code to emit the standard final `yielding borrow`/`yielding mutate` spellings.

Interface files written with the old spellings will continue to be
accepted for some time (likely a year or more).
2026-04-15 12:34:46 -07:00
Alexis Laferrière 8d5d16a9f3 Merge branch 'main' into exportability-embedded-class-properties 2026-04-07 08:36:09 -07:00
Doug Gregor fa4c4facae Merge pull request #88325 from DougGregor/dtor-lookup-embedded
Replace an O(n) search for a destructor with a lookup
2026-04-06 15:35:50 -07:00
Doug Gregor ed0acb74d7 Replace an O(n) search for a destructor with a lookup 2026-04-06 10:47:59 -07:00
Alexis Laferrière dd798e0079 Embedded: Accept and enforce @_implementationOnly class properties
When hiding dependencies in embedded mode there are special rules for
classes. Classes properties can safely reference the hidden
dependencies, however code referencing these properties must be marked
`@export(interface)`.

We previously added a check to report implicit code without the requited
`@export(interface)`. However explicit references from user written code
wasn't fully checked, only explicit references to the imported type or
the type's services would be reported, not references to the property
itself.

We patch that hole here by introducing new requirements and a new layer
of check specific to class properies in embedded mode.

---

Class properties referencing a hidden dependency must be marked
`@_implementationOnly`. This adds on top of the requirement for the
class itself to have an explicit `@export(interface) deinit`.

This allows to report references from user written code using existing
diagnostics.
2026-03-24 13:18:23 -07:00
Alexis Laferrière 0b4827c775 Embedded: Check exportability of implicit inits in classes
Without library-evolution we can be more permissive about references to
hidden dependencies from classes properties. However, lifting these
checks broke other checks on properties. Here we fix this hole and
ensure that while we allow references from stored properties we still
checking implicit initializers.

rdar://173011223
2026-03-23 10:49:17 -07:00
Alexis Laferrière 7c1b4802c8 Sema: Require classes to have a deinit for references non Embedded
Even without library-evolution, we allow references to hidden
dependencies from class properties as long as the class is not marked
open. In embedded, references from functions are only accepted when
marked `@export(interface)` as it can't be inlined in clients.

Combine both requirements to protect the implicitly generated destructor
as well. Add a requirement for classes with such a property to
explicitly declare a `@export(interface)` deinit. Otherwise that deinit
may be inlined in clients and cause a deserialization failure.

rdar://170855491
2026-03-12 09:59:59 -07:00
John Hui 9fe81ed792 Merge pull request #87643 from j-hui/frt-rq 2026-03-06 16:11:10 -08:00
John Hui e178af568c [cxx-interop] [NFC] Replace some uses of CxxRecordSemantics
... with ForeignReferenceTypeInfoRequest (which CxxRecordSemantics now
uses under the hood anyway).

rdar://170858418
2026-03-05 14:22:57 -08:00