Commit Graph

158 Commits

Author SHA1 Message Date
Henrik G. Olsson 7bbaeebba1 [Swiftify] enable safe wrappers for std::span without typedef
We previously prevented generating safe wrappers on functions with
template instantiations in the signature, unless those instantiations
were hidden behind a typedef. This is because those template
instantiations cannot be expressed in Swift syntax, so the macro
would expand to a function with invalid syntax.

For the std::span parameter itself however, that type is replaced with a
Swift Span in the safe wrapper, so it's not an issue in the type
signature. We would previously use the std::span type name from the
original signature to cast from Span to std::span, which does not work
with the raw std::span type. This uses `.init` instead when this is the
case, which avoids spelling out the type. When possible, we still use
the concrete type name, for clarity and by providing information we have
accessible the typechecker needs to do less work.

Resolves #86339

rdar://167712240
2026-04-29 12:30:44 -07:00
Doug Gregor af4c129026 Update SwiftifyImport macro to not emit now-extraneous "unsafe"s 2026-04-17 10:41:17 -07:00
Henrik G. Olsson 9d770fded3 [Swiftify] extend lifetime of unwrapped spans
If a wrapper function is inlined, the span lifetime can end up being
shortened past the use of the internal pointer. This adds an artificial
lifetime extension to prevent this from happening.

rdar://170108525
2026-02-12 11:30:51 -08:00
Henrik G. Olsson a4366f63e1 [Swiftify] handle ~Escapable return values
This adds support for safe wrappers on imported functions returning a
~Escapable value. This is only done if there is lifetime information for
the return value, as the wrapper will always have a lifetime error
otherwise. __lifetimebound is also ignored *unless* the return value is
~Escapable (or will be transformed to a Span), since lifetime info for
an Escapable return value is an error. To enable testing this it also
adds merging of lifetime annotations from the underlying funciton and
the extra info added by the macro.

rdar://157884394
2026-02-06 23:07:08 -08:00
Henrik G. Olsson 2c5542870d [Swiftify] mark init overloads "convenience" in classes
This fixes a test failure where the macro expansion did not mark it's
generated initializer as "convenience init". Struct initializers are
never marked "convenience init" however, so this checks the parent
context.
2026-02-05 11:25:40 -08:00
Henrik G. Olsson 7680725396 [Swiftify] properly support initializers
This linearizes the macro expansions by leaking the internal buffer
pointer in [Mutable][Raw]Span parameters. This avoids the closure-based
nesting, simplifying the function body, but more importantly avoids an
error when the function is an intializer: Swift does not allow calls to
delegated initializers inside other expressions or closures.

Initializers for CoreFoundation-style references are not allowed at all
(other than the ones imported from C), so safe wrappers on those are
avoided entirely.

rdar://169661706
2026-02-04 19:06:46 -08:00
Henrik G. Olsson 4def7528f6 [Swiftify] fix borrow syntax for lifetimebound on mutating self
Mutating methods that borrow self should use the @_lifetime(&self)
syntax.

rdar://153484170
2026-01-29 22:43:52 -08:00
Tim Kientzle 104dba920b [SE-0474] Implement yielding borrow and yielding mutate syntax
This does not rename all the internal variables, functions, and types
whose names were based on the old syntax.

I think it adds new syntax support everywhere it's needed while
retaining enough of the old syntax support that early adopters will
see nice deprecation messages guiding them to the new syntax.
2026-01-03 15:07:10 -08:00
Henrik G. Olsson f1d564ddfe Merge pull request #85123 from hnrklssn/swiftify-obj-c2
[ClangImporter] Attach _SwiftifyImportProtocol to imported protocols with bounds attributes
2025-11-13 12:02:17 -08:00
Henrik G. Olsson 7025b03449 Update lib/Macros/Sources/SwiftMacros/SwiftifyImportMacro.swift
Co-authored-by: John Hui <updog@j-hui.com>
2025-11-10 19:18:17 -08:00
Ben Barham c97838654e Merge pull request #84833 from jamieQ/obs-macro-ii
[Observation]: fix @Observable macro producing invalid code with certain comments
2025-10-31 14:49:27 -07:00
Allan Shortlidge 8cf7582083 Swiftify: Fix an unused variable warning. 2025-10-26 18:00:05 -07:00
Jamie 21b57f7856 [fix][Observation]: further attempts to resolve macro expansion
interaction with comments

Adds logic to insert newlines in various places to try and resolve the
fact that the current expansion produces invalid code in some cases
depending on comment location. Adds some basic tests of the expansion
output.
2025-10-25 20:39:43 -05:00
Henrik G. Olsson ce27af61f7 [Swiftify] make protocol extension methods public 2025-10-24 13:13:05 -07:00
Kuba (Brecka) Mracek eb23d3bc0a Merge pull request #85074 from kubamracek/section
SE-0492: Stabilize @_section/@_used into @section/@used
2025-10-24 12:29:48 -07:00
Kuba Mracek adeb40f261 SE-0492: Stabilize @_section/@_used into @section/@used
Removes the underscored prefixes from the @_section and @_used attributes, making them public as @section and @used respectively. The SymbolLinkageMarkers experimental feature has been removed as these attributes are now part of the standard language. Implemented expression syntactic checking rules per SE-0492.

Major parts:
- Renamed @_section to @section and @_used to @used
- Removed the SymbolLinkageMarkers experimental feature
- Added parsing support for the old underscored names with deprecation warnings
- Updated all tests and examples to use the new attribute names
- Added syntactic validation for @section to align with SE-0492 (reusing the legality checker by @artemcm)
- Changed @DebugDescription macro to explicitly use a tuple type instead of type inferring it, to comply with the expression syntax rules
- Added a testcase for the various allowed and disallowed syntactic forms, `test/ConstValues/SectionSyntactic.swift`.
2025-10-22 16:05:39 -07:00
Henrik G. Olsson 48f81c82dd [Swiftify] Add _SwiftifyImportProtocol for safe overloads for protocols
The existing _SwiftifyImport macro is a peer macro, limiting it to only
emitting function wrappers in the same scope as the original function.
Protocols cannot contain function implementations, so these need to be
placed in a separate protocol extension instead. _SwiftifyImportProtocol
is an extension macro rather than a peer macro, to enable this
functionality.

Rather than operating on a single function, like _SwiftifyImport,
_SwiftifyImportProtocol takes information about multiple methods and
creates a single protocol extension with all wrappers in a one-shot
operation.

rdar://144335990
2025-10-21 21:19:54 -07:00
Konrad Malawski 208c7aeafa [Distributed] Make sure we copy @available and spi for resolvable extensions
Relates to rdar://162800185
2025-10-17 09:27:00 +09:00
Henrik G. Olsson 41903b5bef Merge pull request #84834 from hnrklssn/fix-swiftify-package
[Swiftify] Fix Package.swift
2025-10-13 15:14:13 -07:00
Henrik G. Olsson 16e71da17e Merge pull request #84832 from hnrklssn/swiftify-extract-core
[Swiftify] Extract core of _SwiftifyImport (NFCI)
2025-10-13 13:38:33 -07:00
Henrik G. Olsson bae041c192 Merge pull request #84841 from hnrklssn/swiftify-return-opaque
[Swiftify] Cast OpaquePointer to UnsafeRawPointer before RawSpan
2025-10-13 13:35:24 -07:00
Zev Eisenberg 0d1e482cfe [Observation] fix bug where a comment in an annotation would result in invalid macro expansion. The comment was 'eating' the generated variable declaration, preventing it from being visible to the compiler. 2025-10-11 16:35:59 -05:00
Henrik G. Olsson a62b0054f5 [Swiftify] Cast OpaquePointer to UnsafeRawPointer before RawSpan
The initializers for RawSpan and UnsafeRawBufferPointer take an
UnsafeRawPointer, so when the underlying function returns an
OpaquePointer we need to cast it first.

rdar://162091516
2025-10-11 13:06:09 -07:00
Henrik G. Olsson 2e01ba308f [Swiftify] Don't use unsafe for Unsafe[Mut][Raw]BufferPointer.count
Although the type is unsafe, the count is marked `@safe`, and this use
of `unsafe` results in a warning (regardless of whether strict memory
safety is enabled or not).
Keep emitting `unsafe` when the pointer buffer is wrapped in Optional
for now however, because that is currently flagged as unsafe.

rdar://162416566
2025-10-10 22:51:24 -07:00
Henrik G. Olsson 2d00d94189 [Swiftify] Fix Package.swift
Swift packages are normally in `Sources/<target-name>`, but
SwiftifyImportMacro is in `Sources/SwiftMacros`, and SwiftifyImport is
in `<root>/stdlib/public/core`, which is outside the package root. This
sets the correct path for SwiftifyImportMacro, and creates a directory
`Sources/PublicCorePortal` with a symlink to `SwiftifyImport.swift`.
It also enables LifetimeDependence for SwiftifyImport.

These changes are purely to provide information to SourceKit - this file
isn't actually used by CMake.
2025-10-10 17:00:25 -07:00
Henrik G. Olsson e15f4292e6 [Swiftify] Extract core of _SwiftifyImport (NFCI)
This refactors _SwiftifyImport in preparation of
_SwiftifyImportProtocol, so that they can share a common core
implementation.
2025-10-10 16:42:00 -07:00
Henrik G. Olsson fa252fd5b9 [Swiftify] Support std::span in Android NDK
The Android NDK uses `std.__ndk.span` rather than `std.__1.span`.
2025-10-07 13:50:09 -07:00
Henrik G. Olsson 663ba2efb4 [Swiftify] properly forward inout parameters using &
While we handled prepending & to MutableSpan parameters, regular
parameters that were unchanged during the transformation were not
checked for inout-ness.
2025-10-02 16:37:43 -07:00
Konrad `ktoso` Malawski ec8caf3cdd Remove the experimental @Task macro (#82437) 2025-07-03 10:15:21 -07:00
Meghana Gupta 0dfa1fc312 Update spelling for representing lifetime dependencies to @_lifetime 2025-06-07 12:49:07 -07:00
Henrik G. Olsson 89b09a69e4 Merge pull request #81752 from hnrklssn/swiftify-sized-sizedby
[Swiftify] Support __sized_by on byte-sized pointee types
2025-06-05 08:42:42 -07:00
Gabor Horvath d5faddaa9b [cxx-interop] Support Swiftifying C++ constructors
Unfortunately, there is no common abstraction for initializers and
functions in SwiftSyntax, so this PR rolls our own. Alternatively, we
could probably achieve something similar with a new protocol, but we
only needed a handful of fields so this change keeps it simple.

rdar://152112660
2025-06-04 10:06:16 +01:00
Henrik G. Olsson 0f0a2ca4bb [Swiftify] Support __sized_by on byte-sized pointee types
Previously we would emit a macro that would error on expansion when
trying to add a safe wrapper to a function with __sized_by on a type
that mapped to UnsafePointer<T> instead of UnsafeRawPointer or
OpaquePointer. __sized_by is acceptable when used on byte-sized pointee
types, so this adds machinery in the macro expansion to support that.
Meanwhile on the ClangImporter side, we add a check so that __sized_by
on pointee types with a size is ignored if that size is larger than 1
byte.

When _SwiftifyImport applies .sizedBy to a pointer of type
UnsafePointer<T> it will still map it to a
RawSpan/UnsafeRawBufferPointer in the safe overload. The assumption is
that any API using __sized_by is dealing with raw bytes, so raw pointers
are a better Swift abstraction than UnsafePointer<CChar> etc. It also
lets the user avoid doing a scary pointer cast from some potentially
larger-than-byte-sized pointer to a byte-sized pointer. Casts to
RawPointers are generally safer and more ergonomic.

rdar://150966684
rdar://150966021
2025-05-29 13:32:53 -07:00
Henrik G. Olsson f5fa481205 [Swiftify] Always remove count parameters when possible (#81585)
Previously we did not remove count parameters if any count parameters
were shared between count expressions, or if any count expression
contained operations. Buffer sizes were also just checked to be larger
than or equal than the given count.

We now extract the count from Spans/BufferPointers whenever possible,
and store that value in a variable at the start of the function. If
multiple parameters share the same count, a bounds check is emitted to
make sure that they have the same size. Subspans can be used if one span
is larger than necessary.

The message in the bounds check is changed so that it includes the
expected and actual value, to aid in debugging.

This patch also fixes some incorrect indentation, and adds the
Whitespace.swift test case to act as a regression test in case the
indentation changes, since the other test cases don't use significant
whitespace.

rdar://151488820
rdar://151511090
rdar://146333006
rdar://147715799
2025-05-24 22:08:51 -07:00
Henrik G. Olsson 0f312adb92 [Swiftify] Always annotate overloads with @_disfavoredOverload (#81579)
Previously we would only add @_disfavoredOverload if the only type
changed was the return type, because in any other case it is unambiguous
which overload to call. However it is still ambiguous when storing the
function as a value rather than calling the function, unless explicit
type annotations are used.

To avoid breaking any existing code, this patch adds
@_disfavoredOverload to every overload generated by @_SwiftifyImport.

rdar://151206394
2025-05-23 21:21:49 -07:00
Henrik G. Olsson ebe2c60f43 [Swiftify] Escape param decl refs (#81550)
Parameters can be named with keywords without escaping, because it's
unambiguous in the grammar that they are parameters. They still need to
escaped when referred to inside the function body however. This escapes
all references to parameters using backticks.

Parameter names are also checked for clashes with the function name - in
such cases the parameter is renamed in the same way as unnamed
parameters.

rdar://151024645
2025-05-23 12:33:58 -07:00
Henrik G. Olsson 262a53f599 [Swiftify] Update availability for CxxSpan<->Span, fix lifetimebound on parameters with reference type (#81634)
Update availability for CxxSpan<->Span, fix lifetimebound on parameters
with reference type

Because swift-ide-test doesn't care about typechecking,
std-span-interface.swift passed despite containing 2 separate errors.
This updates the test file to properly exercise the entire compilation
pipeline for the macro expansions, by running swift-frontend
-emit-module and calling each macro expansion.

The first issue was that CxxSpan initializers taking [Mutable]Span still
had their availability set to Swift 6.2+, even after back-deploying
caused [Mutable]Span to have availability back to Swift 5.0. Since
_SwiftifyImport expansions copy the availbility of Span, this resulted
in the macro expansions calling unavailable initializers. Interestingly
enough, this manifested itself in the form of a tripped assert in SIL
verification, because although we do now typecheck the expansions from
_SwiftifyImport, the compilation can still keep going after
`shouldEmitFunctionBody` returns false: the macro expansion declaration
is still there, but is now missing its definition, despite not being
external.

The second issue was when parameters with C++ reference types were
annotated with `[[clang::lifetimebound]]`. For parameters with a type
that is `Escapable`, this is normally done using `@lifetime(borrow
foo)`. However C++ reference parameters are imported as `inout`, which
requires the `@lifetime(&foo)` syntax.

rdar://151493400
rdar://151678415
2025-05-22 15:36:19 -07:00
Henrik G. Olsson 526c68333c [Swiftify] Fix __sized_by and nullable return values (#81693)
Nullable return Spans did not include __swiftifyOverrideLifetime,
resulting in a lifetime error when returning the Span. Meanwhile return
values for __sized_by did not use the correct label for the call to the
RawSpan initializer, using `count` instead of `byteCount`.

rdar://151804085
rdar://151799287
2025-05-22 15:34:58 -07:00
Henrik G. Olsson 6534b9b14f [Swiftify] Copy doc comment from clang node (#81584)
Swift nodes imported from clang don't have doc comments carried over,
but IDEs are clever enough to fetch the comments from the associated
clang node. The swift node in the macro expansion from _SwiftifyImport
doesn't have a clang node directly associated with it however.

This patch adds the same comment from the clang node to the
_SwiftifyImport macro invocation node. Since the macro has access to
this node, it can easily copy over its leading trivia.

For now the comment is not altered at all, meaning @param still remains
even if the parmeter is removed.

rdar://151346977
2025-05-20 08:06:20 -07:00
Henrik G. Olsson 8e27947b2a [Swiftify] Handle anonymous parameters (#81384)
_SwiftifyImport would expand with syntax errors if applied to a function
with anonymous parameters, because it would try to refer to parameters
using the name `_`. Detect these cases and create names for unnamed
parameters.

rdar://150955944
2025-05-08 23:28:14 -07:00
Henrik G. Olsson 59d7d3160f [Swiftify] Emit @availability when expansions contain Span (#81320)
This prevents errors when compiling for older targets using a newer
compiler.

rdar://150740330
2025-05-08 16:13:24 -07:00
Henrik G. Olsson bd233ea26e [Swiftify] Don't use count from Span inside withUnsafeBufferPointer call (#81267) 2025-05-04 01:52:05 -07:00
Doug Gregor fed18d58dc [Observation] Create nonisolated conformances to Observable
This is needed to make default-main-actor mode work well with
Observable. Fixes rdar://150419628.
2025-05-01 22:01:41 -07:00
Philippe Hausler 2381d394db [Observation] forward line numbers to didSet and other property observers from their spelled location to the code-generated duplicated storage location (#80661)
* [Observation] forward line numbers to didSet and other property observers from their spelled location to the code-generated duplicated storage location

* Only emit source locations for the prolog of the body and emit an empty location for the epilog

* Add missing attribute member

* Use the fixed version of the locations since swift-syntax 6.0.1 reports sub-nodes correctly in all contexts
2025-04-18 13:41:21 -07:00
Henrik G. Olsson 4d28cc61c9 [Swiftify] clean up (NFC) (#80400)
* [Swiftify] Extract static methods to free functions (NFC)

This will make the diff smaller with introducing
_SwiftifyImportProtocol.

* [Swiftify] Run swift-format (NFC)

* [Swiftify] Remove `try` from non-throwing expression (NFC)
2025-04-02 21:24:00 -07:00
Allan Shortlidge 82e4e50c93 Distributed: Fix some deprecation warnings in DistributedResolvableMacro. 2025-04-01 13:11:36 -07:00
Allan Shortlidge 119b38e13a Swiftify: Fix 'no calls to throwing function' warnings. 2025-04-01 13:11:28 -07:00
Henrik G. Olsson 87f5309144 [Swiftify] enable mutable span (#80387)
* [Swiftify] Emit Mutable[Raw]Span when possible

Previously wrappers would use UnsafeMutable[Raw]Pointer for mutable
pointers, and Span for non-const std::span, to prevent the compiler from
complaining that MutableSpan didn't exist.

Now that MutableSpan has landed we can finally emit MutableSpan without
causing compilation errors. While we had (disabled) support for MutableSpan
syntax already, some unexpected semantic errors required additional
changes:
 - Mutable[Raw]Span parameters need to be inout (for mutation)
 - inout ~Escapable paramters need explicit lifetime annotations
 - MutableSpan cannot be directly bitcast to std::span, because it is
   ~Copyable, so they need unwrapping to UnsafeMutableBufferPointer

rdar://147883022

* [Swiftify] Wrap if-expressions in Immediately Called Closures

When parameters in swiftified wrapper functions are nullable, we use
separate branches for the nil and nonnil cases, because
`withUnsafeBufferPointer` (and similar) cannot be called on nil.
If-expressions have some limitations on where they are allowed in the
grammar, and cannot be passed as arguments to a function. As such, when
the return value is also swiftified, we get an error when trying to
pass the if-expression to the UnsafeBufferPointer/Span constructor.
While it isn't pretty, the best way forward seems to be by wrapping the
if-expressions in Immediately Called Closures.

The closures have the side-effect of acting as a barrier for 'unsafe':
unsafe keywords outside the closure do not "reach" unsafe expressions
inside the closure. We therefore have to emit "unsafe" where unsafe
expressions are used, rather than just when returning.

rdar://148153063
2025-03-29 05:05:01 -07:00
Henrik G. Olsson d1737b9c20 [Swiftify] Add MutableSpan support for std::span, and disable it (#80315)
__counted_by already had MutableSpan support, so add it for std::span
for parity. But since MutableSpan hasn't landed in the standard library
yet, disable emitting it to prevent compilation errors in expansions.

rdar://147882736
2025-03-27 16:37:31 -07:00
Henrik G. Olsson 160bb41ec2 [Swiftify] Fix return value transformation being applied last
Casting the return value to Span must be done outside
withUnsafeBufferPointer, to prevent returning a ~Escapable type from a
function without lifetime info. To do this we sort the transformations
so that the return value transformation is performed last. There was
a bug in the comparison, so the sorting was not always done correctly.

rdar://147934170
2025-03-26 13:49:22 -07:00