Commit Graph

295 Commits

Author SHA1 Message Date
Doug Gregor
2a01fc9d78 [Function builders] Run syntactic diagnostics for function bodies.
When a function body has had a function builder applied to it, make
sure that we run all of the syntactic diagnostics for expressions and
statements within the body.

Fixes rdar://problem/64493626.
2020-06-24 16:08:51 -07:00
Doug Gregor
f1febc2d52 [Constraint system] Lift PatternBindingDecl into SolutionApplicationTarget.
Generalize the code used to generate constraints and apply solutions to
PatternBindingDecls so that it is handled directly by the constaint
system and solution, respectively, rather than as part of the function
builder transform. No functionality change, but this is a cleaner
abstraction.
2020-06-05 22:51:18 -07:00
Doug Gregor
b1493413ab [Constraint system] Generalize recording of pattern binding entry targets.
Rather than storing the record of each pattern binding entry's solution
application targets as part of an applied function builder, store them
within the constraint system and solution using a newly-generalized
form of SolutionApplicationTargetsKey.
2020-06-05 22:51:18 -07:00
Doug Gregor
f55e7643fa [Constaint system] Add a predicate for when to check closures in enclosing expr
Introduce a new predicate, shouldTypeCheckInEnclosingExpression(), to
determine when the body of a closure should be checked as part of the
enclosing expression rather than separately, and use it in the various
places where "hasSingleExpressionBody()" was used for that purpose.
2020-06-03 22:48:58 -07:00
Anthony Latsis
9fd1aa5d59 [NFC] Pre- increment and decrement where possible 2020-06-01 15:39:29 +03:00
Doug Gregor
2fc2b15753 [Function builders] Align buildDo() implementation with the pitch.
Rather than passing the result of buildBlock() into buildDo(), follow
the (better) design from the function builders pitch by passing in the
components from the block directly into buildDo(). This means that
buildDo() will need to take separate parameters for each component,
but allows buildDo() to treat the components separately.
2020-05-29 15:28:58 -07:00
Doug Gregor
bf7eea08da [Function builders] Infer function builder from a protocol requirement.
Allow a protocol requirement for a function or property to declare
a function builder. A witness to such a protocol requirement will
infer that function builder when all of the following are two:
* The witness does not explicitly adopt a function builder
* The witness is declared within the same context that conforms to the
protocol requirement (e.g., same extension or primary type declaration)
* The witness's body does not contain a "return" statement (since those
disable the function builder transform).
2020-05-24 23:18:18 -07:00
Saleem Abdulrasool
ad3ea02e7a Merge pull request #31627 from compnerd/unreachable-coverage
sprinkle `llvm_unreachable` for covered switches (NFC)
2020-05-07 15:26:12 -07:00
Doug Gregor
57ab2dc0af Merge pull request #31624 from DougGregor/function-builder-locator
[Function builders] Clean up locators in the builder transform.
2020-05-07 13:38:05 -07:00
Saleem Abdulrasool
09975d1253 sprinkle llvm_unreachable for covered switches (NFC)
Annotate the covered switches with `llvm_unreachable` to avoid the MSVC
warning which does not recognise the covered switches.  This allows us
to avoid a spew of warnings.
2020-05-07 11:05:35 -07:00
Doug Gregor
7f242e51e0 [Function builders] Clean up locators in the builder transform.
Now that statements can be locators, we can clean up several FIXMEs.
Also, add an appropriate ContextualType locator noticed by Pavel.
2020-05-07 10:44:14 -07:00
John McCall
5597b2f23c Fix for new use of CallExpr::Create 2020-05-06 12:24:13 -04:00
John McCall
a518e759d9 WIP for a different syntax for multiple trailing closures
that allows arbitrary `label: {}` suffixes after an initial
unlabeled closure.

Type-checking is not yet correct, as well as code-completion
and other kinds of tooling.
2020-05-06 01:56:40 -04:00
Pavel Yaskevich
d06126da3b [Parser] Add support for multiple trailing closures syntax
Accept trailing closures in following form:

```swift
foo {
  <label-1>: { ... }
  <label-2>: { ... }
  ...
  <label-N>: { ... }
}
```

Consider each labeled block to be a regular argument to a call or subscript,
so the result of parser looks like this:

```swift
foo(<label-1>: { ... }, ..., <label-N>: { ... })
```

Note that in this example parens surrounding parameter list are implicit
and for the cases when they are given by the user e.g.

```swift
foo(bar) {
  <label-1>: { ... }
  ...
}
```

location of `)` is changed to a location of `}` to make sure that call
"covers" all of the transformed arguments and parser result would look
like this:

```swift
foo(bar,
   <label-1>: { ... }
)
```

Resolves: rdar://problem/59203764
2020-05-06 01:56:40 -04:00
Pavel Yaskevich
5cea9b9849 [AST] Add support for multiple trailing closures to the parser/expressions 2020-05-06 01:56:40 -04:00
Doug Gregor
19e234f54a [Function builders] Add for...in loop support via buildArray().
Extend function builders with support for for..in loops, such as

   for person in contacts {
     "Hello \(person.name)"
   }

The loop will be (eagerly) executed and all results will be collected
into an array. That array will be passed to a function `buildArray` to
produce the result from the loop. Specifically, the above will be
translated to the following when used with a function builder type
named `FunctionBuilder`,, where all $ names are introduced by the
compiler and are not user-visible:

    let $a1: $T1
    var $a2: [$T2] = []
    for person in contacts {
      let $a3: $T3
      let $a4 = FunctionBuilder.buildExpression("Hello \(person.name)")
      $a3 = FunctionBuilder.buildBlock($a4)
      $a2.append($3)
    }
    $a1 = FunctionBuilder.buildArray($a2)

where `$a1` is the result of the for-each loop.
2020-05-04 14:22:31 -07:00
Robert Widmann
0342855e50 [NFC] Debride Pattern.h of Implicit Tri-State
Remove all of this in favor of explicit constructors to preserve the one-liners, or distribute the setImplicit() calls to the callsites if necessary.
2020-04-30 22:03:55 -07:00
Robert Widmann
a6fc9b3679 Merge pull request #31253 from CodaFi/casting-call
Strip TypeExpr of its TypeLoc
2020-04-28 09:45:53 -07:00
Robert Widmann
09db2902d2 Strip TypeExpr of its TypeLoc
Remove duplication in the modeling of TypeExpr. The type of a TypeExpr
node is always a metatype corresponding to the contextual
type of the type it's referencing. For some reason, the instance type
was also stored in this TypeLoc at random points in semantic analysis.

Under the assumption that this instance type is always going to be the
instance type of the contextual type of the expression, introduce
a number of simplifications:

1) Explicit TypeExpr nodes must be created with a TypeRepr node
2) Implicit TypeExpr nodes must be created with a contextual type
3) The typing rules for implicit TypeExpr simply opens this type
2020-04-23 17:04:38 -07:00
Anthony Latsis
74252028ca AST: Rename getFullName -> getName on ValueDecl & MissingMemberDecl 2020-04-23 05:16:55 +03:00
Owen Voorhees
43e2d107e1 [SE-0276] Implement multi-pattern catch clauses
Like switch cases, a catch clause may now include a comma-
separated list of patterns. The body will be executed if any
one of those patterns is matched.

This patch replaces `CatchStmt` with `CaseStmt` as the children
of `DoCatchStmt` in the AST. This necessitates a number of changes
throughout the compiler, including:
- Parser & libsyntax support for the new syntax and AST structure
- Typechecking of multi-pattern catches, including those which
  contain bindings.
- SILGen support
- Code completion updates
- Profiler updates
- Name lookup changes
2020-04-04 09:28:26 -07:00
Robert Widmann
987cd55f50 [NFC] Drop llvm::Expected from Evaluation Points
A request is intended to be a pure function of its inputs. That function could, in theory, fail. In practice, there were basically no requests taking advantage of this ability - the few that were using it to explicitly detect cycles can just return reasonable defaults instead of forwarding the error on up the stack.

This is because cycles are checked by *the Evaluator*, and are unwound by the Evaluator.

Therefore, restore the idea that the evaluate functions are themselves pure, but keep the idea that *evaluation* of those requests may fail. This model enables the best of both worlds: we not only keep the evaluator flexible enough to handle future use cases like cancellation and diagnostic invalidation, but also request-based dependencies using the values computed at the evaluation points. These aforementioned use cases would use the llvm::Expected interface and the regular evaluation-point interface respectively.
2020-03-26 23:08:02 -07:00
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
ce97d22f21 [Function builders] Add support for buildFinalResult().
When present in a function builder, buildFinalResult() will be called on
the value of the outermost block to form the final result of the closure.
This allows one to collapse the full function builder computation into
a single result without having to do it in each buildBlock() call.
2020-03-09 00:10:07 -07:00
Doug Gregor
3887498e55 [Constraint system] Diagnose @unknown cases in function builders. 2020-03-04 22:46:36 -08:00
Holly Borla
e3239ba5fc [ConstraintSystem] Bail out of applyFunctionBuilderBodyTransform if
there is a failure in constraint generation.
2020-03-03 19:32:06 -08:00
Doug Gregor
12f8b51921 Merge pull request #30189 from DougGregor/function-builders-switch-exhaustive
[Constraint solver] Check switch exhaustiveness in function builders
2020-03-03 18:48:39 -08:00
Doug Gregor
7ee33a920d [Constraint solver] Check switch exhaustiveness in function builders 2020-03-03 13:44:36 -08:00
Doug Gregor
8191aa4924 Merge pull request #30174 from DougGregor/function-builder-switch
[Constraint system] Implement switch support for function builders.
2020-03-03 12:34:08 -08:00
Doug Gregor
ea8d143f64 [Constraint system] Introduce a one-way constraint for a switch subject.
The normal type checking of switch statements checks the switch subject
first, without context, then evaluates the cases. Introduce a one-way
constraint into the type checking of switch statements within function
builders to provide this same behavior. The difference can be observed
in code such as:

    enum E {
      case a
      case b(Int, String?)
    }

    enum E2 {
      case b(Int, String?)
    }

    func getSomeEnumOverloaded(_: Double) -> E { return .a }
    func getSomeEnumOverloaded(_: Int) -> E2 { return .b(0, nil) }

    func f() {
      switch getSomeEnumOverloaded(17) {
      case .a:  // error: no member named "a" in E2
        print("a")
      default:
        print("default")
      }
    }

When the subject expression `getSomeEnumOverloaded(17)` is resolved
without consider cases, it will select the second
`getSomeEnumOverloaded(_:)`, because the literal 17 prefers to be
an `Int`. The type checking of the first case would then fail because E2
does not contain a member named "a".

Prior to this change, the same expression within a function
builder would succeed in type checking, because the lack of case named
"a" within "E2" would make the second getSomeEnumOverloaded() unusable.

Making this code work by considering the cases along with the subject
expression is not unreasonable, and may be the right long term
direction for the language. However, it's a feature that should be
discussed separately, and the semantics should agree between function
builders and normal statements.

Big thanks to John McCall for noting the missing one-way constraint!
2020-03-03 08:51:26 -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
Holly Borla
87bb7755c2 Merge pull request #30101 from hborla/dynamic-replacement-type-erasure
[Sema] Implement type erasure for dynamic replacement.
2020-02-28 09:37:33 -08:00
Holly Borla
3cdc30ffeb [Sema] Support type erasure for dynamic replacement in function
builders.
2020-02-27 09:01:16 -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
141f3e7f07 [Constraint system] Expand SolutionApplicationTarget to StmtConditions.
Handle StmtCondition as part of SolutionApplicationTarget, so we can
generate constraints from it and rewrite directly as part of a solution,
rather than open-coding the operation in the function builder transform.
2020-02-25 13:47:26 -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
3f2f79a699 [Constraint system] Fold pattern variable binding into constraint gen.
Rather than re-walk the pattern to create type bindings for the variables
that show up in the pattern, assign types to each of the variables as part
of constraint generation for the pattern. Only do this in contexts
where we will need the types, e.g., function builders.
2020-02-25 08:51:56 -08:00
Hamish Knight
1a9764e6d7 [CS] Remove SubExpressionDiagnostics option 2020-02-19 07:43:59 -08:00
Doug Gregor
5e28c7c886 [Constraint System] Move bindVariablesInPattern into the constraint system.
This general notion of wiring up the types of variables that occur
within a pattern to the types in the produced pattern type is useful
outside of function builders, too.
2020-02-13 10:51:26 -08:00
Doug Gregor
08315b102d Merge pull request #29786 from DougGregor/function-builders-let-decls
Allow initialized let/var declarations in function builders.
2020-02-12 20:50:28 -08:00
Doug Gregor
d4cd5e0ebc Merge pull request #29801 from DougGregor/constraint-solver-rewrite-target
[Constraint system] Factor out application to a SolutionApplicationTarget
2020-02-12 20:24:41 -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
7f9029071d [Constraint system] Adopt rewriteTarget for function builder transform.
When applying a function builder to a closure to produce the final,
type-checked closure, use the new rewriteTarget() so it’s performed on
a per-target basis. Use this to eliminate some duplicating in the handling
of return types.
2020-02-12 17:51:47 -08:00
Doug Gregor
151fc79264 Merge pull request #29770 from DougGregor/builder-transform-node-types
[Constraint solver] Fix handling of node types for function builder application
2020-02-11 17:21:16 -08:00
Doug Gregor
4c98b31031 [Constraint solver] Apply solution to the system before builder transform.
This makes sure we can find information in the constraint system during
application. Fixes rdar://problem/59239224
2020-02-11 15:14:44 -08:00
Robert Widmann
d2360d2e8c [Gardening] dyn_cast -> isa 2020-02-07 16:09:31 -08:00
Holly Borla
778f8941ee [MiscDiagnostics] Walk into the body of a non single-statement closure
if the closure had a function builder transform applied.

This way, function builder closures can have syntactic restrictions
diagnosed the same way as other expressions.
2020-02-04 16:29:02 -08:00
Doug Gregor
3981a68a76 Merge pull request #29626 from DougGregor/function-builders-single-expr-closures-return
[Constraint solver] Fix function builders with single-expression closures
2020-02-03 23:10:51 -08:00
Doug Gregor
f8eee50310 [Constraint solver] Fix function builders with single-expression closures
Fix a few related issues involving the interaction with
single-expression closures:

* A single-expression closure can have a "return" in it; in such
cases, disable the function-builder transform.
* Have the function builder constraint generator look through the
"return" statement in a single-expression closure the same way as
solution application does

Fixes rdar://problem/59045763, where we rejected some well-formed code
involving a single-expression closure with a "return" keyword.
2020-02-03 17:52:44 -08:00
Pavel Yaskevich
7453d53e48 [TypeChecker/BuilderTransform] Switch to use hasLValueType instead of is<LValueType> to cover all cases where load is expected 2020-02-03 12:40:28 -08:00