Consider following example:
```swift
enum E {
case foo((x: Int, y: Int))
case bar(x: Int, y: Int)
}
func test(e: E) {
if case .foo(let x, let y) = e {}
if case .bar(let tuple) = e {}
}
```
Both of `if case` expressions have to be supported:
1. `case .foo(let x, let y) = e` allows a single tuple
parameter to be "destructured" into multiple arguments.
2. `case .bar(let tuple) = e` allows to match multiple
parameters with a single tuple argument.
Resolves: rdar://problem/60061646
Since constraint system now handles pattern matching it has
to preverse label matching semantics which existed in original
code: if pattern element has a label it has to match the one
in the tuple type it's matched against.
Resolves: rdar://problem/60048356
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.
all cases of missing generic parameters.
In `ComponentStep::take` when there are no bindings or disjunctions, use hole
propagation to default remaining free type variables that aren't for generic
parameters and continue solving. Rather than using a defaultable constraint for
holes, assign a fixed type directly when we have no bindings to try.
Patch up all the places that are making a syntactic judgement about the
isInvalid() bit in a ValueDecl. They may continue to use that query,
but most guard themselves on whether the interface type has been set.
This is an amalgam of simplifications to the way VarDecls are checked
and assigned interface types.
First, remove TypeCheckPattern's ability to assign the interface and
contextual types for a given var decl. Instead, replace it with the
notion of a "naming pattern". This is the pattern that semantically
binds a given VarDecl into scope, and whose type will be used to compute
the interface type. Note that not all VarDecls have a naming pattern
because they may not be canonical.
Second, remove VarDecl's separate contextual type member, and force the
contextual type to be computed the way it always was: by mapping the
interface type into the parent decl context.
Third, introduce a catch-all diagnostic to properly handle the change in
the way that circularity checking occurs. This is also motivated by
TypeCheckPattern not being principled about which parts of the AST it
chooses to invalidate, especially the parent pattern and naming patterns
for a given VarDecl. Once VarDecls are invalidated along with their
parent patterns, a large amount of this diagnostic churn can disappear.
Unfortunately, if this isn't here, we will fail to catch a number of
obviously circular cases and fail to emit a diagnostic.
Use the adjacencies implied by the constraints of a node rather than looking
at the "adjacency" list, and try to simplify this code path a bit. The
diagnostic change is because we are now uniformly recording the
members of the equivalence class.
* Make sure that base and unwrapped types aren't null
* Don't allocate `ForceOptional` fix if nothing has been unwrapped
in `simplifyApplicableFnConstraint`
* Add sugar reconstitution support to `FailureDiagnostic::resolveType`
* Format diagnostics a bit better
Try to fix constraint system in a way where member
reference is going to be defined in terms of its use,
which makes it seem like parameters match arguments
exactly. Such helps to produce solutions and diagnose
failures related to missing members precisely.
These changes would be further extended to diagnose use
of unavailable members and other structural member failures.
Resolves: rdar://problem/34583132
Resolves: rdar://problem/36989788
Resolved: rdar://problem/39586166
Resolves: rdar://problem/40537782
Resolves: rdar://problem/46211109
Since constraint solver has been improved to diagnose more problems
via "fixes", sometimes applying fixes might lead to producing solutions
which are completely ambiguous when compared to each other, and/or are
incomparable, which leads to `findBestSolutions` erasing all of them
while trying to compute best "partial" solution, which is incorrect.
Resolves: rdar://problem/42678836
so that they must result in an optional type.
Add constraint locator path for identifying constraints/variables that are part of the convert type passed into the system.
When we determine that an optional value needs to be unwrapped to make
an expression type check, use notes to provide several different
Fix-It options (with descriptions) rather than always pushing users
toward '!'. Specifically, the errors + Fix-Its now looks like this:
error: value of optional type 'X?' must be unwrapped to a value of
type 'X'
f(x)
^
note: coalesce using '??' to provide a default when the optional
value contains 'nil'
f(x)
^
?? <#default value#>
note: force-unwrap using '!' to abort execution if the optional
value contains 'nil'
f(x)
^
!
Fixes rdar://problem/42081852.
This fixes two easy cases where we would go exponential in type
checking tuple literals.
Instead of generating a conversion to a single type variable (which
results in one large constraint system), we generate a conversion ot
the same type that appears in the initializer expression (which for
tuples is a tuple type, which naturally splits the constraint system).
I experimented with trying to generalize this further, but ran into
problems getting it working, so for now this will have to do.
Fixes rdar://problem/20233198.
When type-checking switch statements with patterns let's
check if we have an optional type and try to see if the case
exists in its base type, if so we can suggest a fix-it.
Resolves: rdar://problem/32241441
This lets you match `case .foo` when `foo` resolves to any static member, instead of only a `case`, albeit without the exhaustiveness checking and subpattern capabilities of proper cases. While we're here, adjust the type system we set up for unresolved patterns embedded in expressions so that we give better signal in the error messages too.
Emit a warning for optionals that are implicitly converted to Any, and
add fixits giving options to:
- Add '??' with a default value after
- Force-unwrap the optional with '!'
- Explicitly cast to 'as Any' to silence the warning
This covers diagnostics aspect of SE-0140.
rdar://problem/28196843
From the Swift documentation:
"If you define an optional variable without providing a default value,
the variable is automatically set to nil for you."
almost always the case that the user didn't know what the rules are between
single expression and multistatement closures, and they often don't know how to
fix the problem.
Address this by doing some heroics when we detect this situation. We now go dive
into the closure body, type check the explicit returns within it, and can usually
divine the right answer. When we do that, generate a fixit hint that generates a
modification to the existing signature, or synthesizes the entire signature from
scratch. This addresses:
<rdar://problem/22123191> QoI: multi-line closure with failure to infer result type should add a fixit
Previously:
error: generic parameter 'T' could not be inferred
now:
error: unable to infer closure return type in current context
There is still more to do, but this fixes:
<rdar://problem/23570873> QoI: Poor error calling map without being able to infer "U" (closure result inference)
TypeCheckPattern was able to take the path checking if `Optional.None`
should be renamed to lowercase `Optional.none` and if this wasn't
necessary still failed but without generating a diagnostic.
Now it always provides a diagnostic when failing.
This fixes SR-2057.
change includes both the necessary protocol updates and the deprecation
warnings
suitable for migration. A future patch will remove the renamings and
make this
a hard error.