mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
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
43 lines
994 B
Swift
43 lines
994 B
Swift
// RUN: %target-parse-verify-swift
|
|
|
|
func takeIntToInt(f: (Int) -> Int) { }
|
|
func takeIntIntToInt(f: (Int, Int) -> Int) { }
|
|
|
|
// Simple closures
|
|
func simple() {
|
|
takeIntToInt({(x: Int) -> Int in
|
|
return x + 1
|
|
})
|
|
takeIntIntToInt({(x: Int, y: Int) -> Int in
|
|
return x + y
|
|
})
|
|
}
|
|
|
|
// Closures with variadic argument lists
|
|
func variadic() {
|
|
var f = {(start: Int, rest: Int...) -> Int in
|
|
var result = start
|
|
for x in rest {
|
|
result += x
|
|
}
|
|
return result
|
|
}
|
|
f(1)
|
|
f(1, 2)
|
|
f(1, 3)
|
|
|
|
let D = { (Ss ...) in 1 } // expected-error{{'...' cannot be applied to a subpattern which is not explicitly typed}}, expected-error{{unable to infer closure return type in current context}}
|
|
}
|
|
|
|
// Closures with attributes in the parameter list.
|
|
func attrs() {
|
|
_ = {(inout z: Int) -> Int in z }
|
|
}
|
|
|
|
// Closures with argument and parameter names.
|
|
func argAndParamNames() -> Int {
|
|
let f1: (x: Int, y: Int) -> Int = { (a x, b y) in x + y }
|
|
f1(x: 1, y: 2)
|
|
return f1(x: 1, y: 2)
|
|
}
|