mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
The issue here is that the constraint solver was deciding on FixKind::RelabelCallTuple as the fix for the problem and emitting the diagnostic, even though there were two different fixes possible. CSDiags has the infrastructure to support doing doing the right thing here, but is only being used for ApplyExprs, not SubscriptExprs. The solution is to fix both problems: remove FixKind::RelabelCallTuple, to let CSDiags handle the problem, and enhance CSDiags to treat SubscriptExpr more commonly with ApplyExpr. This improves several cases where the solver was picking one solution randomly and suggesting that as a fix, instead of listing that there are multiple different solutions.
385 lines
12 KiB
Swift
385 lines
12 KiB
Swift
// RUN: %target-parse-verify-swift
|
|
|
|
// Single extraneous keyword argument (tuple-to-scalar)
|
|
func f1(a: Int) { }
|
|
f1(a: 5) // expected-error{{extraneous argument label 'a:' in call}}{{4-7=}}
|
|
|
|
struct X1 {
|
|
init(_ a: Int) { }
|
|
func f1(a: Int) {}
|
|
}
|
|
X1(a: 5).f1(b: 5) // expected-error{{extraneous argument label 'a:' in call}}{{4-7=}}
|
|
|
|
// <rdar://problem/16801056>
|
|
enum Policy {
|
|
case Head(Int)
|
|
}
|
|
|
|
func extra2(x x: Int, y: Int) { }
|
|
|
|
func testExtra2(policy : Policy) {
|
|
switch (policy)
|
|
{
|
|
case .Head(let count):
|
|
extra2(x: 0, y: count)
|
|
}
|
|
}
|
|
|
|
// Single missing keyword argument (scalar-to-tuple)
|
|
func f2(a a: Int) { }
|
|
f2(5) // expected-error{{missing argument label 'a:' in call}}{{4-4=a: }}
|
|
|
|
struct X2 {
|
|
init(a: Int) { }
|
|
func f2(b b: Int) { }
|
|
}
|
|
X2(5).f2(5) // expected-error{{missing argument label 'a:' in call}}{{4-4=a: }}
|
|
|
|
|
|
// -------------------------------------------
|
|
// Missing keywords
|
|
// -------------------------------------------
|
|
|
|
func allkeywords1(x x: Int, y: Int) { }
|
|
|
|
// Missing keywords.
|
|
allkeywords1(1, 2) // expected-error{{missing argument labels}} {{14-14=x: }} {{17-17=y: }}
|
|
allkeywords1(x: 1, 2) // expected-error{{missing argument label 'y:' in call}} {{20-20=y: }}
|
|
allkeywords1(1, y: 2) // expected-error{{missing argument label 'x:' in call}} {{14-14=x: }}
|
|
|
|
// If keyword is reserved, make sure to quote it. rdar://problem/21392294
|
|
func reservedLabel(x: Int, `repeat`: Bool) {}
|
|
reservedLabel(1, true) // expected-error{{missing argument label 'repeat:' in call}}{{18-18=repeat: }}
|
|
|
|
// Insert missing keyword before initial backtick. rdar://problem/21392294 part 2
|
|
func reservedExpr(x: Int, y: Int) {}
|
|
let `do` = 2
|
|
reservedExpr(1, `do`) // expected-error{{missing argument label 'y:' in call}}{{17-17=y: }}
|
|
reservedExpr(1, y: `do`)
|
|
|
|
class GenericCtor<U> {
|
|
init<T>(t : T) {}
|
|
}
|
|
GenericCtor<Int>() // expected-error{{missing argument for parameter 't' in call}}
|
|
|
|
// -------------------------------------------
|
|
// Extraneous keywords
|
|
// -------------------------------------------
|
|
func nokeywords1(x: Int, _ y: Int) { }
|
|
|
|
nokeywords1(x: 1, y: 1) // expected-error{{extraneous argument labels 'x:y:' in call}}{{13-16=}}{{19-22=}}
|
|
|
|
// -------------------------------------------
|
|
// Some missing, some extraneous keywords
|
|
// -------------------------------------------
|
|
func somekeywords1(x: Int, y: Int, z: Int) { }
|
|
|
|
somekeywords1(x: 1, y: 2, z: 3) // expected-error{{extraneous argument label 'x:' in call}}{{15-18=}}
|
|
somekeywords1(1, 2, 3) // expected-error{{missing argument labels 'y:z:' in call}}{{18-18=y: }}{{21-21=z: }}
|
|
somekeywords1(x: 1, 2, z: 3) // expected-error{{incorrect argument labels in call (have 'x:_:z:', expected '_:y:z:')}}{{15-18=}}{{21-21=y: }}
|
|
|
|
|
|
// -------------------------------------------
|
|
// Out-of-order keywords
|
|
// -------------------------------------------
|
|
allkeywords1(y: 1, x: 2) // expected-error{{argument 'x' must precede argument 'y'}}
|
|
|
|
// -------------------------------------------
|
|
// Default arguments
|
|
// -------------------------------------------
|
|
|
|
func defargs1(x x: Int = 1, y: Int = 2, z: Int = 3) {}
|
|
|
|
// Using defaults (in-order)
|
|
defargs1()
|
|
defargs1(x: 1)
|
|
defargs1(x: 1, y: 2)
|
|
|
|
// Using defaults (in-order, some missing)
|
|
defargs1(y: 2)
|
|
defargs1(y: 2, z: 3)
|
|
defargs1(z: 3)
|
|
defargs1(x: 1, z: 3)
|
|
|
|
// Using defaults (out-of-order, allowed)
|
|
defargs1(z: 3, y: 2, x: 1)
|
|
defargs1(x: 1, z: 3, y: 2)
|
|
defargs1(y: 2, x: 1)
|
|
|
|
// Default arguments "boxed in".
|
|
func defargs2(first first: Int, x: Int = 1, y: Int = 2, z: Int = 3, last: Int) { }
|
|
|
|
// Using defaults in the middle (in-order, some missing)
|
|
defargs2(first: 1, x: 1, z: 3, last: 4)
|
|
defargs2(first: 1, x: 1, last: 4)
|
|
defargs2(first: 1, y: 2, z: 3, last: 4)
|
|
defargs2(first: 1, last: 4)
|
|
|
|
// Using defaults in the middle (out-of-order, allowed)
|
|
defargs2(first: 1, z: 3, x: 1, last: 4)
|
|
defargs2(first: 1, z: 3, y: 2, last: 4)
|
|
|
|
// Using defaults that have moved past a non-defaulted parameter
|
|
defargs2(x: 1, first: 1, last: 4) // expected-error{{argument 'first' must precede argument 'x'}}
|
|
defargs2(first: 1, last: 4, x: 1) // expected-error{{argument 'x' must precede argument 'last'}}
|
|
|
|
// -------------------------------------------
|
|
// Variadics
|
|
// -------------------------------------------
|
|
func variadics1(x x: Int, y: Int, _ z: Int...) { }
|
|
|
|
// Using variadics (in-order, complete)
|
|
variadics1(x: 1, y: 2)
|
|
variadics1(x: 1, y: 2, 1)
|
|
variadics1(x: 1, y: 2, 1, 2)
|
|
variadics1(x: 1, y: 2, 1, 2, 3)
|
|
|
|
// Using various (out-of-order)
|
|
variadics1(1, 2, 3, 4, 5, x: 6, y: 7) // expected-error{{argument 'x' must precede unnamed parameter #0}}
|
|
|
|
func variadics2(x x: Int, y: Int = 2, z: Int...) { }
|
|
|
|
// Using variadics (in-order, complete)
|
|
variadics2(x: 1, y: 2, z: 1)
|
|
variadics2(x: 1, y: 2, z: 1, 2)
|
|
variadics2(x: 1, y: 2, z: 1, 2, 3)
|
|
|
|
// Using variadics (in-order, some missing)
|
|
variadics2(x: 1, z: 1, 2, 3)
|
|
variadics2(x: 1)
|
|
|
|
// Using variadics (out-of-order)
|
|
variadics2(z: 1, 2, 3, y: 2) // expected-error{{missing argument for parameter 'x' in call}}
|
|
variadics2(z: 1, 2, 3, x: 1) // expected-error{{argument 'x' must precede argument 'z'}}
|
|
|
|
func variadics3(x: Int..., y: Int = 2, z: Int = 3) { }
|
|
|
|
// Using variadics (in-order, complete)
|
|
variadics3(1, 2, 3, y: 0, z: 1)
|
|
variadics3(1, y: 0, z: 1)
|
|
variadics3(y: 0, z: 1)
|
|
|
|
// Using variadics (in-order, some missing)
|
|
variadics3(1, 2, 3, y: 0)
|
|
variadics3(1, z: 1)
|
|
variadics3(z: 1)
|
|
|
|
variadics3(1, 2, 3, z: 1)
|
|
variadics3(1, z: 1)
|
|
variadics3(z: 1)
|
|
|
|
variadics3(1, 2, 3)
|
|
variadics3(1)
|
|
variadics3()
|
|
|
|
// Using variadics (out-of-order)
|
|
variadics3(y: 0, 1, 2, 3) // expected-error{{missing argument label 'z:' in call}} {{18-18=z: }}
|
|
variadics3(z: 1, 1) // FIXME: error here?
|
|
|
|
func variadics4(x x: Int..., y: Int = 2, z: Int = 3) { }
|
|
|
|
// Using variadics (in-order, complete)
|
|
variadics4(x: 1, 2, 3, y: 0, z: 1)
|
|
variadics4(x: 1, y: 0, z: 1)
|
|
variadics4(y: 0, z: 1)
|
|
|
|
// Using variadics (in-order, some missing)
|
|
variadics4(x: 1, 2, 3, y: 0)
|
|
variadics4(x: 1, z: 1)
|
|
variadics4(z: 1)
|
|
|
|
variadics4(x: 1, 2, 3, z: 1)
|
|
variadics4(x: 1, z: 1)
|
|
variadics4(z: 1)
|
|
|
|
variadics4(x: 1, 2, 3)
|
|
variadics4(x: 1)
|
|
variadics4()
|
|
|
|
// Using variadics (in-order, some missing)
|
|
variadics4(y: 0, x: 1, 2, 3) // expected-error{{extra argument in call}}
|
|
variadics4(z: 1, x: 1) // FIXME: error
|
|
|
|
func variadics5(x: Int, y: Int, _ z: Int...) { }
|
|
|
|
// Using variadics (in-order, complete)
|
|
variadics5(1, y: 2)
|
|
variadics5(1, y: 2, 1)
|
|
variadics5(1, y: 2, 1, 2)
|
|
variadics5(1, y: 2, 1, 2, 3)
|
|
|
|
// Using various (out-of-order)
|
|
variadics5(1, 2, 3, 4, 5, 6, y: 7) // expected-error{{argument 'y' must precede unnamed parameter #1}}
|
|
variadics5(y: 1, 2, 3, 4, 5, 6, 7) // expected-error{{missing argument for parameter #1 in call}}
|
|
|
|
func outOfOrder(a : Int, b: Int) {
|
|
outOfOrder(b: 42, 52) // expected-error {{argument '_' must precede argument 'b'}}
|
|
}
|
|
|
|
// -------------------------------------------
|
|
// Missing arguments
|
|
// -------------------------------------------
|
|
// FIXME: Diagnostics could be improved with all missing names, or
|
|
// simply # of arguments required.
|
|
func missingargs1(x x: Int, y: Int, z: Int) {}
|
|
|
|
missingargs1(x: 1, y: 2) // expected-error{{missing argument for parameter 'z' in call}}
|
|
|
|
func missingargs2(x x: Int, y: Int, _ z: Int) {}
|
|
missingargs2(x: 1, y: 2) // expected-error{{missing argument for parameter #3 in call}}
|
|
|
|
// -------------------------------------------
|
|
// Extra arguments
|
|
// -------------------------------------------
|
|
// FIXME: Diagnostics could be improved with all extra arguments and
|
|
// note pointing to the declaration being called.
|
|
func extraargs1(x x: Int) {}
|
|
|
|
extraargs1(x: 1, y: 2) // expected-error{{extra argument 'y' in call}}
|
|
extraargs1(x: 1, 2, 3) // expected-error{{extra argument in call}}
|
|
|
|
// -------------------------------------------
|
|
// Argument name mismatch
|
|
// -------------------------------------------
|
|
|
|
func mismatch1(thisFoo thisFoo: Int = 0, bar: Int = 0, wibble: Int = 0) { }
|
|
|
|
mismatch1(foo: 5) // expected-error{{incorrect argument label in call (have 'foo:', expected 'thisFoo:')}} {{11-14=thisFoo}}
|
|
mismatch1(baz: 1, wobble: 2) // expected-error{{incorrect argument labels in call (have 'baz:wobble:', expected 'bar:wibble:')}} {{11-14=bar}} {{19-25=wibble}}
|
|
mismatch1(food: 1, zap: 2) // expected-error{{incorrect argument labels in call (have 'food:zap:', expected 'thisFoo:bar:')}} {{11-15=thisFoo}} {{20-23=bar}}
|
|
|
|
// -------------------------------------------
|
|
// Subscript keyword arguments
|
|
// -------------------------------------------
|
|
|
|
struct Sub1 {
|
|
subscript (i: Int) -> Int {
|
|
get { return i }
|
|
}
|
|
}
|
|
|
|
var sub1 = Sub1()
|
|
var i: Int = 0
|
|
i = sub1[i]
|
|
i = sub1[i: i] // expected-error{{extraneous argument label 'i:' in subscript}} {{10-13=}}
|
|
|
|
struct Sub2 {
|
|
subscript (d d: Double) -> Double {
|
|
get { return d }
|
|
}
|
|
}
|
|
|
|
var sub2 = Sub2()
|
|
var d: Double = 0.0
|
|
d = sub2[d] // expected-error{{missing argument label 'd:' in subscript}} {{9-9=d: }}
|
|
d = sub2[d: d]
|
|
d = sub2[f: d] // expected-error{{incorrect argument label in subscript (have 'f:', expected 'd:')}} {{10-11=d}}
|
|
|
|
// -------------------------------------------
|
|
// Closures
|
|
// -------------------------------------------
|
|
func intToInt(i: Int) -> Int { return i }
|
|
|
|
func testClosures() {
|
|
let c0 = { (x: Int, y: Int) in x + y }
|
|
c0(1, 2)
|
|
|
|
let c1 = { x, y in intToInt(x + y) }
|
|
c1(1, 2)
|
|
|
|
let c2 = { intToInt($0 + $1) }
|
|
c2(1, 2)
|
|
}
|
|
|
|
func acceptAutoclosure(@autoclosure f f: () -> Int) { }
|
|
func produceInt() -> Int { }
|
|
acceptAutoclosure(f: produceInt) // expected-error{{function produces expected type 'Int'; did you mean to call it with '()'?}} {{32-32=()}}
|
|
|
|
// -------------------------------------------
|
|
// Trailing closures
|
|
// -------------------------------------------
|
|
func trailingclosure1(x x: Int, f: () -> Int) {}
|
|
|
|
trailingclosure1(x: 1) { return 5 }
|
|
trailingclosure1(1) { return 5 } // expected-error{{missing argument label 'x:' in call}}{{18-18=x: }}
|
|
|
|
trailingclosure1(x: 1, { return 5 }) // expected-error{{missing argument label 'f:' in call}} {{24-24=f: }}
|
|
|
|
func trailingclosure2(x x: Int, f: (() -> Int)!...) {}
|
|
trailingclosure2(x: 5) { return 5 }
|
|
|
|
func trailingclosure3(x x: Int, f: (() -> Int)!) {
|
|
var f = f
|
|
f = nil
|
|
_ = f
|
|
}
|
|
|
|
trailingclosure3(x: 5) { return 5 }
|
|
|
|
func trailingclosure4(f f: () -> Int) {}
|
|
trailingclosure4 { 5 }
|
|
|
|
func trailingClosure5<T>(file: String = #file, line: UInt = #line, expression: () -> T?) { }
|
|
func trailingClosure6<T>(value value: Int, expression: () -> T?) { }
|
|
|
|
trailingClosure5(file: "hello", line: 17) { return Optional.Some(5) } // expected-error{{extraneous argument label 'file:' in call}}{{18-24=}}
|
|
trailingClosure6(5) { return Optional.Some(5) } // expected-error{{missing argument label 'value:' in call}}{{18-18=value: }}
|
|
|
|
class MismatchOverloaded1 {
|
|
func method1(x: Int!, arg: ((Int) -> Int)!) { }
|
|
func method1(x: Int!, secondArg: ((Int) -> Int)!) { }
|
|
|
|
@available(*, unavailable)
|
|
func method2(x: Int!, arg: ((Int) -> Int)!) { }
|
|
|
|
func method2(x: Int!, secondArg: ((Int) -> Int)!) { }
|
|
}
|
|
|
|
var mismatchOverloaded1 = MismatchOverloaded1()
|
|
mismatchOverloaded1.method1(5, arg: nil)
|
|
mismatchOverloaded1.method1(5, secondArg: nil)
|
|
|
|
// Prefer available to unavailable declaration, if it comes up.
|
|
mismatchOverloaded1.method2(5) { $0 }
|
|
|
|
// -------------------------------------------
|
|
// Values of function type
|
|
// -------------------------------------------
|
|
func testValuesOfFunctionType(f1: (_: Int, arg: Int) -> () ) {
|
|
f1(3, arg: 5)
|
|
f1(x: 3, 5) // expected-error{{incorrect argument labels in call (have 'x:_:', expected '_:arg:')}} {{6-9=}} {{12-12=arg: }}
|
|
f1(3, 5) // expected-error{{missing argument label 'arg:' in call}} {{9-9=arg: }}
|
|
}
|
|
|
|
|
|
// -------------------------------------------
|
|
// Literals
|
|
// -------------------------------------------
|
|
func string_literals1(x x: String) { }
|
|
string_literals1(x: "hello")
|
|
|
|
func int_literals1(x x: Int) { }
|
|
int_literals1(x: 1)
|
|
|
|
func float_literals1(x x: Double) { }
|
|
float_literals1(x: 5)
|
|
|
|
// -------------------------------------------
|
|
// Tuples as arguments
|
|
// -------------------------------------------
|
|
func produceTuple1() -> (Int, Bool) { return (1, true) }
|
|
|
|
func acceptTuple1<T>(x: (T, Bool)) { }
|
|
|
|
acceptTuple1(produceTuple1())
|
|
acceptTuple1((1, false))
|
|
// FIXME: QoI is awful here.
|
|
acceptTuple1(1, false) // expected-error{{extra argument in call}}
|
|
|
|
func acceptTuple2<T>(input : T) -> T { return input }
|
|
var tuple1 = (1, "hello")
|
|
acceptTuple2(tuple1)
|
|
acceptTuple2((1, "hello", 3.14159))
|
|
|
|
|