With the change to include `SmallVector.h` directly in `LLVM.h` rather
than forward declaring in the only case it matters (ie. Clang <= 5),
these fixes are no longer needed. Since defaulted version is preferred
when there's no better choice (which is presumably the case if that's
how they were originally added), use it instead. Some uses were instead
changed to add `llvm::` so remove that too.
Since result builder is just an AST transformation, the result
of a successful transform could be cache and reused with a different
`$__builderSelf` type.
The transform changes closure body into a multi-statement closure
with all of the implicit result builder calls and type-checks it
like a regular closure.
There are a couple of result builder specific changes mentioned below,
otherwise the logic to generate constraints and apply solutions is
unchanged:
- Placeholder variable: A variable declaration that doesn't have a
type deduced and infers it from its first use. If such a variable
has an initializer, it would be type-checked during solution application.
- TypeJoinExpr - an implicit expression that refers to a "join" variable
and a set of expressions that should all produce the same type that
becomes a type of a "join" variable.
Previously for-in target was actually an expression target, which means
certain type-checking behavior. These changes make it a standalone target
with custom behavior which would allow solver to introduce implicit
`makeIterator` and `next` calls and move some logic from SILGen.
For all of the `build*` calls, let's use a special variable declaration
`$builderSelf` which refers to a type of the builder used. This allows
us to remove hacks related to use of `TypeExpr`. Reference to `$builderSelf`
is replaced with `TypeExpr` during solution application when the builder
type is completely resolved.
We record fixes while solving normal expressions for code completion and we should do the same when solving result builders if we are reporting the solutions to completion callbacks.
Enables SE-0348 `buildPartialBlock` feature by default. The frontend flag is kept for compatibility with existing clients, but is now ineffective.
Also includes some improved error messages for invalid result builder call sites.
This hooks up call argument position completion to the typeCheckForCodeCompletion API to generate completions from all the solutions the constraint solver produces (even those requiring fixes), rather than relying on a single solution being applied to the AST (if any).
Co-authored-by: Nathan Hawes <nathan.john.hawes@gmail.com>
This PR implements support for `buildPartialBlock` as proposed in https://forums.swift.org/t/pitch-buildpartialblock-for-result-builders/55561. This is similar to the existing support for `buildBlock(combining:into:)` except that it also checks for availability when deciding whether to fall back to plain old `buildBlock`.
> In the result builder transform, the compiler will look for static members `buildPartialBlock(first:)` and `buildPartialBlock(accumulated:next:)` in the builder type. If the following conditions are met:
> - Both methods `buildPartialBlock(first:)` and `buildPartialBlock(accumulated:next:)` exist.
> - The availability of the enclosing declaration is greater than or equal to the availability of `buildPartialBlock(first:)` and `buildPartialBlock(accumulated:next:)`.
When there's no available `buildPartialBlock` to call and there's no `buildBlock`, emit a diagnostic:
```console
result builder 'Builder' does not implement any 'buildBlock' or a combination of 'buildPartialBlock(first:)' and 'buildPartialBlock(accumulated:next:)' with sufficient availability for this call site
```
Allow a user-defined `buildBlock(combining:into:)` to combine subexpressions in a block pairwise top to bottom. To use `buildBlock(_combining:into:)`, the user also needs to provide a unary `buildBlock(_:)` as a base case. The feature is being gated under frontend flag `-enable-experimental-pairwise-build-block`.
This will enable use cases in `RegexBuilder` in experimental declarative string processing, where we need to concatenate tuples and conditionally skip captureless regexes. For example:
```swift
let regex = Regex {
"a" // Regex<Substring>
OneOrMore("b").capture() // Regex<(Substring, Substring)>
"c" // Regex<Substring>
Optionally("d".capture()) // Regex<(Substring, Substring?)>
} // Regex<Tuple3<Substring, Substring, Substring?>>
let result = "abc".firstMatch(of: regex)
// MatchResult<(Substring, Substring, Substring?)>
```
In this example, patterns `"a"` and `"c"` have no captures, so we need to skip them. However with the existing result builder `buildBlock()` feature that builds a block wholesale from all subexpressions, we had to generate `2^arity` overloads accounting for any occurrences of captureless regexes. There are also other complexities such as having to drop-first from the tuple to obtain the capture type. Though these features could in theory be supported via variadic generics, we feel that allowing result builders to pairwise combine subexpressions in a block is a much simpler and potentially more useful approach.
With `buildBlock(_combining:into:)`, the regex builders can be defined as the following, assuming we have variadic generics:
```swift
enum RegexBuilder {
static func buildBlock() -> Regex<Substring>
static func buildBlock<Match>(_ x: Regex<Match>) -> Regex<Match>
static func buildBlock<
ExistingWholeMatch, NewWholeMatch, ExistingCaptures..., NewCaptures...
>(
_combining next: Regex<(NewWholeMatch, NewCaptures...)>,
into combined: Regex<(ExistingWholeMatch, ExistingCaptures...)>
) -> Regex<Substring, ExistingCaptures..., NewCaptures...>
}
```
Before we have variadic generics, we can define overloads of `buildBlock(_combining:into:)` for up to a certain arity. These overloads will be much fewer than `2^arity`.
* [ConstraintSystem] NFC: Rename `openOpaqueTypeRec` and make `openOpaqueType` private for individual types
* [ConstraintSystem] Require a contextual purpose for `openOpaqueType(Type, ...)`
Some of the contexts require special handling e.g. return type of a function
can only open directly declared opaque result type(s), this would be
implemented in a follow-up commit.
* [ConstraintSystem] Open only directly declared opaque types related to return statements
Re-establish a check which would only open opaque types directly
declared in the return type of a function/accessor declaration,
otherwise constraint system would end up with type variables it
has no context for if the type had generic parameters.
Resolves: rdar://81531010
* [TypeResolver][TypeChecker] Add support for structural opaque result types
* [TypeResolver][TypeChecker] Clean up changes that add structural opaque result types
There were a couple of places where we weren't
handling a nullptr return from one of the visitor
methods. Change the methods to return NullablePtr
and add the missing null checks.
rdar://81228221
While determining whether result builder body is correct, allow
pre-check phase to look into single-statement closures because
their bodies participate in type-check and would fail constraint
generation if they contain `ErrorExpr`s, so it's better to determine
that the body is invalid early and skip result builder application.
Resolves: rdar://79746785