Previously we could allow some invalid coercions to
sneak past Sema. In most cases these would either
cause crashes later down the pipeline or
miscompiles. However, for coercions between
collections, we emitted somewhat reasonable code
that performed a force cast.
This commit aims to preserve compatibility with
those collection coercions that previously
compiled, and emits a warning telling the user to
use either 'as?' or 'as!' instead.
Pull the entirety of type checking for for-each statement headers (i.e., not the
body) into the constraint system, using the normal SolutionApplicationTarget-based
constraint generation and application facilities. Most of this was already handled
in the constraint solver (although the `where` filtering condition was not), so
this is a smaller change than it looks like.
Currently `simplifyAppliedOverloads` depends on
the order in which constraints are simplified,
specifically that a lookup constraint for a
function gets simplified before the applicable
function constraint. This happens to work out
just fine today with the order in which we
re-activate constraints, but I'm planning on
changing that order.
This commit changes the logic such that it it's no
longer affected by the order in which constraints
are simplified. We'll now run it when either an
applicable function constraint is added, or a new
bind overload disjunction is added. This also
means we no longer need to run it potentially
multiple times when simplifying the applicable fn.
Introduce `SK_Hole` which is used to count a number of "holes" in
a given solution. It is used to distinguish solutions with fewer holes.
Also it makes it possible to check whether a solution has holes but
no fixes, which is an issue and such solution shouldn't be applied
to AST.
Make sure that we're resolving types and patterns using the
PatternBindingDecl context, both for the type resolver context and the
contextual pattern used for pattern resolution.
Fixes a regression with implicitly-unwrapped options reported as
SR-11998 / rdar://problem/58455441.
For some reason, the changed caller in CS wasn't actually going to use any of the types in the constraint system from the entrypoint it was calling. Switch over to using the constraint-system-based entrypoint so we can pick up expression types consistently. Then, move the TypeChecker entrypoint onto ConstraintSystem to reduce the duplication here.
The remaining callers of buildCheckedRefExpr should be migrated.
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.
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.
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.
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.
Generate a complete set of constraints for EnumElement patterns, e.g.,
case let .something(x, y)
Most of the complication here comes from the implicit injection of optionals,
e.g., this case can be matched to an optional of the enum type of which
`something` is a member. To effect this change, introduce a locator for
pattern matching and use it to permit implicit unwrapping during member
lookup without triggering an error.
Note also labels are dropped completely when performing the match,
because labels can be added or removed when pattern matching. Label
conflict are currently diagnosed as part of coercePatternToType, which
suffices so long as overloading cases based on argument labels is not
permitted.
The primary observable change from this commit is in diagnostics: rather
than diagnostics being triggered by `TypeChecker::coercePatternToType`,
diagnostics for matching failures here go through the diagnostics machinery
of the constraint solver. This is currently a regression, because
there are no custom diagnostics for pattern match failures within the
constraint system. This regression will be addressed in a subsequent
commit; for now, leave those tests failing.
Currently constraint solver is only capable of detecting universally unavailable
overloads but that's insufficient because it's still possible to pick a contextually
unavailable overload choice which could be better than e.g. generic overload, or
one with defaulted arguments, marked as disfavored etc.
Let's introduce `ConstraintSystem::isDeclUnavailable` which supports both universal
and contextual unavailability and allow constraint solver to rank all unavailable
overload choices lower than any other possible choice(s).
Resolves: rdar://problem/59056638
There were changes due to the StringRef to std::string conversion, changes
in the Debug Info DIBuilder::createModule API, and a drop in the using for
PointerUnion4 since PointerUnion is now a variadic template and will do in its
place.
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.
It's done by first retrieving all generic parameters from each solution,
filtering boundings into distrinct set and diagnosing any differences.
For example:
```swift
func foo<T>(_: T, _: T) {}
func bar(x: Int, y: Float) {
foo(x, y)
}
```
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.