From ba6feee0be0a8b310733e7faf5aa528e9c4c5633 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 4 Jan 2017 17:50:36 -0800 Subject: [PATCH 1/3] xxx --- lib/Sema/CSSimplify.cpp | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 6157032f1d651..cef54ef3ee75d 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -1015,7 +1015,42 @@ 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(); + 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(); + + auto input2 = func2->getInput(); + 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)); From d1138d5bcaf82e7fc0a7032d06ae715621c34786 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 4 Jan 2017 18:42:21 -0800 Subject: [PATCH 2/3] hack --- lib/Sema/CSSimplify.cpp | 60 +++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index cef54ef3ee75d..c0c1e3a12d84f 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -1016,38 +1016,40 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2, // Input types can be contravariant (or equal). auto input1 = func1->getInput(); - 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(); - auto input2 = func2->getInput(); - 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); + 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(input2.getPointer())) - underlying2 = parenTy->getUnderlyingType(); + 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; + if (underlying1 && underlying2) { + input1 = underlying1; + input2 = underlying2; + } } SolutionKind result = matchTypes(input2, input1, From 7d38094844ee0c1056fc25ad67ddc359790dd587 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 5 Jan 2017 18:05:26 -0800 Subject: [PATCH 3/3] test --- anonargs.swift | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 anonargs.swift 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])