Commit Graph

214 Commits

Author SHA1 Message Date
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
Doug Gregor
14be78d54d Remove -(enable|disable)-function-builder-one-way-constraints
Remove the staging flags for unidirectional constraints in function
builders. We're not going back!
2019-10-14 21:22:28 -07:00
Doug Gregor
87b5df7333 [Constraint system] Abstract the record of an applied function builder.
std::pair and std::tuple are a bad, bad drug. NFC, but helps with
future refactoring.
2019-10-11 10:31:27 -07:00
Rintaro Ishizaki
8bd9fde575 Revert "[code-completion] Disable diagnostics in @functionBuilder bodies"
This reverts commit c6eade1c44.
2019-08-30 15:25:12 -07:00
Doug Gregor
7aecca09af [One-way constraints] Don’t inject one-way constraints into buildEither calls
We need both sides of a buildEither constraint to be unified, so don’t
inject one-way constraints on the inputs to buildEither.
2019-08-13 17:45:29 -07:00
Doug Gregor
be73a9d641 [Function builders] Add one-way constraints when applying function builders
When we transform each expression or statement in a function builder,
introduce a one-way constraint so that type information does not flow
backwards from the context into that statement or expression. This
more closely mimics the behavior of normal code, where type inference
is per-statement, flowing from top to bottom.

This also allows us to isolate different expressions and statements
within a closure that's passed into a function builder parameter,
reducing the search space and (hopefully) improving compile times for
large function builder closures.

For now, put this functionality behind the compiler flag
`-enable-function-builder-one-way-constraints` for testing purposes;
we still have both optimization and correctness work to do to turn
this on by default.
2019-08-13 12:38:46 -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
db4c7d2d4c Fill in source locations in implicit function builder expressions
to satisfy the code-coverage instrumentation.

rdar://51612977
2019-07-18 19:36:02 -04:00
Doug Gregor
1aa19b7a47 [Type checker] Fold typeCheckFunctionBuilderFuncBody() so it isn't so special
Instead of being a completely separate body type-checking pass, refactor
this function so it does the function builder transform on the body, then
continues with the rest of typeCheckFunctionBodyUntil() as normal.
2019-07-12 17:10:04 -07:00
Ben Langmuir
c6eade1c44 [code-completion] Disable diagnostics in @functionBuilder bodies
When performing code-completion inside the body of a @functionBuilder
closure/function, set the flag to suppress diagnostics. This works
around a big performance problem in some complex bodies that do not
typecheck, which is typical during code-completion. A real-world example
with SwitfUI went from ~50 seconds to 0.5. We do not disable diagnostics
in general because the diagnostic paths provide falback types that are
useful to code-completion.

rdar://52356229
2019-07-02 07:33:14 -07:00
John McCall
5aa0330cec Merge pull request #25926 from rjmccall/function-builder-func-opaque-result
Support opaque result types when applying a function builder to a func
2019-07-01 21:51:38 -04:00
John McCall
faa3e3483f Support opaque result types when applying a function builder to a func. 2019-07-01 17:42:06 -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
b4cdbc05a6 Move the core builder-transform logic into its own file. 2019-06-11 18:58:11 -07:00