diff --git a/anonargs.swift b/anonargs.swift new file mode 100644 index 0000000000000..08fb57a9c7abc --- /dev/null +++ b/anonargs.swift @@ -0,0 +1,84 @@ +let fn: (Int...) -> () = { + let _: [Int] = $0 +} + +let fna: (Int...) -> () = { (x: Int...) in + let _: [Int] = x +} + +let fn2: (Int, Int...) -> () = { + let _: Int = $0 + let _: [Int] = $1 +} + +let fna2: (Int, Int...) -> () = { + (x: Int, y: Int...) in +} + +let fn3: (Int, Int...) -> () = { + let _: Int = $0.0 + let _: [Int] = $0.1 +} + +let fna3: (Int, Int...) -> () = { + (x: Int, y: Int...) in +} + +func g(t: T) { + let gfn: (T...) -> () = { + let _: [T] = $0 + } + + let gfna: (T...) -> () = { (x: T...) in + let _: [T] = x + } + + let gfn2: (T, T...) -> () = { + let _: T = $0 + let _: [T] = $1 + } + + let gfna2: (T, T...) -> () = { + (x: T, y: T...) in + } + + let gfn3: (T, T...) -> () = { + let _: T = $0.0 + let _: [T] = $0.1 + } + + let gfna3: (T, T...) -> () = { + (x: T, y: T...) in + } +} + +func gg(t: T) { + let gfn: (inout T) -> () = { + let _: T = $0 + } + + let gfn2: (T, inout T) -> () = { + let _: T = $0 + let _: T = $1 + } + + /*let gfn3: (T, inout T) -> () = { + let _: T = $0.0 + let _: T = $0.1 + }*/ +} + + +func fff(fn: @escaping (T...) -> ()) -> ([T]) -> () { + return fn +} + +func fff(fn: @escaping ([T]) -> ()) -> (T...) -> () { + return fn +} + +func ggg(_: Int...) {} + +let ffn: ([Int]) -> () = ggg + +ffn([1, 2, 3]) diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 6157032f1d651..c0c1e3a12d84f 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -1015,7 +1015,44 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2, increaseScore(ScoreKind::SK_FunctionConversion); // Input types can be contravariant (or equal). - SolutionKind result = matchTypes(func2->getInput(), func1->getInput(), + auto input1 = func1->getInput(); + auto input2 = func2->getInput(); + if (kind >= ConstraintKind::Subtype) { + Type underlying1; + if (auto *tupleTy = dyn_cast(input1.getPointer())) { + if (tupleTy->getNumElements() == 1) + underlying1 = tupleTy->getElementType(0); + else { + SmallVector typeElts; + for (auto elt : tupleTy->getElements()) + typeElts.push_back(TupleTypeElt(elt.getType())); + input1 = TupleType::get(typeElts, getTypeChecker().Context); + } + } + else if (auto *parenTy = dyn_cast(input1.getPointer())) + underlying1 = parenTy->getUnderlyingType(); + + Type underlying2; + if (auto *tupleTy = dyn_cast(input2.getPointer())) { + if (tupleTy->getNumElements() == 1) + underlying2 = tupleTy->getElementType(0); + else { + SmallVector typeElts; + for (auto elt : tupleTy->getElements()) + typeElts.push_back(TupleTypeElt(elt.getType())); + input2 = TupleType::get(typeElts, getTypeChecker().Context); + } + } + else if (auto *parenTy = dyn_cast(input2.getPointer())) + underlying2 = parenTy->getUnderlyingType(); + + if (underlying1 && underlying2) { + input1 = underlying1; + input2 = underlying2; + } + } + + SolutionKind result = matchTypes(input2, input1, subKind, subflags, locator.withPathElement( ConstraintLocator::FunctionArgument));