If an InFlightSubstitution has an active pack expansion, then substituting a
PackArchetypeType could cause a PackElementType to be introduced, possibly
erroneously. ProtocolConformanceRef::forAbstract cannot handle PackElementType
types, so set the PreservePackExpansionLevel flag prevents this.
The pass merges to adjacent borrow scopes in a basic block.
```
%2 = begin_borrow %1
use(%2)
end_borrow %2
...
%6 = begin_borrow %1
use(%6)
end_borrow %6
```
->
```
%2 = begin_borrow %1
use(%2)
...
use(%2)
end_borrow %2
```
This helps other optimizations, like common-subexpression-elimination, because the borrow liveranges are larger and not split.
In C++, `std::nullopt` is implicitly convertible to `std::optional<T>`. Swift doesn't support implicit type conversions between arbitrary types. Instead, the developer is expected to use `nil` literal, which is implicitly converted to `std::optional<T>`. This works via `CxxOptional`'s conformance to `ExpressibleByNilLiteral`.
This improves the diagnostic produced by Swift for the attempted usage of `std::nullopt` in places where the type conversion expected by the developer doesn't happen. A note will now be emitted:
```
use the 'nil' literal instead
```
rdar://162203520
It's like Builtin.gep, but marks the resulting `index_addr` as a projection, meaning the result can only reach the single element at the given index and cannot be used for general pointer arithmetic by chaining `index_addr` instructions.
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.
This patch consolidates the FRTInfo checking logic into a single
recursive traversal within a visitor class. It is not intended to have
any observable functional difference in the analysis.
**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>
This PR introduces a new Swift builtin `Builtin.dereferenceable` that
allows the compiler to provide dereferenceable memory hints to LLVM for
optimization purposes.
Resolves rdar://174255636
This adds support for calling virtual methods of C++ foreign reference types with static dispatch.
In C++, one can do:
```cpp
this->Base::virtualMethod()
```
Swift doesn't allow calling a particular overload of an overridden method, however, it allows calling an overload from the superclass with `super`:
```swift
extension Derived {
public func callSuper() {
return super.foo()
}
}
```
For inherited FRTs, the example above behaved in an unexpected way: the call would still be dispatched dynamically, despite using the syntax reserved for static dispatch. This change makes it behave similarly to pure-Swift classes.
rdar://177619427
The cooperative global executor uses <chrono> for its handling of
times. This creates a dependency on a C++11 standard library, and
doesn't actually work with freestanding implementations like we want
for Embedded Swift.
Replace this <chrono> usage with swift_sleep / swift_get_time from
the concurrency library, which already considers various
platform-specific implementations before falling back to <chrono>.
Enable -ffreestanding for the embedded Concurrency library and its
support libraries.
This is a follow-up to 6c464579.
Importing superclasses of C++ foreign reference types can introduce source breaks in Swift under some circumstances.
This change puts the feature behind an experimental flag.
rdar://178736469
When a case statement body inside a switch statement is only reachable if a
specific enum element matches the switch subject, the compiler now generates an
availability scope for the case body that matches the availability of the enum
element:
```
@available(macOS 26, *)
func f() -> Int { 0 }
enum E {
@available(macOS 26, *)
case a
}
func multiplex(_ e: E) -> Int {
switch e {
case .a:
return f() // OK, .a is only available in macOS 26
}
}
```
Supporting the same refinement for cases in switch expressions will need to be
handled as a follow-up as it may require changes to the order in which switch
expression case bodies are type checked relative to the case label.
Resolves https://github.com/swiftlang/swift/issues/46662 and rdar://20937722.
…rather than lazily populating the _isSet flags on access. In most cases
this should go from O(n) writes to 0, since none of them will be set
(#89651)"
This reverts commit c5f72c8f19.
This optimization pull broke the Android CI, #89708, so reverting until
we can figure out why.
Memory analysis tools have trouble identifying the metadata allocator pages. When allocating a new page, write a pointer to the previous page at the end. Combined with the existing _swift_debug_allocationPoolPointer variable, this will allow all metadata allocation pages to be identified definitively.
rdar://175515505
If the module named in `#if canImport(<Module>, _version: ...)` cannot be
found, it may indicate that the developer misspelled the module name. Emit a
warning to indicate that the directive evaluates to false. If it is intentional
that the module not be found, the developer can avoid the warning by first
checking whether the module can be imported and then check its version.
Resolves rdar://128367758.
Avoiding the duplicate `cannot_find_module_version` diagnostics routed
`ExportedSourceFile.configuredRegions(astContext:)` through the side-effect-free
`.analyzing` canImport query. For the default C++ parser that is always correct:
its `EvaluateIfConditionRequest` remains the canonical site that emits the
diagnostic and records the result in `CanImportModuleVersions`, and the
configured-regions walk is only a secondary re-derivation used for various
compiler analysis clients (e.g. warning group control).
In ASTGen-only mode (`-enable-experimental-feature ParserASTGen`) the C++
parser, and therefore `EvaluateIfConditionRequest`, never runs; the
configured-regions walk is the only evaluation that drives `canImport`. Routing
it through `.analyzing` consequently suppressed the diagnostic.
This change adds `swift_ASTGen_evaluateConfiguredRegionsForDiagnostics`, invoked
once at the start of `parseSourceFileViaASTGen`, which evaluates the file's
`#if` directives in `.driving` mode to emit the diagnostics and populate the
version cache before any analysis path consumes the configured-regions cache.
`#if canImport(...)` conditions are evaluated by the parser's primary
`EvaluateIfConditionRequest`, which emits `cannot_find_module_version` and
records the result in `CanImportModuleVersions`. Several later analyses re-walk
the same directives and, before this change, routed through that same emitting
`canImportModule` path, duplicating the diagnostic: the
`ExportedSourceFile.configuredRegions` region-tree rebuild that backs
diagnostic-group control (which could also recurse indefinitely), and the
`VarDeclUsageChecker` inactive-code scans behind unused-variable diagnostics.
Introduce a `CanImportMode` on `CompilerBuildConfiguration` distinguishing the
canonical, diagnostic-emitting `.driving` query from a side-effect-free
`.analyzing` re-derivation. `.analyzing` routes to the new
`BridgedASTContext.testCanImport` -> `ASTContext::testImportModule` bridge,
which answers from the module loaders without emitting diagnostics or populating
`CanImportModuleVersions`; `.driving` keeps the existing `canImport` behavior.
The mode defaults to `.analyzing`, so only the canonical site
`evaluatePoundIfCondition` drives, while every secondary walk re-derives `#if`
activity without repeating the diagnostic.
Adopt changes to `SwiftWarningControl` library API that allow specifying an
input `ConfiguredRegions` parameter to construct a `warningControlTree`.
Resolves rdar://176454319
The initial IPI implementation emits an error when an api/spi-level
module publicly imports an ipi-level module. That is too aggressive for
incremental adoption.
Wrap the diagnostic in a new diagnostic group (IPIVerification) and emit
it as a warning.
Also reword the message from "...from non-internal module 'X'" to a clearer
"...because 'X' has '-library-level api/spi'"
rdar://178560797