Commit Graph

334 Commits

Author SHA1 Message Date
Ben Cohen 3c7cd8fc0c SILGen: handle non-Error destinations in emitThrow (#88948)
`emitThrow` previously asserted that the only legal mismatch between the
in-flight error type and the throw destination was `any Error`, then
existential-erased to `Error`. Anything else Sema accepted — `do
throws(any P) where P: Error`, or a class subtype of the destination —
crashed the assertion (or, before that was tightened, miscompiled at
runtime).

Dispatch on the destination type:
- existential: erase, looking up conformance to each protocol in the
destination's existential layout (so `any P` works, not just `any
Error`);
- class: emit an `upcast`.

Anything else still hits an `unreachable` — Sema rejects those today, so
hitting it would indicate a Sema regression rather than a missing SILGen
path.

Fixes https://github.com/swiftlang/swift/issues/83826.
2026-05-19 11:37:08 -07:00
John McCall 09747e1d86 As a special case, emit defers that call a single builtin inline.
There's an argument that it would generally be better to do this for all
defers, but I really don't want to open that can of worms in this commit.
I'm just trying to make it possible to build specific SIL relationships
using decomposed builtins, and this hack works for that without changing
the normal code-generation pattern, since only a restricted set of code
should be calling builtins in the first place.

Allowing these SIL relationships to be built directly by (careful) Swift
code makes it much easier to model these things, since otherwise we need
a separate higher-order builtin that SILGen lowers.

Tested in a follow-up commit.

We can lock down the condition further if we have source compatibility
problems from people using -enable-builtin-module casually.
2026-03-13 19:40:20 -04:00
Meghana Gupta 6232051247 [NFC] Update a diagnostic for borrow/mutate accessors 2026-03-03 12:50:36 -08:00
Meghana Gupta 087f208ac8 Support borrow accessors returning global lets 2026-02-27 10:54:04 -08:00
Meghana Gupta 085ea1aaf7 Merge pull request #87347 from meg-gupta/diagnoseborrowreabs
Add additional diagnostics for borrow/mutate accessors
2026-02-20 02:37:40 -08:00
Meghana Gupta 5bf5b00ee9 Diagnose multiple returns in borrow/mutate accessors annotated with @_unsafeSelfDependentResult as well 2026-02-18 15:56:39 -08:00
Kavon Farvardin 0b532fe221 SILGen: emit destroy_value if discarding error
Fixes an emission issue with typed throws where the error
path after a `try_apply` is missing a `destroy_value`
on the unused basic block argument holding the error.

Forgetting to emit that makes the SIL verifier upset.

rdar://170353819
2026-02-17 14:02:03 -08:00
Elsa Keirouz 2a0bc57763 [AST] desugar ForEachStmt for BorrowingSequence protocol 2026-02-11 16:02:25 +00:00
Meghana Gupta b75eac9836 Use @guaranteed result convention for borrow accessors returning trivial types 2026-01-30 14:29:06 -08:00
Meghana Gupta d1df7aa236 Diagnose trivial-type borrow accessor results using the same rules as non-trivial types 2026-01-29 15:45:06 -08:00
Meghana Gupta de9dd60c75 Merge pull request #86835 from meg-gupta/banliterals
Ban returning literals from borrow accessors
2026-01-27 20:52:28 -08:00
Meghana Gupta 052ebc32da Ban returning literals from borrow accessors
literals are not "stored values" in a general sense and cannot be returned by borrow accessors
2026-01-27 16:02:29 -08:00
Joe Groff 0f3ddfbcc8 Merge pull request #86545 from jckarter/builtin-borrow
`Builtin.Borrow` implementation
2026-01-26 07:32:31 -08:00
Joe Groff 3d543f545e SILGen: Lowering for Builtin.dereferenceBorrow.
This builtin only needs to be supported as the return of a borrow accessor,
so special case its handling as part of a storage expression in SILGenLValue.
2026-01-23 08:02:08 -08:00
Elsa Keirouz f7c21941b8 [AST] ForEachStmt: rename sequence getter/setter 2026-01-23 15:17:29 +00:00
Elsa Keirouz d54a572f7f [Sema] desugar ForEachStmt at AST level 2026-01-23 15:17:29 +00:00
Elsa Keirouz 27cef65d56 [AST] Introduce opaque AST nodes 2026-01-23 15:17:28 +00:00
Slava Pestov 522a6b7c80 SILGen: Fix break/continue inside 'for ... in ... repeat' loop
We were creating the JumpDests too early, so lowering a 'break' or 'continue'
statement would perform cleanups that were recorded while evaluating the
pack expansion expression, which would cause SIL verifier errors and
runtime crashes.

- Fixes https://github.com/swiftlang/swift/issues/78598
- Fixes rdar://131847933
2025-11-10 20:51:45 -05:00
Meghana Gupta d50aa8ad87 [NFC] Comment on the use of unchecked_ownership 2025-11-06 10:55:41 -08:00
Meghana Gupta bef207521d Use unchecked_ownership during SILGen of borrow accessors 2025-10-23 05:19:10 -07:00
Meghana Gupta a150c67896 Remove unchecked_ownership_conversion from borrow accessor silgen 2025-10-23 05:19:04 -07:00
Meghana Gupta 6c4dd2bc8b [NFC] Eliminate unused variable warning 2025-10-20 09:05:40 -07:00
Meghana Gupta a0c939bd3b Use @inout result convention for mutate accessors 2025-10-20 09:05:32 -07:00
Kavon Farvardin a528c5c19c Merge pull request #84734 from kavon/opaque-values/fixes-2
OpaqueValues: support typed throws
2025-10-08 21:17:23 -07:00
Meghana Gupta 4b7297ac2f Update SILGen for unsafe mutate accessors 2025-10-07 14:12:15 -07:00
Meghana Gupta 3103be60bc Update SILGen for mutate accessors 2025-10-07 14:12:10 -07:00
Kavon Farvardin 00ecc6c2ce SILGen: fix typed throws emission for opaque values
We use a direct @error emission style when opaque values
is enabled, relying on AddressLowering to satisfy the
formal @error_indirect convention.
2025-10-07 09:30:32 -07:00
Kavon Farvardin b9f0578d86 SILGen: refactor emitCleanupsForBranch 2025-10-07 09:27:44 -07:00
Meghana Gupta e4d1123d10 Fix SILGen of borrow accessors returning guaranteed values from within a local borrow
Borrow accessor result can sometimes be generated from a local borrow and
returning the result produced within the local borrow scope will cause ownership errors.

We have to introduce new SIL semantics to make this possible.
Until then use a pair of unchecked_ownership_conversion instructions to silence the ownership errors.
We encounter this when we have:

Address-only self and @guaranteed result
Loadable self and @guaranteed result derived from an unsafe pointer stored property

This change also updates the result convention of borrow accessors with loadable result types
and indirect self argument type.
2025-10-02 07:42:14 -07:00
Meghana Gupta b6c8f8994a [NFC] Move SILGen of ReturnExpr in borrow accessors to a new function 2025-10-02 07:42:12 -07:00
Meghana Gupta fa7281d66e Introduce a new attribute @_unsafeSelfDependentResult
It can be used in borrow/mutate accessors to unsafely specify that the
result is dependent on the self access.
2025-10-02 07:42:07 -07:00
Meghana Gupta 78a165d3ef Fix SILGenBorrowedBaseVisitor::isNonCopyableBaseBorrow 2025-10-02 07:18:26 -07:00
Meghana Gupta c2dab58876 Update SILGen for ~Copyable borrow accessors
Introduce copy_value + mark_unresolved_non_copyable_value + begin_borrow at the return value of
borrow accessor apply to drive move-only diagnostics.

Also strip the copy_value + mark_unresolved_non_copyable_value + begin_borrow trio in a few places, since
they create an artificial scope out of which we cannot return values in a borrow accessor
without resorting to unsafe SIL operations currently.

Borrow accessor diagnostics allow stripping these instructions safely in the following places:

- return value of a borrow accessor
- self argument reference in the borrow accessor return expression and borrow accessor apply
2025-10-02 07:18:23 -07:00
Meghana Gupta e98f3522c8 [NFC] Rename LVOptions::withBorrow -> LVOptions::forGuaranteedReturn
Also add forGuaranteedAddressReturn
2025-10-02 07:18:20 -07:00
Meghana Gupta e4213056a5 Ban multiple returns in borrow accessors returning values as well 2025-10-02 07:18:17 -07:00
Meghana Gupta 6665cd5d46 [NFC] hasGuaranteedAddressResults -> hasGuaranteedAddressResult and hasGuaranteedResults -> hasGuaranteedResult 2025-09-14 23:38:06 -07:00
Meghana Gupta 8c1231e86b SILGen support for borrow accessors on Copyable types and address-only ~Copyable types 2025-09-09 14:45:44 -07:00
Meghana Gupta 6b8c91efe2 [NFC] Move StorageRefResult to a header 2025-09-09 14:45:43 -07:00
Kavon Farvardin 4964a66277 silgen: inherit eval scope for OpenExistentialExpr
We were not able to use an existential as the base
of an access that strictly borrows the existential,
because SILGen's RValue emission would establish
a fresh evaluation scope just for the existential's
opening, and then copy the opened value out.

This is problematic for noncopyable existentials.

So this patch moves & adds FormalEvaluationScope's
around so they're broad enough to enable a
borrow of an existential. The idea behind this
refactoring is to establish top-level
FormalEvaluationScopes when initially creating
RValue's for Expr's in SILGen. Any more-tightly
scoped operations will already establish their own
nested scope, so this is mostly adding safe-guards.

I've limited the existentials fix to noncopyables
for now.

part of rdar://159079818
2025-08-29 13:30:42 -07:00
John McCall bee053f1f0 Switch InitializationPtr to use PossiblyUniquePtr so that we can just
forward existing initializations around when necessary.
2025-08-02 02:13:25 -04:00
Anthony Latsis fec049e5e4 Address llvm::PointerUnion::{is,get} deprecations
These were deprecated in
https://github.com/llvm/llvm-project/pull/122623.
2025-07-29 18:37:48 +01:00
Doug Gregor 5b2520e379 Remove IfConfigDecl from the AST
The swift-syntax tree retains information about the parsed #if
regions. Drop it from the semantic AST.
2024-09-18 20:51:54 -07:00
Slava Pestov 375363a473 AST: Move global conformance lookup entry points to ConformanceLookup.h 2024-08-08 23:35:58 -04:00
Slava Pestov 3fcda140bb AST: ModuleDecl::checkConformance() is a static method 2024-07-06 12:05:46 -04:00
Slava Pestov fae01d9776 AST: Remove ModuleDecl parameter from more places 2024-07-06 12:05:46 -04:00
Tim Kientzle 1098054291 Merge branch 'main' into tbkka-assertions2 2024-06-18 17:52:00 -07:00
Erik Eckstein 2200632a95 SILGen: ignore unreachable var decls
Fixes a crash in case a lazy var is declared after a return statement

https://github.com/apple/swift/issues/73736
2024-06-10 16:19:47 +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
Jamie 58166fc162 [SILGen]: diagnose unreachable opened existentials
updates unreachable code handling in SILGenStmt.cpp to diagnose
opened existentials that were previously ignored.

resolves: https://github.com/apple/swift/issues/73649
2024-05-19 23:26:54 -05:00
Joe Groff ba4f42420b SILGen: Move error values into indirect error returns in proper order with cleanups.
There's an unfortunate layering difference in the cleanup order between address-only
and loadable error values during `catch` pattern matching: for address-only values,
the value is copied into a temporary stack slot, and the stack slot is cleaned up
on exit from the pattern match, meaning the value must be moved into the error return
slot on the "no catch" case before cleanups run. But if it's a loadable value, then
we borrow it for the duration of the switch, and the borrow is released during cleanup
on exit from the pattern match, so the value must be forwarded after running cleanups.

The way the code is structured, it handles these cases properly when the convention of
the function being emitted is in sync with the fundamental properties of the error type
(when the error type is loadable and the error return is by value, or when the error
type is address-only and the error return is indirect, in other words). But when
a closure literal with a loadable error type is emitted in an argument context that
expects a function with an indirect error return, we would try to forward the loadable
error value into the error return slot while a borrow is still active on it, leading
to verifier errors. Defer forwarding the value into memory until after cleanups are
popped, fixing rdar://126576356.

A tidier solution might be to always emit the function body to use a bbarg on the
throw block to pass the error value from the body emission to the epilog when the
type is loadable, deferring the move into memory to the epilog block. This would
make the right behavior fall out of the existing implementation, but would require
a bit more invasive changes (pretty much everywhere that checks IndirectErrorReturn
would need to check a different-tracked AddressOnlyErrorType bit instead or in
addition). This change is more localized.
2024-04-17 14:13:42 -07:00