Commit Graph

26 Commits

Author SHA1 Message Date
Doug Gregor
f0530d0a77 [Function builders] Support buildOptional(_:) in lieu of buildIf(_:).
Line up with the function builders pitch, which uses buildOptional(_:)
to build optional values.
2020-03-09 21:48:15 -07:00
Doug Gregor
c962e48b35 [Function builders] Test with an lvalue subject 2020-03-04 22:46:36 -08:00
Doug Gregor
4b43573693 [Constraint system] Implement switch support for function builders.
Implement support for switch statements within function builders. Cases can
perform arbitrary pattern matches, e.g.,

    tuplify(true) { c in
      "testSwitchCombined"
      switch e {
      case .a:
        "a"
      case .b(let i, _?), .b(let i, nil):
        i + 17
      }
    }

subject to the normal rules of switch statements. Cases within function
builders cannot, however, include “fallthrough” statements, because those
(like “break” and “continue”) are control flow.

The translation of performed for `switch` statements is similar to that of
`if` statements, using `buildEither(first:)` and `buildEither(second:)` on
the function builder type.

This is the bulk of switch support, tracked by rdar://problem/50426203.
2020-03-02 17:25:25 -08:00
Doug Gregor
8482516412 [Constraint system] Properly deal with "as" patterns.
Teach pattern matching involving "as" patterns to work properly in
function builders. The code almost handled this, but prematurely
prechecking expressions in patterns broke it.
2020-02-25 16:29:07 -08:00
Doug Gregor
4830c48960 [Constraint system] Support if let / if case in function builders.
Use the generalized constraint generation and binding for patterns to
introduce support for if-let and if-case in function builders, handling
arbitrary patterns.

Part of function builder generalization, rdar://problem/50426203.
2020-02-25 09:44:06 -08:00
Doug Gregor
2347829324 [Constraint System] Allow initialized let/var declarations in function builders.
Introduce support for initialized let/var declarations within function
builder closures, e.g.,

    let (a, b) = c()

We generate constraints for the declarations as elsewhere, but the types of
the declared variables (a and b in this case) are bound to the type of the
pattern by one-way constraints, to describe the flow of type information
through the closure.

Implements rdar://problem/57330696.
2020-02-12 17:51:48 -08:00
Doug Gregor
6238923e15 [Function builders] Support multiple Boolean conditions in 'if' statements
Generalize support for function builders to allow 'if' statements that
include multiple Boolean conditions, e.g., "if a, b, c, { ... }".
2020-01-23 17:04:17 -08:00
Doug Gregor
d0981292ab [Constraint generation] Collect all closure body references to type variables.
Collect all references to parameters whose types involve type variables,
including in closures that aren’t single-expression. This fixes a type
checker assertion that occurs when the constraint graph can get disconnected
with the combination of delayed constraint generation for single-expression
closures and the use of function builders.

Fixes rdar://problem/58695803.
2020-01-21 10:15:28 -08:00
Doug Gregor
8283a67648 Revert "Revert "Reimplement function builders as statement transformations."" 2020-01-21 10:07:20 -08:00
Doug Gregor
86c13d3c74 Revert "Reimplement function builders as statement transformations." 2020-01-17 15:52:49 -08:00
Doug Gregor
9853926cb2 [Function builders] Make sure we contextualize closures with builders applied.
We used to get this contextualization "for free" because closures that
had function builders applied to them would get translated into
single-expression closures. Now, we need to check for this explicitly.
2020-01-16 13:19:21 -08:00
Pavel Yaskevich
65adc18139 [ConstraintSystem] Delay constraint generation from single-statement closure body
Attempt to infer a closure type based on its parameters and body
and put it aside until contextual type becomes available or it
has been determined that there is no context.

Once all appropriate conditions are met, generate constraints for
the body of the closure and bind it the previously inferred type.

Doing so makes it possible to pass single-statement closures as
an argument to a function builder parameter.

Resolves: SR-11628
Resolves: rdar://problem/56340587
2020-01-14 00:09:32 -08:00
Doug Gregor
fd916f9db6 [Function builders] Add support for buildExpression().
If a function builder type has a static method buildExpression(), use
it to pass through each expression whose value will become part of the
final result. This is part of the function builders pitch that had not
yet been implemented.
2019-10-15 22:25:04 -07:00
Hamish Knight
dafcaeb5eb [CS] Simplify getCalleeDeclAndArgs
Now that we associate argument labels for key path
subscript components, remove the special logic for
it. In addition, we can now search for callees
directly by using `getCalleeLocator`, as it should
now be able to find all the correct callees that
`getCalleeDeclAndArgs` does.

By using `getCalleeLocator`, we now also correctly
resolve callees for operator calls, meaning that
we can now use them with function builders. In
addition, we no longer incorrectly resolve callees
for calls made on SubscriptExprs.

Resolves SR-11439 & SR-11440.
2019-09-10 12:06:35 +01:00
Doug Gregor
b4e80cfd90 [Constraint graph] Enable one-way constraints in function builders.
Enable one-way constraints by default for function builders, finishing
rdar://problem/50150793.
2019-08-19 22:49:15 -07:00
John McCall
33fbfafccb Function builders: pre-check the original closure body in-place.
Prior to this patch, we pre-checked the result of applying the function-builder transformation, but only when we hadn't already pre-checked the closure before.  This causes two problems to arise when the transformation is applied to the same closure along multiple branches of a disjunction.  The first is that any expressions that are synthesized by the transformation will not be pre-checked the second time through, which is a problem if we try to apply different builder types to the same closure (we do cache expressions for identical builder types).  The second is that the pre-check will rewrite sub-expressions in place *in the synthesized expression*, which means that top-level expressions in the original closure body (including `if` conditions) that are now nested in the synthesized expression will not be rewritten in the original closure and therefore will be encountered in their raw state the second time through.

This patch causes all expressions in the original closure body to be pre-checked before doing any other work.  We then pre-check the synthesized expression immediately before generating constraints for it in order to set up the AST appropriately for CSGen; this could be skipped if we just synthesized expressions the way that CSGen wants them, but that seems to be somewhat involved.

Pre-checking is safe to apply to an expression multiple times, so it's
fine if we take this path and then decide not to use a function builder.

I've also merged the check for `return` statements into this same walk, which was convenient.

Fixes rdar://53325810 at least, and probably also some bugs with applying different function builders to the same closure.
2019-07-23 01:50:31 -04:00
John McCall
d975e8ad3c Allow #if in function builders.
Dropping the IfConfigDecl is not a great implementation, but it'll work
well enough to unblock this code while we work to allow multi-statement
bodies in general.
2019-07-01 16:18:17 -04:00
John McCall
a183f762cd Address review feedback on the function-builders-on-funcs/vars patch. 2019-06-11 17:34:45 -07:00
John McCall
952eb9d8f9 Allow function-builder attributes on funcs and computed vars.
rdar://50150690
2019-06-11 17:34:45 -07:00
John McCall
83b5b2fa7d Support if-else chains on function builders.
A substantial amount of this patch goes towards trying to get at least
minimal diagnostics working, since of course I messed up the rule a few
times when implementing this.

rdar://50149837
2019-06-11 17:34:45 -07:00
Doug Gregor
7475bcd2ff [Function builders] Prescan closure bodies for a 'return' statement.
Since we short-circuit in the function builder application when we
hit something we cannot translate, relying on that visitor to
detect 'return' statements (which disable the application) is bogus.
Use a separate, earlier visitor to find 'return' statements consistently.

Fixes rdar://problem/50266341.
2019-06-11 17:34:45 -07:00
Doug Gregor
b7bbf4ca1a [Function builders] Allow uses of generic function builders.
Use the opened type from the callee declaration to open up references to
generic function builders that contain type parameters. This allows general
use of generic function builders.
2019-06-11 17:34:45 -07:00
Doug Gregor
c98f01705c [DSL] Allow function builders to opt in to "if" statements.
If a function builder contains a buildIf function, then "if" statements
will be supported by passing an optional of the "then" branch.
"if" statements with an "else" statement are unsupported at present.
2019-06-11 17:34:44 -07:00
Doug Gregor
ffd160162f [DSL] Allow function builders to opt in to "do" support via buildDo(). 2019-06-11 17:34:44 -07:00
Doug Gregor
6a3739ac65 Ensure that we use the right closure context for constraint generation. 2019-06-11 17:34:44 -07:00
Doug Gregor
a4301cc95b [Type checker] Transform multi-statement closures via function builders.
When calling a function whose parameter specifies a function builder
with a multi-statement closure argument, transform the closure into
a single expression via the function builder. Should the result
type checker, replace the closure body with the single expression.
2019-06-11 17:34:44 -07:00