Introduce an experimental mode (behind the flag
`experimental-one-way-closure-params`) that places one-way
constraints between closure parameter types and references to those
parameters within the body of the closure. The intent here is to
break up constraint systems further, potentially improving type
checking performance and making way for larger closure bodies to be
supported.
This is a source-breaking change when the body of a single-expression
closure is used to determine the parameter types. One obvious example
is when there is no contextual type, e.g.,
let _ = { $0 + 1 }
this type-checks today because `1` becomes `Int`, which matches the
`+` overload with the type `(Int, Int) -> Int`, determining the
parameter type `Int` for the closure. Such code would not type-check
with one-way constraints.
Single-expression closures have always been traversed differently
from multi-statement closures. The former were traversed as if the
expression was their only child, skipping the BraceStmt and implicit
return, while the later was traversed as a normal BraceStmt.
Unify on the latter treatment, so that traversal
There are a few places where we unintentionally relied on this
expression-as-child behavior. Clean those up to work with arbitrary
closures, which is an overall simplification in the logic.
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.
Introduce `repairByUsingRawValueOfRawRepresentableType` which is used for
assignment, argument-to-parameter conversions and contextual mismatches.
It checks whether `from` side is a raw representable type and tries
to match `to` side to its `rawValue`.
Also extract logic common for `repairByUsingRawValueOfRawRepresentableType`
and `repairByExplicitRawRepresentativeUse` into `isValueOfRawRepresentable`.
Introduce `repairByExplicitRawRepresentativeUse` which is used for
assignment, argument-to-parameter conversions and contextual mismatches.
It checks whether `to` side is a raw representable type and tries
to match `from` side to its `rawValue`.
Impact of cases where pointer types mismatch after implict optional
wrap(s) should be higher than mismatch alone.
Distinguishing that helps to disambiguate following case (and other similar ones)
without using ranking:
```swift
func foo(_: UnsafePointer<Int>) {}
func foo(_: UnsafePointer<Int>?) {}
func test(_ ptr: UnsafePointer<Float>) {
foo(ptr)
}
```
We currently leave a key path constraint unsolved
if one of its components hasn't yet had its
overload resolved. However, for e.g a missing
member component, the overload type variable will
be bound to a hole and an overload will never be
resolved.
Tweak the logic to consider the key path constraint
trivially solved if one of its components has been
marked as a hole, which will allow the key path
type itself to be marked as a hole.
Resolves SR-12437 & SR-12823.
Resolves rdar://62201037.
Detect situation when it's impossible to determine types for
closure parameters used in the body from the context. E.g.
when a call closure is associated with refers to a missing
member.
```swift
struct S {
}
S.foo { a, b in } // `S` doesn't have static member `foo`
let _ = { v in } // not enough context to infer type of `v`
_ = .foo { v in } // base type for `.foo` couldn't be determined
```
Resolves: [SR-12815](https://bugs.swift.org/browse/SR-12815)
Resolves: rdar://problem/63230293
When simplifying a keypath constraint with a function type binding, single-parameter functions have the parameter type and the return type matched against the keypath root and value; whereas multiple-parameter functions cause an ambiguous failure (in `simplifyKeyPathConstraint`).
Resolves rdar://problem/57930643
If argument is immutable, with or without explicit `&`, let's
diagnose that as mutability problem because suggesting
to add `&` to immutable declaration is not the best possible fix.
Resolves: rdar://problem/62428353
The current approach for type-checking single trailing closures
is to scan backwards from the end of the parameter list, looking
for something that can be passed a closure. This generalizes that
to perform label-matching in reverse on any later trailing closures,
then pick up from that point when trying to place the unlabeled
trailing closure.
The current approach is really not a good language rule, but changing
it as much as we'd really like will require evolution approval and a
source break, so we have to be cautious.
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.
If this is an attempt to fetch members through key path dynamic member lookup
let's not try to apply any property wrapper related fixes because modifying
base type would not change the result.
Resolves: [SR-12520](https://bugs.swift.org/browse/SR-12520)
Resolves: rdar://problem/61911108
All callers can trivially be refactored to use ModuleDecl::lookupConformance()
instead. Since this was the last flag in ConformanceCheckOptions, we can remove
that, too.
Rename `addNewFailingConstraint` to
`recordFailedConstraint`, and call into it
whenever a constraint fails, instead of setting
`failedConstraint`. This ensures that
`-debug-constraints` will always log the constraint
that failed a given scope.
In addition, introduce `retireFailedConstraint`
to cover the common case of retiring a constraint
that just failed.