Commit Graph

132 Commits

Author SHA1 Message Date
David Farler
93b6962478 Warn when using 'var' bindings in function parameters
These will no longer be allowed in a future Swift release.

rdar://problem/23172698
2015-11-03 17:24:20 -08:00
Chris Lattner
96eaa14f3b Fix an arbitrary restriction where we would not propagate the result type of
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
2015-09-11 06:12:05 +00:00
Chris Lattner
72c5c3e4fe Two changes:
- 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
2015-09-09 00:26:37 +00:00
Chris Lattner
db5f25d290 fix a compiler crasher that can happen when invalid code causes a SequenceExpr to get to
CSGen.


Swift SVN r31722
2015-09-05 23:41:12 +00:00
Chris Lattner
f8b12c6095 merge two tests
Swift SVN r31721
2015-09-05 23:39:57 +00:00
Chris Lattner
e7a86e00b9 Finish up the last bit of work I plan on
<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
2015-09-05 22:37:55 +00:00
Chris Lattner
86b47b8186 remove the TupleSizeMismatch failure mode and diagnose the problem in the mainline
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
2015-09-05 21:38:06 +00:00
Chris Lattner
6619cf76dd Improve the diagnostics generated when the contextual type for a closure
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
2015-09-05 21:02:18 +00:00
Chris Willmore
5d7004a0e1 hasSingleExpressionBody() returns true for void-coercion closures
Have ClosureExpr::hasSingleExpressionBody() return true even after the
closure has been coerced to return Void, i.e., { E } has been rewritten
as { E; () }. This fixes some implicit-self diagnostics, and probably
others.

Revision to r31654 for 22441425.

Swift SVN r31665
2015-09-03 09:36:37 +00:00
Chris Lattner
66a3e8ba14 Fix <rdar://problem/22344208> QoI: Warning for unused capture list variable should be customized
Where before we produced an invalid and misleading diagnostic, produce a correct one.


Swift SVN r31599
2015-09-01 06:12:39 +00:00
Chris Lattner
248727780f Now that enough yaks are cleanly shaven, completely reimplement how
we process contextual constraints when producing diagnostic.  Formerly,
we would aggressively drop contextual type information on the floor under
the idea that it would reduce constraints on the system and make it more
likely to be solvable.  However, this also has the downside of introducing
ambiguity into the system, and some expr nodes (notably closures) cannot
usually be solved without that contextual information.

In the new model, expr diagnostics are expected to handle the fact that
contextual information may be present, and bail out without diagnosing an
error if that is the case.  This gets us more information into closures,
allowing more specific return type information, e.g. in the case in
test/expr/closure/closures.swift.

This approach also produces more correct diagnostics in a bunch of other
cases as well, e.g.:

-  var c = [:]  // expected-error {{type '[_ : _]' does not conform to protocol 'DictionaryLiteralConvertible'}} 
+  var c = [:]  // expected-error {{expression type '[_ : _]' is ambiguous without more context}}

and the examples in test/stmt/foreach.swift, test/expr/cast/as_coerce.swift,
test/expr/cast/array_iteration.swift, etc.

That said, this another two steps forward, one back thing.  Because we
don't handle propagating sametype constraints from results of calls to their
arguments, we regress a couple of (admittedly weird) cases.  This is now 
tracked by:
<rdar://problem/22333090> QoI: Propagate contextual information in a call to operands

There is also the one-off narrow case tracked by:
<rdar://problem/22333281> QoI: improve diagnostic when contextual type of closure disagrees with arguments



Swift SVN r31319
2015-08-18 23:55:02 +00:00
Chris Lattner
7f7b78e051 Fix <rdar://problem/22263468> QoI: Not producing specific argument conversion diagnostic for tuple init
Swift SVN r31211
2015-08-13 06:05:03 +00:00
Chris Lattner
a899872d91 Reapply r31105, with some fixes to invalid unconstrained generics. These fixes correct
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
2015-08-11 06:06:05 +00:00
Chris Lattner
2204dbcbfd revert r31105, it causes some regressions on validation tests.
Swift SVN r31107
2015-08-10 15:01:22 +00:00
Chris Lattner
de79b60c89 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 r31105
2015-08-10 06:18:27 +00:00
Chris Lattner
b6206ab418 add fixit checks to various type checker testcases
Swift SVN r31004
2015-08-04 20:30:54 +00:00
Chris Lattner
b6fbccc1c1 Fix <rdar://problem/21544303> QoI: "Unexpected trailing closure" should have a fixit to insert a 'do' statement
which is gratuitous QoI, but also something that people reasonably hit when used to C programming.



Swift SVN r30986
2015-08-04 06:01:21 +00:00
Chris Lattner
54a5784489 add a radar # for a non-optimal diagnostic.
Swift SVN r30985
2015-08-04 05:43:28 +00:00
Chris Lattner
7a73392087 improve diagnostics relating to closure result types, both when they are
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
2015-08-04 05:41:04 +00:00
Chris Lattner
748845aa4d Now that we have contextual type information more generally available, start
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
2015-08-04 00:55:06 +00:00
Chris Lattner
23e942f122 Reimplement the "multi-statement closures require an explicit return type"
as a proper error, and change it to not be incorrect.  Multi-statement
closures *only* need a return type if they cannot be inferred.

This fixes:
<rdar://problem/22086634> "multi-statement closures require an explicit return type" should be an error not a note


Swift SVN r30937
2015-08-02 21:30:51 +00:00
Chris Lattner
bd03e48090 teach typeCheckArgumentChildIndependently how to propagate type information
down to call argument lists that have more than one operand (heavily leveraging
"computeTupleShuffle").  This resolves a great number of QoI radars, including
things like:
<rdar://problem/19981782> QoI: poor diagnostic for call to memcmp with UInt length parameter

where we used to produce:

error: cannot invoke 'memcmp' with an argument list of type '([UInt8], [UInt8], UInt)'
    return memcmp(left, right, UInt(left.count)) == 0
           ^
note: expected an argument list of type '(UnsafePointer<Void>, UnsafePointer<Void>, Int)'

but now we produce:
error: cannot convert value of type 'UInt' to expected argument type 'Int'
    return memcmp(left, right, UInt(left.count)) == 0
                               ^~~~~~~~~~~~~~~~

which is more "to the point"



Swift SVN r30930
2015-08-02 05:51:26 +00:00
Chris Lattner
97e6a50148 Start using contextual information from function calls to diagnose issues in their
argument.  For now we start with some of the most simple cases: single argument 
calls.  This dramatically improves the QoI for error messages in argument lists,
typically turning a error+note combo into a single specific error message.

Some minor improvements coming (and also generalizing this to n-ary calls), but it 
is nice that all the infrastructure is starting to come together...



Swift SVN r30905
2015-08-01 04:37:52 +00:00
Chris Lattner
1a0a0315fe wordsmith a diagnostic, NFC otherwise.
Swift SVN r30731
2015-07-28 23:35:25 +00:00
Chris Lattner
06cc05daa9 reword a diagnostic, as suggested by Jordan
Swift SVN r30712
2015-07-28 04:03:25 +00:00
Chris Lattner
8c3e62d7c5 Provide contextually sensitive conversion failure messages for situations in
which we have a contextual type that was the failure reason.  These are a bit
longer but also more explicit than the previous diagnostics.



Swift SVN r30669
2015-07-26 23:06:40 +00:00
Chris Lattner
d91f5861d2 Change diagnoseFailure() for unavoidable failures to stop doing anything with
conversion failures, making a bunch of diagnostics more specific and useful.

UnavoidableFailures can be very helpful, but they can also be the first constraint
failure that the system happened to come across... which is not always the most
meaningful one.  CSDiag's expr processing machinery has a generally better way of
narrowing down which ones make the most sense.


Swift SVN r30647
2015-07-26 04:09:34 +00:00
Chris Lattner
5fae58c67f remove getUserFriendlyTypeName.
Swift SVN r30613
2015-07-25 01:18:37 +00:00
Chris Lattner
629a35215f reapply r30570, now that Sema preserves type sugar more correctly:
type check the subexpressions of a callexpr more consistently, 
always checking the arguments independently (not just if one argument 
is inout). This routes around issues handling tuples, and brings more
consistency to the experience. Factor this logic out and use it for
operators and subscripts as well.



Swift SVN r30583
2015-07-24 18:21:48 +00:00
Ted Kremenek
f880276750 Revert "type check the subexpressions of a callexpr more consistently, always checking the arguments independently (not just if one argument is inout). This routes around issues handling tuples, and brings more consistency to the experience. Factor this logic out and use it for operators and subscripts as well."
This reverts commit r30570.

This was causing 'Swift :: stdlib/FixedPointDiagnostics.swift.gyb' to fail.

Swift SVN r30571
2015-07-24 07:48:39 +00:00
Chris Lattner
e28c907e86 type check the subexpressions of a callexpr more consistently, always checking the arguments
independently (not just if one argument is inout).  This routes around issues handling tuples,
and brings more consistency to the experience.  Factor this logic out and use it for operators 
and subscripts as well.

This improves a small collection of diagnostics, including the infamous:

   // Infer incompatible type.
-  func6(fn: {a,b->Float in 4.0 })    // expected-error {{cannot convert return expression of type 'Double' to expected return type 'Float'}}
+  func6(fn: {a,b->Float in 4.0 })    // expected-error {{cannot invoke 'func6' with an argument list of type '(fn: (_, _) -> Float)'}}
+  // expected-note @-1 {{expected an argument list of type '(fn: (Int, Int) -> Int)'}}




Swift SVN r30570
2015-07-24 06:14:27 +00:00
Chris Lattner
04cca603c8 Start peering through the fog of ClosureExprs, using ambiguously typed subexprs to
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
2015-07-23 20:31:43 +00:00
John McCall
50a667b295 Instead of assuming that the return type of a closure
with no returns *must* be (), add a defaulting constraint
so that it will be inferred as () in the absence of
other possibilities.

The chief benefit here is that it allows better QoI when
the user simply hasn't yet written the return statement.

Doing this does regress a corner case where an attempt
to recover from an uncalled function leads to the
type-checker inferring a result for a closure that
doesn't make any sense at all.

Swift SVN r30476
2015-07-22 00:13:02 +00:00
Chris Lattner
86439e9c4e Improve some diagnostics around invalid calls to ClosureExprs and random values of function type,
fixing:
<rdar://problem/20789423> Unclear diagnostic for multi-statement closure with no return type
<rdar://problem/21829141> BOGUS: unexpected trailing closure
<rdar://problem/21784170> Incongruous `unexpected trailing closure` error in `init` function which is cast and called without trailing closure.



Swift SVN r30443
2015-07-21 05:34:36 +00:00
John McCall
bc3b47b98a Infer the return type of a closure to be () if it contains no
return statements, or a return statement with no operand.

Also, fix a special-case diagnostic about converting a return
expression to (1) only apply to converting the actual return
expression, not an arbitrary sub-expression, and (2) use the
actual operand and return types, not the drilled-down types
that caused the failure.

Swift SVN r30420
2015-07-20 21:52:18 +00:00
Chris Lattner
b8868d2727 testcase update to go with r30135
Swift SVN r30136
2015-07-13 06:07:56 +00:00
Chris Lattner
d5aaf13e04 fix <rdar://problem/21459429> QoI: Poor compilation error calling assert
This teaches overload constraint diagnosis to look at the resolved anchor 
expression that fails (instead of assuming that it is the expr itself) and
walks up the AST to find the applyexpr in question.  This allows us to give
much more specific diagnostics for overload resolution failures, and to give
much more specific location information.

Where before my recent patches we used to produce:

t.swift:2:3: error: cannot invoke 'assert' with an argument list of type '(Bool, String)'
  assert(a != nil, "ASSERT COMPILATION ERROR")
  ^
t.swift:2:9: note: expected an argument list of type '(@autoclosure () -> Bool, @autoclosure () -> String, file: StaticString, line: UWord)'
  assert(a != nil, "ASSERT COMPILATION ERROR")
        ^

with this and the other recent patches, we now produce:

t.swift:2:12: error: cannot invoke '!=' with an argument list of type '(Int, nil)'
  assert(a != nil, "ASSERT COMPILATION ERROR")
         ~~^~~~~~




Swift SVN r29792
2015-06-29 22:00:09 +00:00
Chris Lattner
5b31f94d5e Enhance diagnoseGeneralConversionFailure to understand that constraints have a
path associated with them, and to dig the expression the constraint refers to out
of the locator.  Also teach simplifyLocator how to simplify closureexpr results out.

This eliminates a class of completely bogus diagnostics where the types reported
don't make any sense, resolving a class of radars like 19821875, where we now 
produce excellent diagnostics.

That said, we still pick constraints to report that are unfortunate in some cases, 
such as the example in expr/closure/closures.swift.


Swift SVN r29757
2015-06-27 04:33:10 +00:00
Chris Lattner
e41c23801f A bunch of conflated changes:
- Fix TypeCheckExpr.cpp to be more careful when propagating sugar from an 
   argument to the result of the function.  We don't want to propagate parens,
   because they show up in diagnostics later.

 - Restructure FailureDiagnosis::diagnoseFailure() to strictly process the tree
   in depth first order.  Before it would only do this if contextual typing was
   unavailable, leading to unpredictable inconsistencies between diagnostics.

 - Always perform diagnoseContextualConversionError early, as part of the thing
   that calls the visitor, instead of in each visit method.  This may change in
   the future, but is a simplification for now.

 - Make the operator processing code handle the "candidate is an exact match"
   case by emitting a diagnostic indicating that the result type of the operator
   must not match expectations, instead of emitting the silly things like
   "binary operator '&' cannot be applied to two Int operands" which is obviously
   false.

These changes lead to minor improvements across the testsuite, and should make the
diagnostics more predictable for more complex real-world ones, but I haven't gone
through the radars yet.  

Major missing pieces:
 - CallExpr isn't using the same logic that the operators are.
 - When you have a near match (only one argument mismatches) we should specifically
   complain about that argument, instead of spewing an entire argument list.
 - The noescape function attr diagnostic is being emitted twice now.
 



Swift SVN r29733
2015-06-26 07:29:05 +00:00
Chris Lattner
220855433a rework some of CSDiags to be more type based and simplify some things. No major
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
2015-06-26 03:56:40 +00:00
Chris Lattner
20d161cfbf fix <rdar://problem/18123596> unexpected error on self. capture inside class method
We no do not require "self." for closures capturing self in static/class methods.
While we do actually capture the metatype more than we should (rdar://21030087),
this doesn't matter to the developer, since this capture cannot cause a cycle
in the reference graph that they should have to reason about.



Swift SVN r28804
2015-05-20 00:27:34 +00:00
Chris Lattner
db53a225ea fix <rdar://problem/19756953> Swift error: cannot capture '$0' before it is declared
This sets the location of the implicit closure decls (like $0) to being the location
of the { in a ClosureExpr, instead of the location of the first use.  The capture tracker
uses source location information of the decl and the DeclRefExpr to determine if the
referenced value was captured too early, which is what is causing this incorrect error.



Swift SVN r28802
2015-05-20 00:11:22 +00:00
Chris Lattner
e4b6afb9ae Start moving the testsuite to the "_ = foo()" idiom for evaluating an
expression but ignoring its value.  This is the right canonical way to do
this.  NFC, just testsuite changes.



Swift SVN r28638
2015-05-15 20:15:54 +00:00
Chris Lattner
ddd6192094 Implement 3 prominent feature requests:
<rdar://problem/15975935> warning that you can use 'let' not 'var'
<rdar://problem/18876585> Compiler should warn me if I set a parameter as 'var' but never modify it
<rdar://problem/17224539> QoI: warn about unused variables

This uses a simple pass in MiscDiagnostics that walks the body of an
AbstractFunctionDecl.  This means that it doesn't warn about unused properties (etc),
but it captures a vast majority of the cases.

It also does not warn about unused parameters (as a policy decision) because it is too noisy,
there are a variety of other refinements that could be done as well, thoughts welcome.



Swift SVN r28412
2015-05-11 06:26:05 +00:00
Dmitri Hrybenko
f46f16ae82 stdlib: implement new print() API
rdar://20775683

Swift SVN r28309
2015-05-08 01:37:59 +00:00
Doug Gregor
793b3326af Implement the new rules for argument label defaults.
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
2015-04-24 19:03:30 +00:00
Doug Gregor
1dbbf92660 Add a warning when a closure parameter is followed by defaulted parameters.
This finds cases where something that used to be a trailing closure is
no longer a trailing closure due to the recent rule change.

Swift SVN r25289
2015-02-14 00:23:38 +00:00
Chris Lattner
635d46d909 Fix <rdar://problem/19821633> only allow autoclosure on parameters, not on properties and globals
Disallow autoclosure on anything but paramdecls, and provide better QoI when you use them in enums.



Swift SVN r25262
2015-02-13 01:55:56 +00:00
Joe Pamer
6a70bd085e These changes implement some oft-requested tweaks and fixes to our closure implementation:
- Closures that are comprised of only a single return statement are now considered to be "single expression" closures. (rdar://problem/17550847)
- Unannotated single expression closures with non-void return types can now be used in void contexts. (rdar://problem/17228969)
- Situations where a multi-statement closure's type could not be inferred because of the lack of a return-type annotation are now properly diagnosed. (rdar://problem/17212107)

I also encountered a number of crashers along the way, which should now be fixed.

Swift SVN r24817
2015-01-29 18:48:39 +00:00
Chris Willmore
6c21a6414a <rdar://problem/19421148> Calling init with a missing label doesn't provide a descriptive error when overloaded inits differ only by label
Swift SVN r24624
2015-01-22 01:12:45 +00:00