mismatches in function types.
This improves the diagnostic in cases where we have argument-to-parameter
conversion failures or contextual type mismatches due to inout attribute
mismatches.
In the specific case of sr-69, and in a bunch of other code where
errors arise involving generic function application, better type
constraint failure diagnoses are being masked by the overly
conservative implementation in evaluateCloseness(). If the actual arg
types didn’t exactly match the parameter types, we’d always diagnose a
non-specific arguments-don’t-match error instead of allowing discovery
of better errors from the constraint system.
This commit adds more cases where evaluateCloseness will return
CC_ExactMatch, specifically in application of functions with one or
more arguments of a single archetype, like `func min<T: Comparable>(T,
T) -> T`. It verifies that the actual argument type
isSubstitutableFor() the archetype, and that all such arguments are of
the same type. Anything more complicated than that still has the
previous behavior of not matching at all.
I think the final answer here ought to be to make a constraint system
with type variables for any archetypes, add appropriate constraints to
the actual args and then see if the system can solve all the argument
constraints at once. That’s because the next most complicated set of
things to handle in the stdlib are things like `func -<T:
Strideable>(lhs: T, rhs: T.Stride)` where generic argument types depend
on each other. I tried attacking that, but it was too big of a bite for
me to manage all at once. But there are FIXME’s here to try that again
at some point.
New tests for SR-69 are at the end of deduction.swift, and the rest of
the test changes are generally improved deduced diagnoses. I think the
changed diagnoses in materializable_restrictions.swift is the only one
which is worse instead of better, and that’s just because the previous
general message mentioned `inout` basically accidentally. Opportunity
for further improvement (a new diagnosis maybe) there.
Validation tests run and passed.
overloaded argument list mismatches. We printed them in simple cases
due to "Failure" detecting them in trivial situations. Instead of
doing that, let CSDiags do it, which allows us to pick things out of
overload sets and handle the more complex cases well.
This is a progression across the board except for a couple of cases
where we now produce "cannot convert value of type 'whatever' to
expected argument type '(arglist)'", this is a known issue that I'll
fix in a subsequent commit.
Introduce a new "OpenedGeneric" locator for when openGeneric opens a generic
decl into a plethora of constraints, and use this in CSDiags to distinguish
whether a constraint refers to an Expr as a whole or an "aspect" of the constraint.
Use that information in FailureDiagnosis::diagnoseGeneralConversionFailure
to know whether (as a fallback) we can correctly re-typecheck an entire expr
to obtain a missing type. If we are talking about an aspect of the expr, then
this clearly won't work.
The upshot of this is that where we previously compiled the testcase in 22519983
to:
y.swift:31:9: error: type '(inout _) -> Bool' does not conform to protocol 'RawRepresentable'
let a = safeAssign
^
we now produce the somewhat more useful:
y.swift:31:9: error: argument for generic parameter 'T' could not be inferred
let a = safeAssign
^
y.swift:27:6: note: in call to function 'safeAssign'
func safeAssign<T: RawRepresentable>(inout lhs: T) -> Bool {
^
Swift SVN r31620
use that contextual type to guide typechecking of the callee. This allows us to
propagate that type through generic constraints effectively, making us produce
much more useful diagnostics within closures taking methods like "map" (for
example).
This fixes:
<rdar://problem/20491794> QoI closures: Error message does not tell me what the problem is
Specifically, running the testcase:
enum Color { case Unknown(description: String) }
let xs: (Int, Color) = [1,2].map({ ($0, .Unknown("")) })
produces: error: cannot convert call result type '[_]' to expected type '(Int, Color)'
Changing that to:
let xs: [(Int, Color)] = [1,2].map({ ($0, .Unknown("")) })
produces: error: missing argument label 'description:' in call
... with a fixit to introduce the label.
This also fixes most of 22333090, but we're only using this machinery for CallExprs
so far, not for operators yet.
Swift SVN r31484
the regressions that r31105 introduced in the validation tests, as well as fixing a number
of other validation tests as well.
Introduce a new UnresolvedType to the type system, and have CSDiags start to use it
as a way to get more type information out of incorrect subexpressions. UnresolvedType
generally just propagates around the type system like a type variable:
- it magically conforms to all protocols
- it CSGens as an unconstrained type variable.
- it ASTPrints as _, just like a type variable.
The major difference is that UnresolvedType can be used outside the context of a
ConstraintSystem, which is useful for CSGen since it sets up several of them to
diagnose subexpressions w.r.t. their types.
For now, our use of this is extremely limited: when a closureexpr has no contextual
type available and its parameters are invalid, we wipe them out with UnresolvedType
(instead of the previous nulltype dance) to get ambiguities later on.
We also introduce a new FreeTypeVariableBinding::UnresolvedType approach for
constraint solving (and use this only in one place in CSDiags so far, to resolve
the callee of a CallExpr) which solves a system and rewrites any leftover type
variables as UnresolvedTypes. This allows us to get more precise information out,
for example, diagnosing:
func r22162441(lines: [String]) {
lines.map { line in line.fooBar() }
}
with: value of type 'String' has no member 'fooBar'
instead of: type of expression is ambiguous without more context
This improves a number of other diagnostics as well, but is just the infrastructural
stepping stone for greater things.
Swift SVN r31130
as a way to get more type information out of incorrect subexpressions. UnresolvedType
generally just propagates around the type system like a type variable:
- it magically conforms to all protocols
- it CSGens as an unconstrained type variable.
- it ASTPrints as _, just like a type variable.
The major difference is that UnresolvedType can be used outside the context of a
ConstraintSystem, which is useful for CSGen since it sets up several of them to
diagnose subexpressions w.r.t. their types.
For now, our use of this is extremely limited: when a closureexpr has no contextual
type available and its parameters are invalid, we wipe them out with UnresolvedType
(instead of the previous nulltype dance) to get ambiguities later on.
We also introduce a new FreeTypeVariableBinding::UnresolvedType approach for
constraint solving (and use this only in one place in CSDiags so far, to resolve
the callee of a CallExpr) which solves a system and rewrites any leftover type
variables as UnresolvedTypes. This allows us to get more precise information out,
for example, diagnosing:
func r22162441(lines: [String]) {
lines.map { line in line.fooBar() }
}
with: value of type 'String' has no member 'fooBar'
instead of: type of expression is ambiguous without more context
This improves a number of other diagnostics as well, but is just the infrastructural
stepping stone for greater things.
Swift SVN r31105
and use it in the diagnostics path (only!) to revisit active constraints that
are left in the system after a failure is found. This improves a number of
otherwise sad diagnostics in the testsuite and resolves rdar://22083115.
The one QoI regression (in throwing_functions.swift) is now tracked by 22158167.
Swift SVN r31027
other constraints intentionally ripped off, tell the recursive solution that
we can tolerate an ambiguous result. The point of this walk is not to
produce a concrete type for the subexpression, it is to expose any structural
errors within that subsystem that don't depend on the contextual constraints.
Swift SVN r30917
Add a new option, TVO_MustBeMaterializable, to
TypeVariableType::Implementation, and set it for type variables
resulting from opening a generic type. This solution isn't complete (we
don't yet copy the non-materializable bit on unification of type
variables, and it's possible to bind a must-be-materializable type
variable to a type with type variables that later get bound to
non-materializable types) but it addresses all reported crashes for this
issue.
<rdar://problem/20807269> Crash in non-materializable type
Swift SVN r28792