Passing a function type to an @autoclosure param would always fail to
type check because of the attempt to decompose the parallel structure
of the two (both being functions). In this case, though, we don’t want
to do any such thing, we want to allow the ExprRewriter to explicitly
insert an AutoClosureExpr in coerceToType, as it would do with any
other non-function arg type.
Rearrange diagnoseGeneralConversionFailure to diagnose structural problems
even if we have some UnresolvedTypes floating around, then reject constraint
failures with UnresolvedTypes in them even harder. This keeps us giving
good errors about failures where we have a structural problem (with buried
irrelevant details) while not complaining about cases that are actually
ambiguous.
The end result of this is that we produce a lot better error messages in the
case of failed archetype inference. This also highlights the poor job we do
handling multi-stmt closureexprs...
This time, the issue is that TypeNullifier skips bodies of
multi-statement closures. However, ExprRewriter will type
happily pass them on to typeCheckClosureBody(). This could
trigger assertions. Fix this by skipping type checking of
multi-statement closures when diagnosing.
There seems to be a minor QoI regression in some test cases
that already looked pretty dodgy and/or had FIXMEs. However
I think its worth fixing a crash.
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.
Introduce a new constraint kind, BindParam, which relates the type of a
function parameter to the type of a reference to it from within the
function body. If the param type is an inout type, the ref type is an
lvalue type with the same underlying object type; otherwise the two
types must be the same. This prevents DeclRefExprs from being inferred
to have inout type in some cases.
<rdar://problem/15998821> Fail to infer types for closure that takes an inout argument
Swift SVN r32183
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
<rdar://problem/22333281> QoI: improve diagnostic when contextual type of closure disagrees with arguments
In the common case where someone doesn't care about the argument
list to a closure, we now generate a tailored error message with a
fixit to introduce the necessary "_,_ in " nonsense at the start
of the closure. IMO ideally we wouldn't require this, but until we
fix that type checker issue, we should at least give people the
obvious fix.
Swift SVN r31720
expr diagnosis stuff, giving us much better diagnostics on the cases in
expr/closure/closures.swift. This is part #2 of resolving
<rdar://problem/22333281> QoI: improve diagnostic when contextual type of closure disagrees with arguments
Swift SVN r31717
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
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
When CSGen was analyzing a DeclRefExpr reference, it was accidentally
applying some magic only to anonymous closure parameters, not named ones,
leading to a silent CSGen failure. Fix this by handling all closure parameters
the same way.
Swift SVN r31098
explicitly written and disagree with context, and when context provides a
non-explicitly written type that disagrees with the body of the closure.
Swift SVN r30984
using it to improve closure diagnostics by inferring the types of otherwise
untyped closure paramdecls from this context information. This
resolves:
<rdar://problem/20371273> Type errors inside anonymous functions don't provide enough information
producing
error: binary operator '==' cannot be applied to operands of type 'Int' and 'UInt'
note: overloads for '==' exist with these partially matching parameter lists: (UInt, UInt), (Int, Int)
and:
<rdar://problem/20978044> QoI: Poor diagnostic when using an incorrect tuple element in a closure
producing:
error: value of tuple type '(Int, Int)' has no member '2'
and probably a lot more. We're still limited from getting things like "foo.map {...}" because
we're not doing type subsitutions from the base into the protocol extension member.
Swift SVN r30971
diagnose problems inside of them instead of punting on them completely.
This leads to substantially better error messages in many cases, fixing:
<rdar://problem/19870975> Incorrect diagnostic for failed member lookups within closures passed as arguments ("(_) -> _")
<rdar://problem/21883806> Bogus "'_' can only appear in a pattern or on the left side of an assignment" is back
<rdar://problem/20712541> QoI: Int/UInt mismatch produces useless error inside a block
and possibly others. We are not yet capitalizing on available type information we do
have about closure exprs, so there are some cases where we produce
"error: type of expression is ambiguous without more context"
when this isn't strictly true, but this is still a huge step forward.
Swift SVN r30547
win from this other than simplification. Some minor wins are that we handle varargs
better and don't get extraneous ()'s in types in some cases.
Swift SVN r29729
If you want to make the parameter and argument label the same in
places where you don't get the argument label for free (i.e., the
first parameter of a function or a parameter of a subscript),
double-up the identifier:
func translate(dx dx: Int, dy: Int) { }
Make this a warning with Fix-Its to ease migration. Part of
rdar://problem/17218256.
Swift SVN r27715
The rule changes are as follows:
* All functions (introduced with the 'func' keyword) have argument
labels for arguments beyond the first, by default. Methods are no
longer special in this regard.
* The presence of a default argument no longer implies an argument
label.
The actual changes to the parser and printer are fairly simple; the
rest of the noise is updating the standard library, overlays, tests,
etc.
With the standard library, this change is intended to be API neutral:
I've added/removed #'s and _'s as appropriate to keep the user
interface the same. If we want to separately consider using argument
labels for more free functions now that the defaults in the language
have shifted, we can tackle that separately.
Fixes rdar://problem/17218256.
Swift SVN r27704
Most tests were using %swift or similar substitutions, which did not
include the target triple and SDK. The driver was defaulting to the
host OS. Thus, we could not run the tests when the standard library was
not built for OS X.
Swift SVN r24504
These changes make the following improvements to how we generate diagnostics for expression typecheck failure:
- Customizing a diagnostic for a specific expression kind is as easy as adding a new method to the FailureDiagnosis class,
and does not require intimate knowledge of the constraint solver’s inner workings.
- As part of this patch, I’ve introduced specialized diagnostics for call, binop, unop, subscript, assignment and inout
expressions, but we can go pretty far with this.
- This also opens up the possibility to customize diagnostics not just for the expression kind, but for the specific types
involved as well.
- For the purpose of presenting accurate type info, partially-specialized subexpressions are individually re-typechecked
free of any contextual types. This allows us to:
- Properly surface subexpression errors.
- Almost completely avoid any type variables in our diagnostics. In cases where they could not be eliminated, we now
substitute in "_".
- More accurately indicate the sources of errors.
- We do a much better job of diagnosing disjunction failures. (So no more nonsensical ‘UInt8’ error messages.)
- We now present reasonable error messages for overload resolution failures, informing the user of partially-matching
parameter lists when possible.
At the very least, these changes address the following bugs:
<rdar://problem/15863738> More information needed in type-checking error messages
<rdar://problem/16306600> QoI: passing a 'let' value as an inout results in an unfriendly diagnostic
<rdar://problem/16449805> Wrong error for struct-to-protocol downcast
<rdar://problem/16699932> improve type checker diagnostic when passing Double to function taking a Float
<rdar://problem/16707914> fatal error: Can't unwrap Optional.None…Optional.swift, line 75 running Master-Detail Swift app built from template
<rdar://problem/16785829> Inout parameter fixit
<rdar://problem/16900438> We shouldn't leak the internal type placeholder
<rdar://problem/16909379> confusing type check diagnostics
<rdar://problem/16951521> Extra arguments to functions result in an unhelpful error
<rdar://problem/16971025> Two Terrible Diagnostics
<rdar://problem/17007804> $T2 in compiler error string
<rdar://problem/17027483> Terrible diagnostic
<rdar://problem/17083239> Mysterious error using find() with Foundation types
<rdar://problem/17149771> Diagnostic for closure with no inferred return value leaks type variables
<rdar://problem/17212371> Swift poorly-worded error message when overload resolution fails on return type
<rdar://problem/17236976> QoI: Swift error for incorrectly typed parameter is confusing/misleading
<rdar://problem/17304200> Wrong error for non-self-conforming protocols
<rdar://problem/17321369> better error message for inout protocols
<rdar://problem/17539380> Swift error seems wrong
<rdar://problem/17559593> Bogus locationless "treating a forced downcast to 'NSData' as optional will never produce 'nil'" warning
<rdar://problem/17567973> 32-bit error message is really far from the mark: error: missing argument for parameter 'withFont' in call
<rdar://problem/17671058> Wrong error message: "Missing argument for parameter 'completion' in call"
<rdar://problem/17704609> Float is not convertible to UInt8
<rdar://problem/17705424> Poor error reporting for passing Doubles to NSColor: extra argument 'red' in call
<rdar://problem/17743603> Swift compiler gives misleading error message in "NSLayoutConstraint.constraintsWithVisualFormat("x", options: 123, metrics: nil, views: views)"
<rdar://problem/17784167> application of operator to generic type results in odd diagnostic
<rdar://problem/17801696> Awful diagnostic trying to construct an Int when .Int is around
<rdar://problem/17863882> cannot convert the expression's type '()' to type 'Seq'
<rdar://problem/17865869> "has different argument names" diagnostic when parameter defaulted-ness differs
<rdar://problem/17937593> Unclear error message for empty array literal without type context
<rdar://problem/17943023> QoI: compiler displays wrong error when a float is provided to a Int16 parameter in init method
<rdar://problem/17951148> Improve error messages for expressions inside if statements by pre-evaluating outside the 'if'
<rdar://problem/18057815> Unhelpful Swift error message
<rdar://problem/18077468> Incorrect argument label for insertSubview(...)
<rdar://problem/18079213> 'T1' is not identical to 'T2' lacks directionality
<rdar://problem/18086470> Confusing Swift error message: error: 'T' is not convertible to 'MirrorDisposition'
<rdar://problem/18098995> QoI: Unhelpful compiler error when leaving off an & on an inout parameter
<rdar://problem/18104379> Terrible error message
<rdar://problem/18121897> unexpected low-level error on assignment to immutable value through array writeback
<rdar://problem/18123596> unexpected error on self. capture inside class method
<rdar://problem/18152074> QoI: Improve diagnostic for type mismatch in dictionary subscripting
<rdar://problem/18242160> There could be a better error message when using [] instead of [:]
<rdar://problem/18242812> 6A1021a : Type variable leaked
<rdar://problem/18331819> Unclear error message when trying to set an element of an array constant (Swift)
<rdar://problem/18414834> Bad diagnostics example
<rdar://problem/18422468> Calculation of constant value yields unexplainable error
<rdar://problem/18427217> Misleading error message makes debugging difficult
<rdar://problem/18439742> Misleading error: "cannot invoke" mentions completely unrelated types as arguments
<rdar://problem/18535804> Wrong compiler error from swift compiler
<rdar://problem/18567914> Xcode 6.1. GM, Swift, assignment from Int64 to NSNumber. Warning shown as problem with UInt8
<rdar://problem/18784027> Negating Int? Yields Float
<rdar://problem/17691565> attempt to modify a 'let' variable with ++ results in typecheck error about @lvalue Float
<rdar://problem/17164001> "++" on let value could give a better error message
Swift SVN r23782
Start capitalizing on some of the new diagnostic machinery in a few different ways:
- When mining constraints for type information, utilize constraints "favored" by the overload resolution process.
- When printing type variables, if the variable was created by opening a literal expression, utilize the literal
default type or conformance if possible.
- Utilize syntactic information when crafting diagnostics:
- If the constraint miner can produce a better diagnostic than the recorded failure, diagnose via constraints.
- Factor in the expression kind when choosing which types to include in a diagnostic message.
- Start customizing diagnostics based on the amount of type data available.
What does all this mean?
- Fewer type variables leaking into diagnostic messages.
- Far better diagnostics for overload resolution failures. Specifically, we now print proper argument type data
for failed function calls.
- No more "'Foo' is not convertible to 'Foo'" error messages
- A greater emphasis on type data means less dependence on the ordering of failed constraints. This means fewer
inscrutable diagnostics complaining about 'UInt8' when all the constituent expressions are of type Float.
So we still have a ways to go, but these changes should greatly improve the number of head-scratchers served up
by the type checker.
These changes address the following radars:
rdar://problem/17618403
rdar://problem/17559042
rdar://problem/17007456
rdar://problem/17559042
rdar://problem/17590992
rdar://problem/17646988
rdar://problem/16979859
rdar://problem/16922560
rdar://problem/17144902
rdar://problem/16616948
rdar://problem/16756363
rdar://problem/16338509
Swift SVN r20927
This is motivated by <rdar://problem/17051606>.
This ends up renaming variables as well, which seems right for
consistency since we use "predicate" as variable name.
Swift SVN r19135
constraint-based type checker, include the body of the explicit
closure within the set of constraints. This allows type information to
flow from the body expression, so that we can type-check, e.g.,
map(new Int[N], { $0.toString() })
to a String[] without context information. Fixes <rdar://problem/11229738>.
Swift SVN r2794