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
This commit is contained in:
Chris Lattner
2015-08-10 06:18:27 +00:00
parent 48276ecefd
commit de79b60c89
33 changed files with 186 additions and 76 deletions

View File

@@ -116,10 +116,10 @@ i ***~ i // expected-error{{cannot convert value of type 'Int' to expected argum
// FIXME: poor diagnostic, to be fixed in 20142462. For now, we just want to
// make sure that it doesn't crash.
func rdar20142523() {
// expected-note @+1 {{overloads for 'map' exist with these partially matching parameter lists: (C, (C.Generator.Element) -> T), (T?, @noescape (T) -> U)}}
map(0..<10, { x in // expected-error{{cannot invoke 'map' with an argument list of type '(Range<Int>, (_) -> _)'}}
// expected-note @-1 {{expected an argument list of type '(C, (C.Generator.Element) -> T)'}}
()
return x
return x // expected-error {{type of expression is ambiguous without more context}}
})
}
@@ -348,7 +348,6 @@ CurriedClass.method2(c)(1)(b: 1.0) // expected-error {{cannot convert value of t
CurriedClass.method2(c)(2)(c: 1.0) // expected-error {{cannot invoke 'method2' with an argument list of type '(c: Double)'}}
// expected-note @-1 {{expected an argument list of type '(b: Int)'}}
CurriedClass.method3(c)(32, b: 1)
_ = CurriedClass.method3(c)
_ = CurriedClass.method3(c)(1, 2) // expected-error {{missing argument label 'b:' in call}} {{32-32=b: }}
@@ -407,13 +406,15 @@ func f20371273() {
// <rdar://problem/20921068> Swift fails to compile: [0].map() { _ in let r = (1,2).0; return r }
// FIXME: Should complain about not having a return type annotation in the closure.
[0].map { _ in let r = (1,2).0; return r } // expected-error {{cannot invoke 'map' with an argument list of type '((_) -> _)'}}
[0].map { _ in let r = (1,2).0; return r }
// expected-error @-1 {{cannot invoke 'map' with an argument list of type '(@noescape (Int) throws -> _)'}}
// expected-note @-2 {{expected an argument list of type '(@noescape (Self.Generator.Element) throws -> T)'}}
// <rdar://problem/21078316> Less than useful error message when using map on optional dictionary type
func rdar21078316() {
var foo : [String : String]?
var bar : [(String, String)]?
bar = foo.map { ($0, $1) } // expected-error {{type of expression is ambiguous without more context}}
bar = foo.map { ($0, $1) } // expected-error {{tuple pattern cannot match values of the non-tuple type '[String : String]'}}
}