It is a somewhat common case where folks are accidentally referring to an
instance member with the Type as the base. This forms a curried member,
which then produced head scratching error messages downstream.
Now that the prep work has gone in, the first part of this is now
straight-forward to fix: simply check for this case and diagnose it
with a custom error, which makes it more clear what the mistake was.
The other half of this problem (tracked by 22108559) affects cases where
the method you're calling takes a single argument. This isn't fixed
yet, but I'm adding a testcase for it anyway.
the code to be actually readable since it unnests it greatly), and call it
both before and after argument type validation. This allows us to capture
many more structural errors than before, leading to much better diagnostics
in a lot of cases. This also fixes the specific regressions introduced by
96a1e96.
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.
These APIs are from the Swift 1.2 => Swift 2.0 transition, and are not
relevant anymore.
Removing them reduces the surface area of the library that needs to be
reviewed.
Previously we erroneously complained:
error: cannot invoke 'contains' with an argument list of type '(String)'
now we correctly complain:
error: unexpected non-void return value in void function
This enhances CSDiags to use "getTypeOfMember" when analyzing method
candidates that are applied to a known base type. Using it allows us to
substitute information about the base, resolving archetypes that exist in
subsequent argument positions. In the testcase, this means that we use
information about Set<String> to know that the argument to "contains" is a
String.
This allows us to generate much better diagnostics in some cases, and works
around some limitations in the existing stuff for handling unresolved
archetypes. One unfortunate change is the notes in Misc/misc_diagnostics.swift.
Because we don't track argument lists very well, we are flattening an argument
list that is actually ((Int,Int)) into (Int, Int) so we get a bogus looking
diagnostic. This was possible before this patch though, it is just one
more case that triggers the issue.
The original issue has long since been fixed, but we were now producing:
error: cannot subscript a value of type 'UnsafePointer<Int8>'
which is pretty obviously wrong. The problem is that when ranking subscript
decl candidates, CSDiags was using TC.isConvertibleTo to evaluate whether the
actual base type is compatible with the base type of a subscript decl. This
was failing when the base was generic, because the logic isn't opening
archetypes. Instead of incorrectly deciding that they are incompatible, just
decide we don't know if an archetype is present. This allows us to generate
good errors in situation like this.
A crash in CSDiag that happened when we were unconditionally looking at the
getter of a subscript. This failed on UnsafeMutablePointer because it only
has addressors, not getter/setters.
and probably others.
When we're type-checking a failed ApplyExpr that has an overload set that
prevents getting a specific type to feed into the initial typechecking of
the argument list, ranking can often narrow down the list of candidates
further, to the point where there is only one candidate left or where all
candidates agree that one argument is wrong.
In this case, re-type-check the subexpr with the expected type. In the case of
rdar://problem/22243469 we now produce:
t.swift:6:11: error: invalid conversion from throwing function of type '() throws -> ()' to non-throwing function type '() -> Void'
process {
^
instead of:
t.swift:6:3: error: cannot invoke 'process' with an argument list of type '(() throws -> ())'
process {
^
t.swift:6:3: note: overloads for 'process' exist with these partially matching parameter lists: (UInt, fn: () -> Void)
process {
^
Which is a heck of a lot less specific. Similarly, in the testcase from rdar://23550816, instead
of producing:
takeTwoFuncsWithDefaults { $0 + 1 }
error: cannot invoke 'takeTwoFuncsWithDefaults' with an argument list of type '((Int -> Int)?)'
note: expected an argument list of type '(f1: (Int -> Int)?, f2: (String -> String)?)'
we now produce:
error: cannot convert value of type '_ -> Int' to expected argument type '(String -> String)?'
which is a lot closer to what we want to complain about.
This case attempts to diagnose assignment into an invalid lvalue which only had
a computable type due to a fixit that the constraint solver was assuming. In this
situation, don't diagnose the invalid lvalue at all, diagnose the required fix.
When passing a contextual type to a call, if we have a scalar element
initializing a varargs parameter list, we need to use the varargs element type
contextually. Fixing this improves some confusing diagnostics.
call expression onto a callee when it was a binary expression. Doing this
requires improving the diagnostics for when the contextual result type is
incompatible with all candidates, but that is general goodness all around.
This fixes:
<rdar://problem/22333090> QoI: Propagate contextual information in a call to operands
and improves a number of diagnostics where the problem is that an operator
is used in a context that expects a type that it cannot produce.
Swift SVN r31891
- Enhance the branch new argument label overload diagnostic to just
print the argument labels that are the problem, instead of printing
the types inferred at the argument context. This can lead to confusion
particularly when an argument label is missing. For example before:
error: argument labels '(Int)' do not match any available overloads
note: overloads for 'TestOverloadSets.init' exist with these partially matching parameter lists: (a: Z0), (value: Int), (value: Double)
after:
error: argument labels '(_:)' do not match any available overloads
note: overloads for 'TestOverloadSets.init' exist with these partially matching parameter lists: (a: Z0), (value: Int), (value: Double)
Second, fix <rdar://problem/22451001> QoI: incorrect diagnostic when argument to print has the wrong type
by specifically diagnosing the problem when you pass in an argument to a nullary function. Before:
error: cannot convert value of type 'Int' to expected argument type '()'
after:
error: argument passed to call that takes no arguments
print(r22451001(5))
^
Swift SVN r31795
OverloadedDeclRefExpr or OverloadedMemberRefExpr when there is no
contextual type information available. The problem is that CSRanking
will take a look at the various solutions formed by picking each member
of the set, and will arbitrarily rank them against each other based on
how specific the candidates are. The problem with this is that the
constraints on the candidates are being resolved by UnresolvedType, which
means that we end up accidentally pruning the overload set too early.
This can lead to incorrect diagnostics that *should* have been ambiguity
diagnostics, such as the example in TypeCoercion/overload_noncall.swift.
It also is causing me other grief as I'm trying to make the call analysis
diagnostics more specific and the lack of the proper candidates is
triggering badness.
The actual change to the testsuite here is minor, but not all good. It will
be re-won by later changes.
Swift SVN r31744
fixit hint in CSDiags instead of being a FixKind. This resolves a number of issues with
it, particularly that it didn't actually check to see if the function in question takes
a () argument or not.
This fixes:
<rdar://problem/21692808> QoI: Incorrect 'add ()' fixit with trailing closure
among other issues.
Swift SVN r31728
forced conversion to "_ -> T" if it will refine the type otherwise found by
doing a non-contextual type check. This allows us to diagnose calls to
non-function values with more specificity, e.g. adding another case were we
recommend "do" when using bare braces.
Swift SVN r31726
specifies some # of arguments but the closureexpr itself disagrees. This is
step #1 to resolving
<rdar://problem/22333281> QoI: improve diagnostic when contextual type of closure disagrees with arguments
Swift SVN r31715
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
diagnostics around invalid references to unavailable declarations, resolving
<rdar://problem/22491394> References to unavailable decls sometimes diagnosed as ambiguous
and a complex case exposed working through rdar://21928143.
Swift SVN r31587
We type check expressions using a contextual purpose of CTP_CalleeResult
without a specific contextualType, because we install the contextual type
as a conversion constraint. This formerly failed the assertion expecting
that you have to have a type if you have a purpose, because parenexprs
propagated their contextual info down.
In addition to making the assertion in TypeCheckConstraints.cpp more
lenient, change visitCallExpr to just pass down the purpose directly
instead of installing it in its ExprTypeCheckListener.
Swift SVN r31575
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
automatically pass down TypeCheckExprFlags::AllowUnresolvedTypeVariables
IFF we have no contextual type. This gives us UnresolvedTypes in more cases,
which improves diagnostics in various situations, and also simplifies
CSDiag. The change to misc_diagnostics.swift is a particularly nice progression.
Swift SVN r31406
where we type check the destination first, then apply its type to the source.
This allows us to get diagnostics for assignments that are as good as PBD
initializers and other cases.
Swift SVN r31404
argument list mismatches, and diagnose them with a very specific error when
they occur in member lookups. This fixes
<rdar://problem/22356434> QoI: Missing diagnostic for invalid arguments passed to enum case constructor
where before we'd produce:
ee.swift:5:16: error: type of expression is ambiguous without more context
let list: E = .C(wrongLabel: 0)
~^~~~~~~~~~~~~~~~
now we produce:
ee.swift:1:17: error: incorrect argument label in call (have 'wrongLabel:', expected 'label:')
let list: E = .C(wrongLabel: 0)
^~~~~~~~~~~
label
I think that unresolved member exprs now get good diagnostics in all cases that they have
a contextual type, but of course there are lots more cases where we're not getting a
contextual type.
Swift SVN r31402
information and use this to improve the UnresolvedMemberExpr errors.
The notable problem remaining is that we don't handle problems involving
argument labels.
Swift SVN r31378