Commit Graph

317 Commits

Author SHA1 Message Date
Sima Nerush
6ab831043d SIL 2023-12-03 21:51:40 -08:00
Doug Gregor
cfe2b3c87d [Typed throws] Implement support for do throws(...) syntax
During the review of SE-0413, typed throws, the notion of a `do throws`
syntax for `do..catch` blocks came up. Implement that syntax and
semantics, as a way to explicitly specify the type of error that is
thrown from the `do` body in `do..catch` statement.
2023-12-02 07:37:47 -08:00
Hamish Knight
49ad980b86 [Profiler] Map regions for error-throwing AST nodes
Map a counter for the error branch of a given
potentially-throwing expression, and subtract it
from the following region count.

rdar://34244637
2023-11-16 17:28:57 +00:00
Doug Gregor
927e2420a0 [Typed throws] Handle closure reabstraction
This peephole optimization in SILGen requires us to use the thrown
error for the context of a closure type rather than the thrown error
for the closure AST node itself.
2023-11-08 12:08:01 -08:00
Doug Gregor
0ba605a4b9 [Typed throws] Implement reabstraction thunks that change the error
Introduce SILGen support for reabstractions thunks that change the
error, between indirect and direct errors as well as conversions
amongst error types (e.g., from concrete to `any Error`).
2023-11-07 11:39:56 -08:00
Slava Pestov
204bb0c2f2 SILGen: Lowering 'try?' and 'try!' with typed throws 2023-10-31 22:55:48 -04:00
Slava Pestov
079c5c4a1c SILGen: Support for 'throw' and 'try_apply' with indirect error result 2023-10-31 16:58:54 -04:00
Doug Gregor
2d4e8fda3e [Typed throws] Compute and use the caught error type of a do..catch block.
The type that is caught by the `catch` clauses in a `do..catch` block is
determined by the union of the thrown error types in the `do`
statement. Compute this type and use it for the catch clauses. This
does several things at once:

* Makes the type of the implicit `error` be a more-specific concrete
type when all throwing sites throw that same type
* When there's a concrete type for the error, one can use patterns
like `.cancelled`
* Check that this error type can be rethrown in the current context
* Verify that SIL generation involving do..catch with typed errors
doesn't require any existentials.
2023-10-04 17:20:36 -07:00
Doug Gregor
b6b999abd4 [Typed throws] Basic SIL lowering and SIL generation for typed throws
Lower the thrown error type into the SIL function type. This requires
very little code because the thrown error type was already modeled as
a SILResultInfo, which carries type information. Note that this
lowering does not yet account for error types that need to passed
indirectly, but we will need to do so for (e.g.) using resilient error
types.

Teach a few places in SIL generation not to assume that thrown types
are always the existential error type, which primarily comes down to
ensuring that rethrow epilogues have the thrown type of the
corresponding function or closure.

Teach throw emission to implicitly box concrete thrown errors in the
error existential when needed to satisfy the throw destination. This
is a temporary solution that helps translate typed throws into untyped
throws, but it should be replaced by a better modeling within the AST
of the points at which thrown errors are converted.
2023-09-29 10:51:55 -07:00
Hamish Knight
41dc6e2e04 [SILGen] Emit unreachable for uninhabited if/switch expr branches
If we have an uninhabited branch, emit it as an
ignored expr followed by an unreachable.
Previously we would omit the unreachable and rely
on the SILOptimizer to infer it, but we ought to
just emit it here. Also check `isUninhabited()`
instead of `isStructurallyUninhabited` since this
better matches what we allow in Sema. For tuples
of uninhabited values, we can do a regular
initialization without issue.
2023-09-22 18:44:43 +01:00
Kuba Mracek
a3ee08fbc9 [embedded] Use cond_fail in throw-as-traps mode 2023-09-21 07:17:19 -07:00
Kuba Mracek
a31c3388e4 [embedded] Add a temporary flag that turns throws into traps so that programs that use throwing can at least be compiled for now 2023-09-19 22:00:51 -07:00
Hamish Knight
6ee44f09b4 Introduce then statements
These allow multi-statement `if`/`switch` expression
branches that can produce a value at the end by
saying `then <expr>`. This is gated behind
`-enable-experimental-feature ThenStatements`
pending evolution discussion.
2023-09-01 14:32:14 +01:00
Zak Kent
3657cbafc9 [SILGen] Move all top-level emission code to SILGenTopLevel.cpp 2023-08-08 11:25:11 -07:00
Zak Kent
7dae2e6905 [SILGen] Implement SILGenTopLevel
Implement SILGenTopLevel, a class that walks a file
run in script mode to generate all toplevel code
at once.
2023-08-08 11:25:11 -07:00
Slava Pestov
9ebb5f2e03 AST: Rename VarDecl::getType() to VarDecl::getTypeInContext()
This is a futile attempt to discourage future use of getType() by
giving it a "scary" name.

We want people to use getInterfaceType() like with the other decl kinds.
2023-08-04 14:19:25 -04:00
Joe Groff
c52ae08c7d SILGen: Don't reuse the Initialization across branches of an if or switch expression.
`Initialization` is stateful and not meant to be emitted into multiple times across different contexts.
If emitting into an initialization causes it to be split or aborted, that will carry over into
further uses of the initialization. This was happening during `if` and `switch` expression
emission, leading to miscompiles or compiler crashes. Fix this by saving only the buffer when
we prepare emission for a statement expression, and creating the initialization in the scope
where the expression for a branch actually gets emitted. Fixes rdar://112213253.
2023-07-14 14:21:57 -07:00
John McCall
e14f2bc0c7 [NFC] Add a method to just ask if a tuple AP vanishes under substitution 2023-06-29 19:39:51 -04:00
Erik Eckstein
6b1697eb06 use new llvm::Optional APIs to fix deprecation warnings 2023-06-28 14:28:38 +02:00
John McCall
acbd4a6022 Fix the emission of closures into reabstracted contexts with
variadic-tuple results.  There are three parts to this.

First, fix the emission of indirect result parameters to do a
proper abstraction-pattern-aware traversal of tuple patterns.
There was a FIXME here and everything.

Second, fix the computation of substituted abstraction
patterns to properly handle vanishing tuples.  The previous code
was recursively destructuring tuples, but only when it saw a
tuple as the substituted type, which of course breaks on vanishing
tuples.

Finally, fix the emission of returns into vanishing tuple
patterns by allowing the code to not produce a TupleInitialization
when the tuple pattern vanishes.  We should always get a singleton
element initializer in this case.

Fixes rdar://109843932, plus a closely-related test case for
vanishing tuples that I added myself.
2023-06-14 21:29:22 -04:00
Andrew Trick
2f200a6caa [move-only] Fix drop_deinit OSSA lowering
drop_deinit ultimately only affects the semantics of its
destroy_value. Avoid generating releases for destroys in which the
deinit has been dropped. Instead, individually release the members.
2023-06-06 09:17:53 -07:00
Kavon Farvardin
3e4bc82aa8 rename _forget to discard; deprecate _forget
SE-390 concluded with choosing the keyword discard rather than forget for
the statement that disables the deinit of a noncopyable type. This commit
adds parsing support for `discard self` and adds a deprecation warning for
`_forget self`.

rdar://108859077
2023-05-08 21:42:19 -07:00
Kavon Farvardin
578da4949d disallow "non-trivial" stored properties when using forget
We haven't quite got the semantics we want implemented
for `discard` aka `_forget` statements. Allowing people
to use `_forget` in noncopyable types that have stored
properties that require destruction will not let us
implement it the way we'd like in the future without
source break. But, if the type only has "trivial" stored
properties with a no-op destruction, like `Int`, then we
can still provide utility for users like FileDescriptor
who just want to disable the deinit and have nothing
fancy stored in the type itself.

rdar://108877261
2023-05-05 19:05:04 -07:00
Adrian Prantl
158772c2ab Rebase SILScope generation on top of ASTScope.
This patch replaces the stateful generation of SILScope information in
SILGenFunction with data derived from the ASTScope hierarchy, which should be
100% in sync with the scopes needed for local variables. The goal is to
eliminate the surprising effects that the stack of cleanup operations can have
on the current state of SILBuilder leading to a fully deterministic (in the
sense of: predictible by a human) association of SILDebugScopes with
SILInstructions. The patch also eliminates the need to many workarounds. There
are still some accomodations for several Sema transformation passes such as
ResultBuilders, which don't correctly update the source locations when moving
around nodes. If these were implemented as macros, this problem would disappear.

This necessary rewrite of the macro scope handling included in this patch also
adds proper support nested macro expansions.

This fixes

rdar://88274783

and either fixes or at least partially addresses the following:

rdar://89252827
rdar://105186946
rdar://105757810
rdar://105997826
rdar://105102288
2023-04-04 15:20:11 -07:00
John McCall
debc8d9ebd [NFC] Move forEachTupleElement to use a generator 2023-03-22 22:04:36 -04:00
John McCall
9ab4dc494c [NFC] Add better APIs for parallel destructuring of orig+subst types
As I've been iterating on this work, I've been gradually mulling these
over, and I think this is the way to go for now.  These should make it
a lot less cumbersome to write these kinds of traversals correctly.

The intent is to the sunset the existing expanded-components stuff
after I do a similar pass for function parameters.
2023-03-16 00:19:30 -04:00
John McCall
239777aacb Fix parameter binding for tuples containing pack expansions
More missing infrastructure.  In this case, it's really *existing*
missing infrastructure, though; we should have been imploding tuples
this way all along, given that we're doing it in the first place.

I don't like that we're doing all these extra tuple copies.  I'm not
sure yet if they're just coming out of SILGen and eliminated immediately
after in practice; maybe so.  Still, it should be obvious that they're
unnecessary.
2023-03-09 02:28:29 -05:00
John McCall
81d9e6865a Add a couple convenience APIs for working with abstraction patterns 2023-03-07 03:15:31 -05:00
John McCall
157be3420c Implement the callee side of returning a tuple containing a pack expansion.
This required quite a bit of infrastructure for emitting this kind of
tuple expression, although I'm not going to claim they really work yet;
in particular, I know the RValue constructor is going to try to explode
them, which it really shouldn't.

It also doesn't include the caller side of returns, for which I'll need
to teach ResultPlan to do the new abstraction-pattern walk.  But that's
next.
2023-03-06 04:26:18 -05:00
Kavon Farvardin
f41ed5926b implement the forget statement
Currently, this is staged in as `_forget`,
as part of SE-390. It can only be used on
`self` for a move-only type within a consuming
method or accessor. There are other rules, see
Sema for the details.

A `forget self` really just consumes self and
performs memberwise destruction of its data.
Thus, the current expansion of this statement
just reuses what we inject into the end of a
deinit.

Parsing of `forget` is "contextual".
By contextual I mean that we do lookahead to
the next token and see if it's identifier-like.
If so, then we parse it as the `forget` statement.
Otherwise, we parse it as though "forget" is an
identifier as part of some expression.

This way, we won't introduce a source break for
people who wrote code that calls a forget
function.

This should make it seamless to change it from
`_forget` to `forget` in the future.

resolves rdar://105795731
2023-02-28 21:15:17 -08:00
Hamish Knight
a40f1abaff Introduce if/switch expressions
Introduce SingleValueStmtExpr, which allows the
embedding of a statement in an expression context.
This then allows us to parse and type-check `if`
and `switch` statements as expressions, gated
behind the `IfSwitchExpression` experimental
feature for now. In the future,
SingleValueStmtExpr could also be used for e.g
`do` expressions.

For now, only single expression branches are
supported for producing a value from an
`if`/`switch` expression, and each branch is
type-checked independently. A multi-statement
branch may only appear if it ends with a `throw`,
and it may not `break`, `continue`, or `return`.

The placement of `if`/`switch` expressions is also
currently limited by a syntactic use diagnostic.
Currently they're only allowed in bindings,
assignments, throws, and returns. But this could
be lifted in the future if desired.
2023-02-01 15:30:18 +00:00
swift-ci
fd6fd76dae Merge pull request #42513 from jsoref/spelling-silgen
Spelling silgen
2022-11-09 23:28:43 -08:00
Josh Soref
9a6bf46c0f Spelling silgen
* actually
* arbitrary
* cargo-culted
* clazz
* constrained
* continuation
* coordinator
* coroutine
* derivative
* destroyer
* given
* have
* imported
* initialization
* items
* necessarily
* occurring
* omitting
* overridden
* parameter
* possible
* predecessor
* preparation
* resilience
* should
* struct
* that
* the
* throwing
* unexpectedly
* uniqueness
* using
* value
* villain

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-11-09 21:44:17 -05:00
Hamish Knight
bfa3a3f4f3 [Profiler] Avoid passing null node to loadProfilerCount
This will become an assertion failure in a future
commit.
2022-10-13 19:42:37 +01:00
Ikko Ashimine
d82d26b03f [SILGen] Fix typo in SILGenStmt.cpp
refering -> referring
2022-08-01 11:40:03 +09:00
Pavel Yaskevich
b7860ea055 [TypeChecker] Split for-in sequence into parsed and type-checked versions 2022-05-30 23:17:41 -07:00
Pavel Yaskevich
2c8bfee225 [SILGen] Unify handling of for-in and async for-in statements 2022-05-30 23:17:41 -07:00
Pavel Yaskevich
86165291aa [TypeChecker] Change the way for-in statement in type-checked
Instead of asking SILGen to build calls to `makeIterator` and
`$generator.next()`, let's synthesize and type-check them
together with the rest of for-in preamble. This greatly simplifies
interaction between Sema and SILGen for for-in statements.
2022-05-30 23:17:41 -07:00
Konrad `ktoso` Malawski
d96cb1dbaf [SIL] Allow giving debug names to SILBasicBlocks 2022-02-01 14:35:03 +09:00
Joe Groff
4d18573da0 SILGen: Continue emitting local decls after hitting a return.
Instead of short-circuiting out of emitBlockStmt if the SIL insertion point
has become unreachable (because, for instance, all paths through the function
have returned), iterate through the remaining elements and process
non-PatternBindingDecl declarations, to ensure that local functions and types
get emitted. Fixes rdar://87039628.
2022-01-10 16:16:05 -08:00
Robert Widmann
5bbd126179 Redo The Notes For "Uninhabited" Parameter Types
The use of the term 'uninhabited' does not make sense outside of formal type theoretic contexts. In Swift, we also do not use this term in a standard way - hence the term "structurally uninhabited" since we only consider products and sums eligible for the check. (Aside: We do not do exponentials because... well, Swift's type system implements Harper's "typerec" operator and as a consequence parametricity is just _not a thing_). I digress...

So, improve upon the old diagnostic in two ways:
1) Do away with 'uninhabited' - instead, mention that it's either an enum or a tuple with an enum in it that 'has no cases'
2) Since the SIL parameter convention flattens all tuples, point directly at the offending uninhabited element type

rdar://83600669
2021-09-27 20:17:28 -07:00
Adrian Prantl
8bb292e4d9 Enter a new debug scope for every let binding.
This fixes an ambiguity (that leads to a crash further down the pipeline) when
compiling optional unwrap bindings that bind the same variable name.

rdar://73490741
(cherry picked from commit 173c0b4657)
2021-09-17 08:41:39 -07:00
Joe Groff
fdc0e08d60 SILGen: Emit literal closures at the abstraction level of their context.
Literal closures are only ever directly referenced in the context of the expression they're written in,
so it's wasteful to emit them at their fully-substituted calling convention and then reabstract them if
they're passed directly to a generic function. Avoid this by saving the abstraction pattern of the context
before emitting the closure, and then lowering its main entry point's calling convention at that
level of abstraction. Generalize some of the prolog/epilog code to handle converting arguments and returns
to the correct representation for a different abstraction level.
2021-09-09 13:42:02 -07:00
Joe Groff
3abe16f40f Revert "SILGen: Emit literal closures at the abstraction level of their context. [take 2]" (#39228) 2021-09-09 11:53:43 -05:00
Joe Groff
43506a29a2 SILGen: Emit literal closures at the abstraction level of their context.
Literal closures are only ever directly referenced in the context of the expression they're written in,
so it's wasteful to emit them at their fully-substituted calling convention and then reabstract them if
they're passed directly to a generic function. Avoid this by saving the abstraction pattern of the context
before emitting the closure, and then lowering its main entry point's calling convention at that
level of abstraction. Generalize some of the prolog/epilog code to handle converting arguments and returns
to the correct representation for a different abstraction level.
2021-09-07 11:55:29 -07:00
Holly Borla
86e1014399 Revert " SILGen: Emit literal closures at the abstraction level of their context." 2021-08-18 09:03:23 -07:00
Joe Groff
309500d4bf SILGen: Emit literal closures at the abstraction level of their context.
Literal closures are only ever directly referenced in the context of the expression they're written in,
so it's wasteful to emit them at their fully-substituted calling convention and then reabstract them if
they're passed directly to a generic function. Avoid this by saving the abstraction pattern of the context
before emitting the closure, and then lowering its main entry point's calling convention at that
level of abstraction. Generalize some of the prolog/epilog code to handle converting arguments and returns
to the correct representation for a different abstraction level.
2021-08-16 09:39:19 -07:00
Holly Borla
bd80342a4b [SILGen] Record local auxiliary decls when a parameter is emitted, and
emit those auxiliary decls inside the function body brace statement.

This generalizes the old code to work for parameters to any kind of
function (e.g. initializers).
2021-08-12 13:56:05 -07:00
Robert Widmann
2c936fb7f6 Ignore All 'Unreachable' Decls That Don't Carry Expressions
We were just ignoring types here, but local functions don't matter. In
fact, if a local decl survives to SILGen, we only really care if it
carries some expression or statement itself - so pattern bindings are
the real stars here.

Re-resolves rdar://76269551 and SR-14449
2021-07-22 14:59:45 -07:00
Joe Groff
79fb05b362 Concurrency: Hop back to the previous executor after actor calls.
Tasks shouldn't normally hog the actor context indefinitely after making a call that's bound to
that actor, since that prevents the actor from potentially taking on other jobs it needs to
be able to address. Set up SILGen so that it saves the current executor (using a new runtime
entry point) and hops back to it after every actor call, not only ones where the caller context
is also actor-bound.

The added executor hopping here also exposed a bug in the runtime implementation while processing
DefaultActor jobs, where if an actor job returned to the processing loop having already yielded
the thread back to a generic executor, we would still attempt to make the actor give up the thread
again, corrupting its state.

rdar://71905765
2021-03-18 11:47:50 -07:00