From 45330816b4772b708233f0f3b19ad309c06fbe95 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 10 Mar 2020 15:46:54 -0400 Subject: [PATCH 1/4] Profile: Run tests through to -emit-ir to get better coverage --- test/Profiler/coverage_arg_ternary.swift | 1 + test/Profiler/coverage_class.swift | 1 + test/Profiler/coverage_closures.swift | 1 + test/Profiler/coverage_curry.swift | 3 ++- test/Profiler/coverage_dead_code_elim.swift | 1 + test/Profiler/coverage_default_args.swift | 1 + test/Profiler/coverage_deinit.swift | 1 + test/Profiler/coverage_empty_region_stack1.swift | 1 + test/Profiler/coverage_exceptions.swift | 1 + test/Profiler/coverage_force_emission.swift | 1 + test/Profiler/coverage_function_builder.swift | 1 + test/Profiler/coverage_guard.swift | 1 + test/Profiler/coverage_if.swift | 1 + test/Profiler/coverage_invalid_loc.swift | 1 + test/Profiler/coverage_label.swift | 1 + test/Profiler/coverage_member_closure.swift | 1 + test/Profiler/coverage_nested_func.swift | 1 + test/Profiler/coverage_primary_file.swift | 2 ++ test/Profiler/coverage_private.swift | 1 + test/Profiler/coverage_struct.swift | 1 + test/Profiler/coverage_subscript_autoclosure.swift | 1 + test/Profiler/coverage_switch.swift | 1 + test/Profiler/coverage_synthesized_witness.swift | 1 + test/Profiler/coverage_ternary.swift | 1 + test/Profiler/coverage_toplevel.swift | 1 + test/Profiler/coverage_uikit.swift | 1 + test/Profiler/coverage_var_init.swift | 1 + test/Profiler/coverage_while.swift | 1 + test/Profiler/coverage_with_asan.swift | 2 ++ 29 files changed, 32 insertions(+), 1 deletion(-) diff --git a/test/Profiler/coverage_arg_ternary.swift b/test/Profiler/coverage_arg_ternary.swift index e18596fccad70..cbc3da4918c8e 100644 --- a/test/Profiler/coverage_arg_ternary.swift +++ b/test/Profiler/coverage_arg_ternary.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_arg_ternary %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s var s: String? diff --git a/test/Profiler/coverage_class.swift b/test/Profiler/coverage_class.swift index 3c4188978474a..24fc0888d19fc 100644 --- a/test/Profiler/coverage_class.swift +++ b/test/Profiler/coverage_class.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sil -module-name coverage_class %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s class C { // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_class.C.foo() -> () diff --git a/test/Profiler/coverage_closures.swift b/test/Profiler/coverage_closures.swift index 2136f7432a34c..3f6867265b573 100644 --- a/test/Profiler/coverage_closures.swift +++ b/test/Profiler/coverage_closures.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sil -module-name coverage_closures %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s func bar(arr: [(Int32) -> Int32]) { // CHECK-LABEL: sil_coverage_map {{.*}}// closure #1 (Swift.Int32) -> Swift.Int32 in coverage_closures.bar diff --git a/test/Profiler/coverage_curry.swift b/test/Profiler/coverage_curry.swift index 57d668cbce7a6..4e76225aea0f2 100644 --- a/test/Profiler/coverage_curry.swift +++ b/test/Profiler/coverage_curry.swift @@ -1,4 +1,5 @@ -// RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sil -module-name coverage_curry %s | %FileCheck %s +// RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sil %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s struct S0 { init(a: Int, b: Int) { } diff --git a/test/Profiler/coverage_dead_code_elim.swift b/test/Profiler/coverage_dead_code_elim.swift index 35e526b59b4c1..4f54a1086a42f 100644 --- a/test/Profiler/coverage_dead_code_elim.swift +++ b/test/Profiler/coverage_dead_code_elim.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend %s -profile-generate -profile-coverage-mapping -O -whole-module-optimization -emit-ir -o - | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s // CHECK-NOT: llvm_coverage_mapping = internal constant diff --git a/test/Profiler/coverage_default_args.swift b/test/Profiler/coverage_default_args.swift index 9ed8de1ce1d8f..7fb83535b8b19 100644 --- a/test/Profiler/coverage_default_args.swift +++ b/test/Profiler/coverage_default_args.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_default_args %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_default_args.closureInArgs(f: (Swift.Int) -> Swift.Int) -> () // CHECK-NEXT: [[@LINE+5]]:59 -> [[@LINE+7]]:2 : 0 diff --git a/test/Profiler/coverage_deinit.swift b/test/Profiler/coverage_deinit.swift index 8b7abff4fed24..02a131ceb6e2f 100644 --- a/test/Profiler/coverage_deinit.swift +++ b/test/Profiler/coverage_deinit.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -suppress-warnings -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_deinit %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s // REQUIRES: objc_interop import Foundation diff --git a/test/Profiler/coverage_empty_region_stack1.swift b/test/Profiler/coverage_empty_region_stack1.swift index 57fd3a8ec1ddd..94f5128a5672f 100644 --- a/test/Profiler/coverage_empty_region_stack1.swift +++ b/test/Profiler/coverage_empty_region_stack1.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sil -module-name coverage_empty %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s // Skip the sil prologue, which reproduces the swift source of this file // and confounds FileCheck. diff --git a/test/Profiler/coverage_exceptions.swift b/test/Profiler/coverage_exceptions.swift index b48ea05c8d8b3..1762cbb1becc3 100644 --- a/test/Profiler/coverage_exceptions.swift +++ b/test/Profiler/coverage_exceptions.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_catch %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s struct S { // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_catch.S.init() -> coverage_catch.S diff --git a/test/Profiler/coverage_force_emission.swift b/test/Profiler/coverage_force_emission.swift index a96db07cd6fb0..92cb05edef2f3 100644 --- a/test/Profiler/coverage_force_emission.swift +++ b/test/Profiler/coverage_force_emission.swift @@ -1,5 +1,6 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sil -module-name coverage_force_emission %s | %FileCheck %s -check-prefix=COVERAGE // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -emit-sil -module-name coverage_force_emission %s | %FileCheck %s -check-prefix=PGO +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s final class VarInit { // COVERAGE: sil_coverage_map {{.*}} "$s23coverage_force_emission7VarInitC04lazydE033_7D375D72BA8B0C53C9AD7E4DBC7FF493LLSSvgSSyXEfU_" diff --git a/test/Profiler/coverage_function_builder.swift b/test/Profiler/coverage_function_builder.swift index a08237f268eb8..fff05ac6ef0f6 100644 --- a/test/Profiler/coverage_function_builder.swift +++ b/test/Profiler/coverage_function_builder.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_functon_builder %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s @_functionBuilder struct Summer { diff --git a/test/Profiler/coverage_guard.swift b/test/Profiler/coverage_guard.swift index 020d971052710..8a41d0fb015fd 100644 --- a/test/Profiler/coverage_guard.swift +++ b/test/Profiler/coverage_guard.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_guard %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_guard.foo func foo(_ x : Int32) { // CHECK: [[@LINE]]:23 -> [[END:[0-9]+:2]] : 0 diff --git a/test/Profiler/coverage_if.swift b/test/Profiler/coverage_if.swift index 6e1419e8a130b..5dfb738ad4590 100644 --- a/test/Profiler/coverage_if.swift +++ b/test/Profiler/coverage_if.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_if %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_if.foo func foo(x : Bool) { // CHECK: [[@LINE]]:20 -> {{[0-9]+}}:2 : 0 diff --git a/test/Profiler/coverage_invalid_loc.swift b/test/Profiler/coverage_invalid_loc.swift index ff22c4ab94698..c8219dfd7443c 100644 --- a/test/Profiler/coverage_invalid_loc.swift +++ b/test/Profiler/coverage_invalid_loc.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -disable-sil-ownership-verifier -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_invalid_loc %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s // The implicit tuple and array exprs formed to call `dynamicallyCall` // happen to have invalid source locations (n.b. this may not always be true, diff --git a/test/Profiler/coverage_label.swift b/test/Profiler/coverage_label.swift index 986514289c371..11fc33c56e7d7 100644 --- a/test/Profiler/coverage_label.swift +++ b/test/Profiler/coverage_label.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -suppress-warnings -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_label %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_label.foo func foo() { // CHECK-DAG: [[@LINE]]:12 -> [[@LINE+19]]:2 : 0 diff --git a/test/Profiler/coverage_member_closure.swift b/test/Profiler/coverage_member_closure.swift index 064d9556ee63a..3fa81ba55c772 100644 --- a/test/Profiler/coverage_member_closure.swift +++ b/test/Profiler/coverage_member_closure.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sil -module-name coverage_member_closure %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s class C { // Closures in members receive their own coverage mapping. diff --git a/test/Profiler/coverage_nested_func.swift b/test/Profiler/coverage_nested_func.swift index 6048de4f003d1..db309893aa8a2 100644 --- a/test/Profiler/coverage_nested_func.swift +++ b/test/Profiler/coverage_nested_func.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sil -module-name coverage_autoclosure %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_autoclosure.call_auto_closure() // CHECK-NEXT: [[@LINE+3]]:26 -> [[@LINE+10]]:2 : 0 diff --git a/test/Profiler/coverage_primary_file.swift b/test/Profiler/coverage_primary_file.swift index deafa2ec82c40..f7eaca63c8d00 100644 --- a/test/Profiler/coverage_primary_file.swift +++ b/test/Profiler/coverage_primary_file.swift @@ -1,5 +1,7 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_primary_file %s %S/Inputs/coverage_imports.swift | %FileCheck %s -check-prefix=ALL // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_primary_file -primary-file %s %S/Inputs/coverage_imports.swift | %FileCheck %s -check-prefix=PRIMARY +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s %S/Inputs/coverage_imports.swift +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir -primary-file %s %S/Inputs/coverage_imports.swift // ALL: sil_coverage_map {{.*}} // closure #1 () -> Swift.Int in coverage_primary_file.Box.x.getter : Swift.Int // ALL: sil_coverage_map {{.*}} // coverage_primary_file.Box.init(y: Swift.Int) -> coverage_primary_file.Box diff --git a/test/Profiler/coverage_private.swift b/test/Profiler/coverage_private.swift index 61f5334c6e78d..6e5f9ebee7d16 100644 --- a/test/Profiler/coverage_private.swift +++ b/test/Profiler/coverage_private.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_private %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s struct S { func visible() { diff --git a/test/Profiler/coverage_struct.swift b/test/Profiler/coverage_struct.swift index 5063574734438..657c9a05b0eda 100644 --- a/test/Profiler/coverage_struct.swift +++ b/test/Profiler/coverage_struct.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_struct %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s struct Foo { var a = false diff --git a/test/Profiler/coverage_subscript_autoclosure.swift b/test/Profiler/coverage_subscript_autoclosure.swift index 0e521ccd9379b..a48f14fa5b8fb 100644 --- a/test/Profiler/coverage_subscript_autoclosure.swift +++ b/test/Profiler/coverage_subscript_autoclosure.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -enable-testing -profile-generate -profile-coverage-mapping -emit-sil -module-name coverage_subscript_autoclosure %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s struct S { subscript(i: Int, autoclosure: @autoclosure () -> Int) -> Int { diff --git a/test/Profiler/coverage_switch.swift b/test/Profiler/coverage_switch.swift index 953c472edb488..b5248d0a94c1b 100644 --- a/test/Profiler/coverage_switch.swift +++ b/test/Profiler/coverage_switch.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_switch %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_switch.f1 func f1(_ x : Int32) { diff --git a/test/Profiler/coverage_synthesized_witness.swift b/test/Profiler/coverage_synthesized_witness.swift index 58553f3eed542..023c45788f9f2 100644 --- a/test/Profiler/coverage_synthesized_witness.swift +++ b/test/Profiler/coverage_synthesized_witness.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sil %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s protocol P { associatedtype T diff --git a/test/Profiler/coverage_ternary.swift b/test/Profiler/coverage_ternary.swift index e9006c1264304..8483f4c60d9bc 100644 --- a/test/Profiler/coverage_ternary.swift +++ b/test/Profiler/coverage_ternary.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_ternary %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s // coverage_ternary.bar.init() -> coverage_ternary.bar // CHECK-LABEL: sil hidden @$s16coverage_ternary3barCACycfc diff --git a/test/Profiler/coverage_toplevel.swift b/test/Profiler/coverage_toplevel.swift index ca1bc481eb0d8..a7795c6d1a7d2 100644 --- a/test/Profiler/coverage_toplevel.swift +++ b/test/Profiler/coverage_toplevel.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sil -module-name coverage_toplevel %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s // CHECK: sil_coverage_map{{.*}}__tlcd_line:[[@LINE+2]]:1 // CHECK: [[@LINE+1]]:1 -> [[@LINE+1]]:11 diff --git a/test/Profiler/coverage_uikit.swift b/test/Profiler/coverage_uikit.swift index 6768b83a62ac3..3c0c0076ed122 100644 --- a/test/Profiler/coverage_uikit.swift +++ b/test/Profiler/coverage_uikit.swift @@ -2,6 +2,7 @@ // REQUIRES: objc_interop // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sil -module-name coverage_uikit %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s import UIKit diff --git a/test/Profiler/coverage_var_init.swift b/test/Profiler/coverage_var_init.swift index 6d20ad36f41ce..5d54a3b1c22dd 100644 --- a/test/Profiler/coverage_var_init.swift +++ b/test/Profiler/coverage_var_init.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_var_init %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s final class VarInit { // CHECK: sil_coverage_map {{.*}} "$s17coverage_var_init7VarInitC018initializedWrapperE0SivpfP" diff --git a/test/Profiler/coverage_while.swift b/test/Profiler/coverage_while.swift index d78680f98d627..24851fe906fd8 100644 --- a/test/Profiler/coverage_while.swift +++ b/test/Profiler/coverage_while.swift @@ -1,4 +1,5 @@ // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -suppress-warnings -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_while %s | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s // CHECK-LABEL: // coverage_while.eoo() -> () func eoo() { diff --git a/test/Profiler/coverage_with_asan.swift b/test/Profiler/coverage_with_asan.swift index 63803d72d2b62..e8b08ef331fb0 100644 --- a/test/Profiler/coverage_with_asan.swift +++ b/test/Profiler/coverage_with_asan.swift @@ -1,4 +1,6 @@ // RUN: %target-swift-frontend %s -profile-generate -profile-coverage-mapping -sanitize=address -emit-ir -o - | %FileCheck %s +// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s + // REQUIRES: OS=macosx // CHECK: main From b45f70d8b068184e54946250f8b1310405241920 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 11 Mar 2020 16:10:22 -0400 Subject: [PATCH 2/4] IDE: Clean up traversal logic in SourceEntityWalker Try to make this a bit more self-documenting. --- lib/IDE/SourceEntityWalker.cpp | 111 +++++++++++++++------------------ 1 file changed, 52 insertions(+), 59 deletions(-) diff --git a/lib/IDE/SourceEntityWalker.cpp b/lib/IDE/SourceEntityWalker.cpp index ea10b7429be4f..c75c62d7374ca 100644 --- a/lib/IDE/SourceEntityWalker.cpp +++ b/lib/IDE/SourceEntityWalker.cpp @@ -246,14 +246,23 @@ static SemaReferenceKind getReferenceKind(Expr *Parent, Expr *E) { std::pair SemaAnnotator::walkToExprPre(Expr *E) { assert(E); + std::pair stopTraversal = { false, nullptr }; + std::pair skipChildren = { false, E }; + + auto doSkipChildren = [&]() -> std::pair { + if (!SEWalker.walkToExprPost(E)) + return stopTraversal; + return skipChildren; + }; + if (isDone()) - return { false, nullptr }; + return stopTraversal; if (ExprsToSkip.count(E) != 0) - return { false, E }; + return skipChildren; if (!SEWalker.walkToExprPre(E)) - return { false, E }; + return skipChildren; if (auto *CtorRefE = dyn_cast(E)) CtorRefs.push_back(CtorRefE); @@ -262,11 +271,10 @@ std::pair SemaAnnotator::walkToExprPre(Expr *E) { if (auto *SubExpr = ACE->getUnwrappedCurryThunkExpr()) { if (auto *DRE = dyn_cast(SubExpr)) { if (!passReference(DRE->getDecl(), DRE->getType(), - DRE->getNameLoc(), - ReferenceMetaData(getReferenceKind(Parent.getAsExpr(), DRE), - OpAccess))) { - return { false, nullptr }; - } + DRE->getNameLoc(), + ReferenceMetaData(getReferenceKind(Parent.getAsExpr(), DRE), + OpAccess))) + return stopTraversal; return { true, E }; } @@ -300,12 +308,12 @@ std::pair SemaAnnotator::walkToExprPre(Expr *E) { if (auto *module = dyn_cast(DRE->getDecl())) { if (!passReference(ModuleEntity(module), {module->getName(), E->getLoc()})) - return { false, nullptr }; + return stopTraversal; } else if (!passReference(DRE->getDecl(), DRE->getType(), DRE->getNameLoc(), ReferenceMetaData(getReferenceKind(Parent.getAsExpr(), DRE), OpAccess))) { - return { false, nullptr }; + return stopTraversal; } } else if (auto *MRE = dyn_cast(E)) { { @@ -324,31 +332,29 @@ std::pair SemaAnnotator::walkToExprPre(Expr *E) { // Visit in source order. if (!MRE->getBase()->walk(*this)) - return { false, nullptr }; + return stopTraversal; } if (!passReference(MRE->getMember().getDecl(), MRE->getType(), MRE->getNameLoc(), ReferenceMetaData(SemaReferenceKind::DeclMemberRef, OpAccess))) - return { false, nullptr }; + return stopTraversal; // We already visited the children. - if (!walkToExprPost(E)) - return { false, nullptr }; - return { false, E }; + return doSkipChildren(); } else if (auto OtherCtorE = dyn_cast(E)) { if (!passReference(OtherCtorE->getDecl(), OtherCtorE->getType(), OtherCtorE->getConstructorLoc(), ReferenceMetaData(SemaReferenceKind::DeclConstructorRef, OpAccess))) - return { false, nullptr }; + return stopTraversal; } else if (auto *SE = dyn_cast(E)) { // Visit in source order. if (!SE->getBase()->walk(*this)) - return { false, nullptr }; + return stopTraversal; ValueDecl *SubscrD = nullptr; if (SE->hasDecl()) @@ -359,21 +365,19 @@ std::pair SemaAnnotator::walkToExprPre(Expr *E) { if (SubscrD) { if (!passSubscriptReference(SubscrD, E->getLoc(), data, true)) - return { false, nullptr }; + return stopTraversal; } if (!SE->getIndex()->walk(*this)) - return { false, nullptr }; + return stopTraversal; if (SubscrD) { if (!passSubscriptReference(SubscrD, E->getEndLoc(), data, false)) - return { false, nullptr }; + return stopTraversal; } // We already visited the children. - if (!walkToExprPost(E)) - return { false, nullptr }; - return { false, E }; + return doSkipChildren(); } else if (auto *KPE = dyn_cast(E)) { for (auto &component : KPE->getComponents()) { @@ -406,60 +410,54 @@ std::pair SemaAnnotator::walkToExprPre(Expr *E) { } else if (auto *BinE = dyn_cast(E)) { // Visit in source order. if (!BinE->getArg()->getElement(0)->walk(*this)) - return { false, nullptr }; + return stopTraversal; if (!BinE->getFn()->walk(*this)) - return { false, nullptr }; + return stopTraversal; if (!BinE->getArg()->getElement(1)->walk(*this)) - return { false, nullptr }; + return stopTraversal; // We already visited the children. - if (!walkToExprPost(E)) - return { false, nullptr }; - return { false, E }; + return doSkipChildren(); } else if (auto TupleE = dyn_cast(E)) { if (auto CallE = dyn_cast_or_null(Parent.getAsExpr())) { if (!passCallArgNames(CallE->getFn(), TupleE)) - return { false, nullptr }; + return stopTraversal; } } else if (auto IOE = dyn_cast(E)) { llvm::SaveAndRestore> C(this->OpAccess, AccessKind::ReadWrite); if (!IOE->getSubExpr()->walk(*this)) - return { false, nullptr }; + return stopTraversal; // We already visited the children. if (!walkToExprPost(E)) - return { false, nullptr }; - return { false, E }; + return stopTraversal; + return skipChildren; } else if (auto LE = dyn_cast(E)) { llvm::SaveAndRestore> C(this->OpAccess, AccessKind::Read); if (!LE->getSubExpr()->walk(*this)) - return { false, nullptr }; + return stopTraversal; // We already visited the children. - if (!walkToExprPost(E)) - return { false, nullptr }; - return { false, E }; + return doSkipChildren(); } else if (auto AE = dyn_cast(E)) { { llvm::SaveAndRestore> C(this->OpAccess, AccessKind::Write); if (AE->getDest() && !AE->getDest()->walk(*this)) - return { false, nullptr }; + return stopTraversal; } if (AE->getSrc() && !AE->getSrc()->walk(*this)) - return { false, nullptr }; + return stopTraversal; // We already visited the children. - if (!walkToExprPost(E)) - return { false, nullptr }; - return { false, E }; + return doSkipChildren(); } else if (auto OEE = dyn_cast(E)) { // Record opaque value. OpaqueValueMap[OEE->getOpaqueValue()] = OEE->getExistentialValue(); @@ -468,44 +466,39 @@ std::pair SemaAnnotator::walkToExprPre(Expr *E) { }; if (!OEE->getSubExpr()->walk(*this)) - return { false, nullptr }; - if (!walkToExprPost(E)) - return { false, nullptr }; - return { false, E }; + return stopTraversal; + + return doSkipChildren(); } else if (auto MTEE = dyn_cast(E)) { // Manually walk to original arguments in order. We don't handle // OpaqueValueExpr here. // Original non-escaping closure. if (!MTEE->getNonescapingClosureValue()->walk(*this)) - return { false, nullptr }; + return stopTraversal; // Body, which is called by synthesized CallExpr. auto *callExpr = cast(MTEE->getSubExpr()); if (!callExpr->getFn()->walk(*this)) - return { false, nullptr }; + return stopTraversal; - if (!walkToExprPost(E)) - return { false, nullptr }; - return { false, E }; + return doSkipChildren(); } else if (auto CUCE = dyn_cast(E)) { // Ignore conversion expressions. We don't handle OpaqueValueExpr here // because it's only in conversion expressions. Instead, just walk into // sub expression. if (!CUCE->getSubExpr()->walk(*this)) - return { false, nullptr }; - if (!walkToExprPost(E)) - return { false, nullptr }; - return { false, E }; + return stopTraversal; + + return doSkipChildren(); } else if (auto OVE = dyn_cast(E)) { // Walk into mapped value. auto value = OpaqueValueMap.find(OVE); if (value != OpaqueValueMap.end()) { if (!value->second->walk(*this)) - return { false, nullptr }; - if (!walkToExprPost(E)) - return { false, nullptr }; - return { false, E }; + return stopTraversal; + + return doSkipChildren(); } } From 4caa6d70031244ef06a39fa738a25cc17539e5b9 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 11 Mar 2020 15:17:41 -0400 Subject: [PATCH 3/4] IDE: Fix indexing for Sema-built curry thunks --- lib/AST/Expr.cpp | 10 ++++++++++ lib/IDE/SourceEntityWalker.cpp | 4 +++- test/Index/expressions.swift | 10 ++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 5a2a4e5fcef27..c1c221cbfad0c 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -1851,6 +1851,11 @@ Expr *AutoClosureExpr::getUnwrappedCurryThunkExpr() const { case AutoClosureExpr::Kind::SingleCurryThunk: { auto *body = getSingleExpressionBody(); body = body->getSemanticsProvidingExpr(); + + if (auto *openExistential = dyn_cast(body)) { + body = openExistential->getSubExpr(); + } + if (auto *outerCall = dyn_cast(body)) { return outerCall->getFn(); } @@ -1866,6 +1871,11 @@ Expr *AutoClosureExpr::getUnwrappedCurryThunkExpr() const { AutoClosureExpr::Kind::SingleCurryThunk); auto *innerBody = innerClosure->getSingleExpressionBody(); innerBody = innerBody->getSemanticsProvidingExpr(); + + if (auto *openExistential = dyn_cast(innerBody)) { + innerBody = openExistential->getSubExpr(); + } + if (auto *outerCall = dyn_cast(innerBody)) { if (auto *innerCall = dyn_cast(outerCall->getFn())) { if (auto *declRef = dyn_cast(innerCall->getFn())) { diff --git a/lib/IDE/SourceEntityWalker.cpp b/lib/IDE/SourceEntityWalker.cpp index c75c62d7374ca..1e8a8b3194efe 100644 --- a/lib/IDE/SourceEntityWalker.cpp +++ b/lib/IDE/SourceEntityWalker.cpp @@ -276,9 +276,11 @@ std::pair SemaAnnotator::walkToExprPre(Expr *E) { OpAccess))) return stopTraversal; - return { true, E }; + return doSkipChildren(); } } + + return { true, E }; } if (auto *DRE = dyn_cast(E)) { diff --git a/test/Index/expressions.swift b/test/Index/expressions.swift index c92fb142fd9f5..d33c1b3a5ae06 100644 --- a/test/Index/expressions.swift +++ b/test/Index/expressions.swift @@ -58,3 +58,13 @@ func test2(x: X) { // CHECK: [[@LINE+1]]:19 | type-alias/associated-type/Swift | A | [[AP_P_USR]] | Ref,RelCont | rel: 1 _ = type(of: x).A.self } + +protocol Disposable { + func dispose() +} + +func useDisposable(_ d: Disposable?) { + // CHECK: [[@LINE+1]]:26 | instance-method/Swift | dispose() | s:14swift_ide_test10DisposableP7disposeyyF | Ref,RelCont | rel: 1 + guard let dispose = d?.dispose else { return } + _ = dispose +} \ No newline at end of file From c54383885485ed0b0b7203fa61c32eefe686d579 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 26 Feb 2020 23:09:41 -0500 Subject: [PATCH 4/4] Sema: Rewrite partial applications into closures When a method is called with fewer than two parameter lists, transform it into a fully-applied call by wrapping it in a closure. Eg, Foo.bar => { self in { args... self.bar(args...) } } foo.bar => { self in { args... self.bar(args...) } }(self) super.bar => { args... in super.bar(args...) } With this change, SILGen only ever sees fully-applied calls, which will allow ripping out some code. This new way of doing curry thunks fixes a long-standing bug where unbound references to protocol methods did not work. This is because such a reference must open the existential *inside* the closure, after 'self' has been applied, whereas the old SILGen implementation of curry thunks really wanted the type of the method reference to match the opened type of the method. A follow-up cleanup will remove the SILGen curry thunk implementation. Fixes rdar://21289579 and https://bugs.swift.org/browse/SR-75. --- CHANGELOG.md | 14 + lib/SIL/SILDeclRef.cpp | 7 +- lib/SIL/SILProfiler.cpp | 6 + lib/Sema/CSApply.cpp | 395 +++++++++++++++++- test/ClangImporter/objc_ir.swift | 2 +- test/Constraints/ranking.swift | 6 +- test/DebugInfo/closure-arg-linetable.swift | 21 - test/IRGen/big_types_corner_cases.swift | 6 +- test/IRGen/objc_super.swift | 10 +- test/IRGen/partial_apply_generic.swift | 5 +- test/IRGen/struct_with_resilient_type.swift | 10 +- test/Profiler/coverage_curry.swift | 4 +- test/SILGen/cf_members.swift | 29 +- test/SILGen/dynamic_self.swift | 10 +- test/SILGen/enum.swift | 62 +-- test/SILGen/enum_curry_thunks.swift | 15 +- test/SILGen/extensions.swift | 3 - test/SILGen/extensions_objc.swift | 12 +- test/SILGen/foreign_errors.swift | 10 +- test/SILGen/functions.swift | 41 +- .../guaranteed_normal_args_curry_thunks.swift | 161 +------ test/SILGen/inlinable_attribute.swift | 11 +- test/SILGen/inlinable_attribute_objc.swift | 15 - test/SILGen/mangling.swift | 9 - test/SILGen/objc_currying.swift | 66 +-- test/SILGen/objc_extensions.swift | 15 +- test/SILGen/objc_protocol_native_thunk.swift | 3 +- test/SILGen/objc_protocols.swift | 81 ++-- test/SILGen/opaque_values_silgen_lib.swift | 31 +- test/SILGen/partial_apply_apply.swift | 24 ++ .../SILGen/partial_apply_consuming_self.swift | 22 + test/SILGen/partial_apply_generic.swift | 78 ++-- test/SILGen/partial_apply_init.swift | 57 ++- test/SILGen/partial_apply_override.swift | 19 +- test/SILGen/partial_apply_protocol.swift | 110 +---- test/SILGen/partial_apply_super.swift | 242 +++++------ test/SILGen/partial_apply_throws.swift | 15 + .../SILOptimizer/closure_lifetime_fixup.swift | 9 +- .../SILOptimizer/dead_partial_apply_arg.swift | 14 +- .../specialize_opaque_type_archetypes.swift | 6 +- ...g-silgenfunction-emitopenexistential.swift | 2 +- ...g-silgenfunction-emitopenexistential.swift | 2 +- 42 files changed, 837 insertions(+), 823 deletions(-) delete mode 100644 test/DebugInfo/closure-arg-linetable.swift create mode 100644 test/SILGen/partial_apply_apply.swift create mode 100644 test/SILGen/partial_apply_consuming_self.swift create mode 100644 test/SILGen/partial_apply_throws.swift rename validation-test/{compiler_crashers => compiler_crashers_fixed}/28682-swift-lowering-silgenfunction-emitopenexistential.swift (87%) rename validation-test/{compiler_crashers => compiler_crashers_fixed}/28689-swift-lowering-silgenfunction-emitopenexistential.swift (88%) diff --git a/CHANGELOG.md b/CHANGELOG.md index c54040f3db578..51f925bef5dff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,19 @@ Swift Next // OK, has broader visibility than override func foo() where U: Equatable { ... } } + +* [SR-75][]: + + Unapplied references to protocol methods methods are now supported. Previously this + only worked for methods defined in structs, enums and classes. + + ```swift + protocol Cat { + func play(catToy: Toy) + } + + let fn = Cat.play + fn(myCat)(myToy) ``` * [SE-0266][]: @@ -7939,6 +7952,7 @@ Swift 1.0 [SE-0267]: [SE-0269]: +[SR-75]: [SR-106]: [SR-419]: [SR-631]: diff --git a/lib/SIL/SILDeclRef.cpp b/lib/SIL/SILDeclRef.cpp index d6de976bd5429..262f463475a5d 100644 --- a/lib/SIL/SILDeclRef.cpp +++ b/lib/SIL/SILDeclRef.cpp @@ -450,8 +450,11 @@ bool SILDeclRef::isTransparent() const { if (isStoredPropertyInitializer()) return true; - if (hasAutoClosureExpr()) - return true; + if (hasAutoClosureExpr()) { + auto *ace = getAutoClosureExpr(); + if (ace->getThunkKind() == AutoClosureExpr::Kind::None) + return true; + } if (hasDecl()) { if (auto *AFD = dyn_cast(getDecl())) diff --git a/lib/SIL/SILProfiler.cpp b/lib/SIL/SILProfiler.cpp index 520b8584fcbf4..762cad37c1e8f 100644 --- a/lib/SIL/SILProfiler.cpp +++ b/lib/SIL/SILProfiler.cpp @@ -68,6 +68,12 @@ static bool isUnmapped(ASTNode N) { LLVM_DEBUG(llvm::dbgs() << "Skipping ASTNode: implicit closure expr\n"); return true; } + + if (isa(CE) && + cast(CE)->getThunkKind() != AutoClosureExpr::Kind::None) { + LLVM_DEBUG(llvm::dbgs() << "Skipping ASTNode: curry thunk expr\n"); + return true; + } } // Map all other kinds of expressions. diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index 8cd8ee7fe64e2..0a5809a9ba924 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -792,6 +792,244 @@ namespace { return true; } + /// Determines if a partially-applied member reference should be + /// converted into a fully-applied member reference with a pair of + /// closures. + bool shouldBuildCurryThunk(OverloadChoice choice, + bool baseIsInstance, + bool extraUncurryLevel) { + ValueDecl *member = choice.getDecl(); + auto isDynamic = choice.getKind() == OverloadChoiceKind::DeclViaDynamic; + + // FIXME: We should finish plumbing this through for dynamic + // lookup as well. + if (isDynamic || member->getAttrs().hasAttribute()) + return false; + + // If we're inside a selector expression, don't build the thunk. + // Were not actually going to emit the member reference, just + // look at the AST. + for (auto expr : ExprStack) + if (isa(expr)) + return false; + + // Unbound instance method references always build a thunk, even if + // we apply the arguments (eg, SomeClass.method(self)(a)), to avoid + // representational issues. + if (!baseIsInstance && member->isInstanceMember()) + return true; + + // Figure out how many argument lists we need. + unsigned maxArgCount = member->getNumCurryLevels(); + + unsigned argCount = [&]() -> unsigned { + Expr *prev = ExprStack.back(); + + // FIXME: Representational gunk because "T(...)" is really + // "T.init(...)" -- pretend it has two argument lists like + // a real '.' call. + if (isa(member) && + isa(prev) && + isa(cast(prev)->getFn())) { + assert(maxArgCount == 2); + return 1; + } + + // Similarly, ".foo(...)" really applies two argument lists. + if (auto *unresolvedMemberExpr = dyn_cast(prev)) { + if (unresolvedMemberExpr->hasArguments() || + unresolvedMemberExpr->hasTrailingClosure()) + return 1; + return 0; + } + + return getArgCount(maxArgCount); + }(); + + // Sometimes we build a member reference that has an implicit + // level of function application in the AST. For example, + // @dynamicCallable and callAsFunction are handled this way. + // + // FIXME: It would be nice to simplify this and the argCount + // computation above somehow. + if (extraUncurryLevel) + argCount++; + + // If we have fewer argument lists than expected, build a thunk. + if (argCount < maxArgCount) + return true; + + return false; + } + + AutoClosureExpr *buildCurryThunk(ValueDecl *member, + FunctionType *selfFnTy, + Expr *selfParamRef, + Expr *ref, + ConstraintLocatorBuilder locator) { + auto &context = cs.getASTContext(); + + OptionSet options + = (ParameterList::Implicit | + ParameterList::NamedArguments); + auto *params = getParameterList(member)->clone(context, options); + + for (auto idx : indices(*params)) { + auto *param = params->get(idx); + auto arg = selfFnTy->getParams()[idx]; + + param->setInterfaceType( + arg.getParameterType()->mapTypeOutOfContext()); + param->setSpecifier( + ParamDecl::getParameterSpecifierForValueOwnership( + arg.getValueOwnership())); + } + + auto resultTy = selfFnTy->getResult(); + auto discriminator = AutoClosureExpr::InvalidDiscriminator; + auto closure = + new (context) AutoClosureExpr(/*set body later*/nullptr, resultTy, + discriminator, cs.DC); + closure->setParameterList(params); + closure->setType(selfFnTy); + closure->setThunkKind(AutoClosureExpr::Kind::SingleCurryThunk); + cs.cacheType(closure); + + auto refTy = cs.getType(ref)->castTo(); + auto calleeParams = refTy->getResult()->castTo()->getParams(); + auto calleeResultTy = refTy->getResult()->castTo()->getResult(); + + auto selfParam = refTy->getParams()[0]; + auto selfParamTy = selfParam.getPlainType(); + + Expr *selfOpenedRef = selfParamRef; + + if (selfParamTy->hasOpenedExistential()) { + // If we're opening an existential: + // - the type of 'ref' inside the closure is written in terms of the + // open existental archetype + // - the type of the closure, 'selfFnTy' is written in terms of the + // erased existential bounds + if (selfParam.isInOut()) + selfParamTy = LValueType::get(selfParamTy); + + selfOpenedRef = + new (context) OpaqueValueExpr(SourceLoc(), selfParamTy); + cs.cacheType(selfOpenedRef); + } + + // (Self) -> ... + auto *selfCall = + CallExpr::createImplicit(context, ref, selfOpenedRef, { }, + [&](const Expr *E) { return cs.getType(E); }); + selfCall->setType(refTy->getResult()); + cs.cacheType(selfCall->getArg()); + cs.cacheType(selfCall); + + // FIXME: This is a holdover from the old tuple-based function call + // representation. + auto selfArgTy = ParenType::get(context, + selfParam.getPlainType(), + selfParam.getParameterFlags()); + selfCall->getArg()->setType(selfArgTy); + cs.cacheType(selfCall->getArg()); + + if (selfParamRef->isSuperExpr()) + selfCall->setIsSuper(true); + + // Pass all the closure parameters to the call. + SmallVector labels; + SmallVector labelLocs; + SmallVector args; + + for (auto idx : indices(*params)) { + auto *param = params->get(idx); + auto calleeParamType = calleeParams[idx].getParameterType(); + + auto type = param->getType(); + + Expr *paramRef = + new (context) DeclRefExpr(param, DeclNameLoc(), /*implicit*/ true); + paramRef->setType( + param->isInOut() + ? LValueType::get(type) + : type); + cs.cacheType(paramRef); + + paramRef = coerceToType( + paramRef, + param->isInOut() + ? LValueType::get(calleeParamType) + : calleeParamType, + locator); + + if (param->isInOut()) { + paramRef = + new (context) InOutExpr(SourceLoc(), paramRef, calleeParamType, + /*implicit=*/true); + cs.cacheType(paramRef); + } else if (param->isVariadic()) { + paramRef = + new (context) VarargExpansionExpr(paramRef, /*implicit*/ true); + paramRef->setType(calleeParamType); + cs.cacheType(paramRef); + } + + args.push_back(paramRef); + + labels.push_back(calleeParams[idx].getLabel()); + labelLocs.push_back(SourceLoc()); + } + + Expr *closureArg; + if (args.size() == 1 && + labels[0].empty() && + !calleeParams[0].getParameterFlags().isVariadic()) { + closureArg = new (context) ParenExpr(SourceLoc(), args[0], SourceLoc(), + /*hasTrailingClosure=*/false); + closureArg->setImplicit(); + } else { + closureArg = TupleExpr::create(context, SourceLoc(), args, labels, labelLocs, + SourceLoc(), /*hasTrailingClosure=*/false, + /*implicit=*/true); + } + + auto argTy = AnyFunctionType::composeInput(context, calleeParams, + /*canonical*/false); + closureArg->setType(argTy); + cs.cacheType(closureArg); + + // (Self) -> (Args...) -> ... + auto *closureCall = + CallExpr::create(context, selfCall, closureArg, { }, { }, + /*hasTrailingClosure=*/false, + /*implicit=*/true); + closureCall->setType(calleeResultTy); + cs.cacheType(closureCall); + + Expr *closureBody = closureCall; + closureBody = coerceToType(closureCall, resultTy, locator); + + if (selfFnTy->getExtInfo().throws()) { + closureBody = new (context) TryExpr(closureBody->getStartLoc(), closureBody, + cs.getType(closureBody), + /*implicit=*/true); + cs.cacheType(closureBody); + } + + if (selfParam.getPlainType()->hasOpenedExistential()) { + closureBody = + new (context) OpenExistentialExpr( + selfParamRef, cast(selfOpenedRef), + closureBody, resultTy); + cs.cacheType(closureBody); + } + + closure->setBody(closureBody); + + return closure; + } + /// Build a new member reference with the given base and member. Expr *buildMemberRef(Expr *base, SourceLoc dotLoc, SelectedOverload overload, DeclNameLoc memberLoc, @@ -851,6 +1089,8 @@ namespace { bool isUnboundInstanceMember = (!baseIsInstance && member->isInstanceMember()); + bool isPartialApplication = + shouldBuildCurryThunk(choice, baseIsInstance, extraUncurryLevel); auto refTy = simplifyType(openedFullType); @@ -871,11 +1111,29 @@ namespace { getConstraintSystem().getConstraintLocator( memberLocator)); if (knownOpened != solution.OpenedExistentialTypes.end()) { - // Open the existential before performing the member reference. - base = openExistentialReference(base, knownOpened->second, member); - baseTy = knownOpened->second; - selfTy = baseTy; - openedExistential = true; + // Determine if we're going to have an OpenExistentialExpr around + // this member reference. + // + // If we have a partial application of a protocol method, we open + // the existential in the curry thunk, instead of opening it here, + // because we won't have a 'self' value until the curry thunk is + // applied. + // + // However, a partial application of a class method on a subclass + // existential does need to open the existential, so that it can be + // upcast to the appropriate class reference type. + if (!isPartialApplication || !containerTy->hasOpenedExistential()) { + // Open the existential before performing the member reference. + base = openExistentialReference(base, knownOpened->second, member); + baseTy = knownOpened->second; + selfTy = baseTy; + openedExistential = true; + } else { + // Erase opened existentials from the type of the thunk; we're + // going to open the existential inside the thunk's body. + containerTy = containerTy->eraseOpenedExistential(knownOpened->second); + selfTy = containerTy; + } } // References to properties with accessors and storage usually go @@ -1025,6 +1283,133 @@ namespace { cs.setType(declRefExpr, refTy); Expr *ref = declRefExpr; + if (isPartialApplication) { + auto curryThunkTy = refTy->castTo(); + + // A partial application thunk consists of two nested closures: + // + // { self in { args... in self.method(args...) } } + // + // If the reference has an applied 'self', eg 'let fn = foo.method', + // the outermost closure is wrapped inside a single ApplyExpr: + // + // { self in { args... in self.method(args...) } }(foo) + // + // This is done instead of just hoising the expression 'foo' up + // into the closure, which would change evaluation order. + // + // However, for a super method reference, eg, 'let fn = super.foo', + // the base expression is always a SuperRefExpr, possibly wrapped + // by an upcast. Since SILGen expects super method calls to have a + // very specific shape, we only emit a single closure here and + // capture the original SuperRefExpr, since its evaluation does not + // have side effects, instead of abstracting out a 'self' parameter. + if (isSuper) { + auto selfFnTy = curryThunkTy->getResult()->castTo(); + + auto closure = buildCurryThunk(member, selfFnTy, base, ref, + memberLocator); + + // Skip the code below -- we're not building an extra level of + // call by applying the 'super', instead the closure we just + // built is the curried reference. + return closure; + } + + // Another case where we want to build a single closure is when + // we have a partial application of a constructor on a statically- + // derived metatype value. Again, there are no order of evaluation + // concerns here, and keeping the call and base together in the AST + // improves SILGen. + if (isa(member) && + cs.isStaticallyDerivedMetatype(base)) { + auto selfFnTy = curryThunkTy->getResult()->castTo(); + + // Add a useless ".self" to avoid downstream diagnostics. + base = new (context) DotSelfExpr(base, SourceLoc(), base->getEndLoc(), + cs.getType(base)); + cs.setType(base, base->getType()); + + auto closure = buildCurryThunk(member, selfFnTy, base, ref, + memberLocator); + + // Skip the code below -- we're not building an extra level of + // call by applying the metatype instead the closure we just + // built is the curried reference. + return closure; + } + + // Check if we need to open an existential stored inside 'self'. + auto knownOpened = solution.OpenedExistentialTypes.find( + getConstraintSystem().getConstraintLocator( + memberLocator)); + if (knownOpened != solution.OpenedExistentialTypes.end()) { + curryThunkTy = + curryThunkTy->eraseOpenedExistential(knownOpened->second) + ->castTo(); + } + + auto discriminator = AutoClosureExpr::InvalidDiscriminator; + + // The outer closure. + // + // let outerClosure = "{ self in \(closure) }" + auto selfParam = curryThunkTy->getParams()[0]; + auto selfParamDecl = new (context) ParamDecl( + SourceLoc(), + /*argument label*/ SourceLoc(), Identifier(), + /*parameter name*/ SourceLoc(), context.Id_self, + cs.DC); + + auto selfParamTy = selfParam.getPlainType(); + bool isLValue = selfParam.isInOut(); + + selfParamDecl->setInterfaceType(selfParamTy->mapTypeOutOfContext()); + selfParamDecl->setSpecifier( + ParamDecl::getParameterSpecifierForValueOwnership( + selfParam.getValueOwnership())); + + auto *outerParams = + ParameterList::create(context, SourceLoc(), selfParamDecl, + SourceLoc()); + + // The inner closure. + // + // let closure = "{ args... in self.member(args...) }" + auto selfFnTy = curryThunkTy->getResult()->castTo(); + + Expr *selfParamRef = + new (context) DeclRefExpr(selfParamDecl, DeclNameLoc(), + /*implicit=*/true); + + selfParamRef->setType( + isLValue ? LValueType::get(selfParamTy) : selfParamTy); + cs.cacheType(selfParamRef); + + if (isLValue) { + selfParamRef = + new (context) InOutExpr(SourceLoc(), selfParamRef, selfParamTy, + /*implicit=*/true); + cs.cacheType(selfParamRef); + } + + auto closure = buildCurryThunk(member, selfFnTy, selfParamRef, ref, + memberLocator); + + auto outerClosure = + new (context) AutoClosureExpr(closure, selfFnTy, + discriminator, cs.DC); + outerClosure->setThunkKind(AutoClosureExpr::Kind::DoubleCurryThunk); + + outerClosure->setParameterList(outerParams); + outerClosure->setType(curryThunkTy); + cs.cacheType(outerClosure); + + // Replace the DeclRefExpr with a closure expression which SILGen + // knows how to emit. + ref = outerClosure; + } + // If this is a method whose result type is dynamic Self, or a // construction, replace the result type with the actual object type. if (!member->getDeclContext()->getSelfProtocolDecl()) { diff --git a/test/ClangImporter/objc_ir.swift b/test/ClangImporter/objc_ir.swift index f7436dc9fa2a2..b61e34ff01309 100644 --- a/test/ClangImporter/objc_ir.swift +++ b/test/ClangImporter/objc_ir.swift @@ -351,7 +351,7 @@ func testConstrGenericCompatibilityAliasMangling(constr_generic_obj: SwiftConstr // CHECK-LABEL: s7objc_ir22testBlocksWithGenerics3hbaypSo13HasBlockArrayC_tF func testBlocksWithGenerics(hba: HasBlockArray) -> Any { - // CHECK: {{call swiftcc.*sSo13HasBlockArrayC05blockC0SayyyXBGyFTcTO}} + // CHECK: s7objc_ir22testBlocksWithGenerics3hbaypSo13HasBlockArrayC_tFSayyyXBGycAEcfu_AFycfu0_TA let _ = hba.blockPointerType() return hba.blockArray } diff --git a/test/Constraints/ranking.swift b/test/Constraints/ranking.swift index d78acc3215557..3f6019e9e137e 100644 --- a/test/Constraints/ranking.swift +++ b/test/Constraints/ranking.swift @@ -36,7 +36,7 @@ func propertyVersusFunction(_ p: P, _ t: T) { let _ = p.p // CHECK: witness_method $@opened("{{.*}}") P, #P.p!getter.1 let _: P = p.p - // CHECK: function_ref @$s7ranking1PP1pyyAaB_pFTc + // CHECK: function_ref @$s7ranking22propertyVersusFunctionyyAA1P_p_xtAaCRzlFyAaC_pcAaC_pcfu_ : $@convention(thin) (@in_guaranteed P) -> @owned @callee_guaranteed (@in_guaranteed P) -> () let _: (P) -> () = p.p // CHECK: witness_method $@opened("{{.*}}") P, #P.p!getter.1 let _: P? = p.p @@ -68,7 +68,7 @@ func propertyVersusFunction(_ p: P, _ t: T) { let _ = t.p // CHECK: witness_method $T, #P.p!getter.1 let _: P = t.p - // CHECK: function_ref @$s7ranking1PP1pyyAaB_pFTc + // CHECK: function_ref @$s7ranking22propertyVersusFunctionyyAA1P_p_xtAaCRzlFyAaC_pcxcfu1_ : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @owned @callee_guaranteed (@in_guaranteed P) -> () let _: (P) -> () = t.p // CHECK: witness_method $T, #P.p!getter.1 let _: P? = t.p @@ -103,7 +103,7 @@ extension P { let _ = self.p // CHECK: witness_method $Self, #P.p!getter.1 let _: P = self.p - // CHECK: function_ref @$s7ranking1PP1pyyAaB_pFTc + // CHECK: function_ref @$s7ranking1PPAAE22propertyVersusFunctionyyFyAaB_pcxcfu_ : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @owned @callee_guaranteed (@in_guaranteed P) -> () let _: (P) -> () = self.p // CHECK: witness_method $Self, #P.p!getter.1 let _: P? = self.p diff --git a/test/DebugInfo/closure-arg-linetable.swift b/test/DebugInfo/closure-arg-linetable.swift deleted file mode 100644 index 7841c9606fff2..0000000000000 --- a/test/DebugInfo/closure-arg-linetable.swift +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s - -public class C { - - // Test that curry thunks don't have line table entries. - // CHECK: define {{.*}}@"$s4main1CC11someHandleryyFTc"(%T4main1CC* %0) - // CHECK-SAME: !dbg ![[CURRY_THUNK:[0-9]+]] - // CHECK-NOT: ret {{.*}}, - // CHECK: {{.*}}, !dbg ![[DBG:[0-9]+]] - // CHECK: ret {{.*}}, !dbg ![[DBG]] - // CHECK: ![[DBG]] = !DILocation(line: 0, scope: ![[CURRY_THUNK]]) - func someHandler() { } - - func doSomethingWithHandler(_ theHandler: (() -> Void)!) -> Void { - theHandler() - } - - public func entry() { - doSomethingWithHandler(someHandler) - } -} diff --git a/test/IRGen/big_types_corner_cases.swift b/test/IRGen/big_types_corner_cases.swift index f9dc5d24b6ec9..543f0a3f51290 100644 --- a/test/IRGen/big_types_corner_cases.swift +++ b/test/IRGen/big_types_corner_cases.swift @@ -117,11 +117,7 @@ class Foo { func myMethod(_ callback: (MyStruct, Int) -> Void) -> Void { } } -// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} linkonce_odr hidden swiftcc { i8*, %swift.refcounted* } @"$s22big_types_corner_cases3FooC8myMethodyyyAA8MyStructV_SitXEFTc"(%T22big_types_corner_cases3FooC* %0) -// CHECK: getelementptr inbounds %T22big_types_corner_cases3FooC, %T22big_types_corner_cases3FooC* -// CHECK: getelementptr inbounds void (i8*, %swift.opaque*, %T22big_types_corner_cases3FooC*)*, void (i8*, %swift.opaque*, %T22big_types_corner_cases3FooC*)** -// CHECK: call noalias %swift.refcounted* @swift_allocObject(%swift.type* getelementptr inbounds (%swift.full_boxmetadata, %swift.full_boxmetadata* -// CHECK: ret { i8*, %swift.refcounted* } +// CHECK-LABEL: define internal swiftcc void @"$s22big_types_corner_cases3FooC4blamyyFyyAA8MyStructV_SitXEcACcfu_yyAF_SitXEcfu0_"(i8* %0, %swift.opaque* %1, %T22big_types_corner_cases3FooC* %2) public enum LargeEnum { public enum InnerEnum { diff --git a/test/IRGen/objc_super.swift b/test/IRGen/objc_super.swift index 8c169354c94a3..72b045bd7ea2f 100644 --- a/test/IRGen/objc_super.swift +++ b/test/IRGen/objc_super.swift @@ -82,6 +82,12 @@ class PartialApply : Gizmo { // CHECK: } } +// CHECK: define internal swiftcc void @"$s10objc_super12PartialApplyC4frobyyFyycfu_"(%T10objc_super12PartialApplyC* %0) +// CHECK: call swiftcc %swift.metadata_response @"$s10objc_super12PartialApplyCMa"([[INT]] 0) +// CHECK: @"\01L_selector(frob)" +// CHECK: @objc_msgSendSuper2 +// CHECK: } + class GenericRuncer : Gizmo { var x: Gizmo? = nil var y: T? @@ -130,7 +136,5 @@ class GenericRuncer : Gizmo { } // CHECK: define internal swiftcc void [[PARTIAL_FORWARDING_THUNK]](%swift.refcounted* swiftself %0) {{.*}} { -// CHECK: call swiftcc %swift.metadata_response @"$s10objc_super12PartialApplyCMa"([[INT]] 0) -// CHECK: @"\01L_selector(frob)" -// CHECK: call void bitcast (void ()* @objc_msgSendSuper2 +// CHECK: @"$ss12StaticStringV14withUTF8BufferyxxSRys5UInt8VGXElFyAEcfU_" // CHECK: } diff --git a/test/IRGen/partial_apply_generic.swift b/test/IRGen/partial_apply_generic.swift index e012878d01166..5989f44a8e93a 100644 --- a/test/IRGen/partial_apply_generic.swift +++ b/test/IRGen/partial_apply_generic.swift @@ -48,10 +48,9 @@ struct S { let s = S() var y = s.hugeStructReturn -// CHECK-LABEL: define internal swiftcc { i64, i64, i64, i64 } @"$s21partial_apply_generic1SV16hugeStructReturnyAA04HugeE0VAFFTA"(i64 %0, i64 %1, i64 %2, i64 %3, %swift.refcounted* swiftself %4) {{.*}} { +// CHECK-LABEL: define internal swiftcc { i64, i64, i64, i64 } @"$s21partial_apply_genericAA10HugeStructVACcAA1SVcfu_A2Ccfu0_TA"(i64 %0, i64 %1, i64 %2, i64 %3, %swift.refcounted* swiftself %4) // CHECK: entry: -// CHECK: %5 = tail call swiftcc { i64, i64, i64, i64 } @"$s21partial_apply_generic1SV16hugeStructReturnyAA04HugeE0VAFF"(i64 %0, i64 %1, i64 %2, i64 %3) -// CHECK: ret { i64, i64, i64, i64 } %5 +// CHECK: call swiftcc { i64, i64, i64, i64 } @"$s21partial_apply_genericAA10HugeStructVACcAA1SVcfu_A2Ccfu0_"(i64 %0, i64 %1, i64 %2, i64 %3) // CHECK: } // diff --git a/test/IRGen/struct_with_resilient_type.swift b/test/IRGen/struct_with_resilient_type.swift index 0201209d01538..ffa0ef33525f9 100644 --- a/test/IRGen/struct_with_resilient_type.swift +++ b/test/IRGen/struct_with_resilient_type.swift @@ -1,6 +1,6 @@ // RUN: %empty-directory(%t) // RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift -// RUN: %target-swift-frontend -I %t -emit-ir %s | %FileCheck %s +// RUN: %target-swift-frontend -I %t -emit-ir %s // REQUIRES: CPU=x86_64 @@ -27,14 +27,6 @@ struct ProtAndResilStruct { func crash() { fooImp.foo(ptr: bar) } -// CHECK-LABEL: define{{.*}} @"$s26struct_with_resilient_type18ProtAndResilStructV3baryyFTc"(%T26struct_with_resilient_type18ProtAndResilStructV* noalias nocapture %0) -// CHECK: [[T0:%.*]] = zext i32 %flags to i64 -// CHECK: %flags.alignmentMask = and i64 [[T0]], 255 -// CHECK: [[XOR_ALIGN:%.*]] = xor i64 %flags.alignmentMask, -1 -// CHECK: [[INIT_OFFSET:%.*]] = add i64 16, %flags.alignmentMask -// CHECK: [[T0:%.*]] = and i64 [[INIT_OFFSET]], [[XOR_ALIGN]] -// CHECK: [[T1:%.*]] = add i64 [[T0]], %size -// CHECK: [[ALIGN:%.*]] = or i64 7, %flags.alignmentMask } func crashCaller() { diff --git a/test/Profiler/coverage_curry.swift b/test/Profiler/coverage_curry.swift index 4e76225aea0f2..c1ae2e98e7a1b 100644 --- a/test/Profiler/coverage_curry.swift +++ b/test/Profiler/coverage_curry.swift @@ -7,12 +7,14 @@ struct S0 { } // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_curry.testS0CurriedInstanceMethods(s0: coverage_curry.S0, a: Swift.Int, b: Swift.Int) -// CHECK-NEXT: [[@LINE+2]]:59 -> [[@LINE+8]]:2 : 0 +// CHECK-NEXT: [[@LINE+2]]:59 -> [[@LINE+10]]:2 : 0 // CHECK-NEXT: } func testS0CurriedInstanceMethods(s0: S0, a: Int, b: Int) { _ = S0.f1(s0)(a: a, b: a) _ = (S0.f1)(s0)(a: a, b: a) _ = ((S0.f1))(s0)(a: a, b: a) _ = S0.f1(a:b:)(s0)(a, b) + _ = S0.init(a:b:)(0, 0) let f1OneLevel = S0.f1(s0) + let f1Init = S0.init(a:b:) } diff --git a/test/SILGen/cf_members.swift b/test/SILGen/cf_members.swift index 575eab9c576fc..1d91e5703b624 100644 --- a/test/SILGen/cf_members.swift +++ b/test/SILGen/cf_members.swift @@ -36,9 +36,8 @@ public func foo(_ x: Double) { // CHECK: apply [[FN]]([[X]]) z = makeMetatype().init(value: x) - // CHECK: [[SELF_META:%.*]] = metatype $@thin Struct1.Type - // CHECK: [[THUNK:%.*]] = function_ref @$sSo10IAMStruct1V5valueABSd_tcfCTcTO - // CHECK: [[A:%.*]] = apply [[THUNK]]([[SELF_META]]) + // CHECK: [[FN:%.*]] = function_ref @$s10cf_members3fooyySdFSo10IAMStruct1VSdcfu_ : $@convention(thin) (Double) -> Struct1 + // CHECK: [[A:%.*]] = thin_to_thick_function [[FN]] // CHECK: [[BORROWED_A:%.*]] = begin_borrow [[A]] // CHECK: [[A_COPY:%.*]] = copy_value [[BORROWED_A]] // CHECK: [[BORROWED_A2:%.*]] = begin_borrow [[A_COPY]] @@ -66,7 +65,7 @@ public func foo(_ x: Double) { // CHECK: [[READ:%.*]] = begin_access [read] [unknown] [[Z]] : $*Struct1 // CHECK: [[ZVAL:%.*]] = load [trivial] [[READ]] - // CHECK: [[THUNK:%.*]] = function_ref [[THUNK_NAME:@\$sSo10IAMStruct1V9translate7radiansABSd_tFTcTO]] + // CHECK: [[THUNK:%.*]] = function_ref @$s10cf_members3fooyySdFSo10IAMStruct1VSdcADcfu0_ : $@convention(thin) (Struct1) -> @owned @callee_guaranteed (Double) -> Struct1 // CHECK: [[C:%.*]] = apply [[THUNK]]([[ZVAL]]) // CHECK: [[BORROWED_C:%.*]] = begin_borrow [[C]] // CHECK: [[C_COPY:%.*]] = copy_value [[BORROWED_C]] @@ -76,7 +75,7 @@ public func foo(_ x: Double) { // CHECK: destroy_value [[C_COPY]] // CHECK: end_borrow [[BORROWED_C]] z = c(x) - // CHECK: [[THUNK:%.*]] = function_ref [[THUNK_NAME]] + // CHECK: [[THUNK:%.*]] = function_ref @$s10cf_members3fooyySdFSo10IAMStruct1VSdcADcfu2_ : $@convention(thin) (Struct1) -> @owned @callee_guaranteed (Double) -> Struct1 // CHECK: [[THICK:%.*]] = thin_to_thick_function [[THUNK]] // CHECK: [[BORROW:%.*]] = begin_borrow [[THICK]] // CHECK: [[COPY:%.*]] = copy_value [[BORROW]] @@ -103,7 +102,7 @@ public func foo(_ x: Double) { // CHECK: [[READ:%.*]] = begin_access [read] [unknown] [[Z]] : $*Struct1 // CHECK: [[ZVAL:%.*]] = load [trivial] [[READ]] - // CHECK: [[THUNK:%.*]] = function_ref @$sSo10IAMStruct1V5scaleyABSdFTcTO + // CHECK: [[THUNK:%.*]] = function_ref @$s10cf_members3fooyySdFSo10IAMStruct1VSdcADcfu4_ : $@convention(thin) (Struct1) -> @owned @callee_guaranteed (Double) -> Struct1 // CHECK: [[F:%.*]] = apply [[THUNK]]([[ZVAL]]) // CHECK: [[BORROWED_F:%.*]] = begin_borrow [[F]] // CHECK: [[F_COPY:%.*]] = copy_value [[BORROWED_F]] @@ -113,7 +112,7 @@ public func foo(_ x: Double) { // CHECK: destroy_value [[F_COPY]] // CHECK: end_borrow [[BORROWED_F]] z = f(x) - // CHECK: [[THUNK:%.*]] = function_ref @$sSo10IAMStruct1V5scaleyABSdFTcTO + // CHECK: [[THUNK:%.*]] = function_ref @$s10cf_members3fooyySdFSo10IAMStruct1VSdcADcfu6_ : $@convention(thin) (Struct1) -> @owned @callee_guaranteed (Double) -> Struct1 // CHECK: thin_to_thick_function [[THUNK]] let g = Struct1.scale // CHECK: [[READ:%.*]] = begin_access [read] [unknown] [[Z]] : $*Struct1 @@ -159,7 +158,7 @@ public func foo(_ x: Double) { // CHECK: apply [[FN]]() var y = Struct1.staticMethod() // CHECK: [[SELF:%.*]] = metatype - // CHECK: [[THUNK:%.*]] = function_ref @$sSo10IAMStruct1V12staticMethods5Int32VyFZTcTO + // CHECK: [[THUNK:%.*]] = function_ref @$s10cf_members3fooyySdFs5Int32VycSo10IAMStruct1Vmcfu8_ : $@convention(thin) (@thin Struct1.Type) -> @owned @callee_guaranteed () -> Int32 // CHECK: [[I:%.*]] = apply [[THUNK]]([[SELF]]) // CHECK: [[BORROWED_I:%.*]] = begin_borrow [[I]] // CHECK: [[I_COPY:%.*]] = copy_value [[BORROWED_I]] @@ -236,37 +235,37 @@ public func foo(_ x: Double) { } // CHECK: } // end sil function '$s10cf_members3foo{{[_0-9a-zA-Z]*}}F' -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo10IAMStruct1V5valueABSd_tcfCTO -// CHECK: bb0([[X:%.*]] : $Double, [[SELF:%.*]] : $@thin Struct1.Type): +// CHECK-LABEL: sil private [ossa] @$s10cf_members3fooyySdFSo10IAMStruct1VSdcfu_ : $@convention(thin) (Double) -> Struct1 { +// CHECK: bb0([[X:%.*]] : $Double): // CHECK: [[CFUNC:%.*]] = function_ref @IAMStruct1CreateSimple // CHECK: [[RET:%.*]] = apply [[CFUNC]]([[X]]) // CHECK: return [[RET]] -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo10IAMStruct1V9translate7radiansABSd_tFTO +// CHECK-LABEL: sil private [ossa] @$s10cf_members3fooyySdFSo10IAMStruct1VSdcADcfu0_ADSdcfu1_ : $@convention(thin) (Double, Struct1) -> Struct1 { // CHECK: bb0([[X:%.*]] : $Double, [[SELF:%.*]] : $Struct1): // CHECK: store [[SELF]] to [trivial] [[TMP:%.*]] : // CHECK: [[CFUNC:%.*]] = function_ref @IAMStruct1Rotate // CHECK: [[RET:%.*]] = apply [[CFUNC]]([[TMP]], [[X]]) // CHECK: return [[RET]] -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo10IAMStruct1V5scaleyABSdFTO +// CHECK-LABEL: sil private [ossa] @$s10cf_members3fooyySdFSo10IAMStruct1VSdcADcfu4_ADSdcfu5_ : $@convention(thin) (Double, Struct1) -> Struct1 { // CHECK: bb0([[X:%.*]] : $Double, [[SELF:%.*]] : $Struct1): // CHECK: [[CFUNC:%.*]] = function_ref @IAMStruct1Scale // CHECK: [[RET:%.*]] = apply [[CFUNC]]([[SELF]], [[X]]) // CHECK: return [[RET]] -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo10IAMStruct1V12staticMethods5Int32VyFZTO +// CHECK-LABEL: sil private [ossa] @$s10cf_members3fooyySdFs5Int32VycSo10IAMStruct1Vmcfu8_ADycfu9_ : $@convention(thin) (@thin Struct1.Type) -> Int32 { // CHECK: bb0([[SELF:%.*]] : $@thin Struct1.Type): // CHECK: [[CFUNC:%.*]] = function_ref @IAMStruct1StaticMethod // CHECK: [[RET:%.*]] = apply [[CFUNC]]() // CHECK: return [[RET]] -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo10IAMStruct1V13selfComesLast1xySd_tFTO +// CHECK-LABEL:sil private [ossa] @$s10cf_members3fooyySdFySdcSo10IAMStruct1Vcfu10_ySdcfu11_ : $@convention(thin) (Double, Struct1) -> () { // CHECK: bb0([[X:%.*]] : $Double, [[SELF:%.*]] : $Struct1): // CHECK: [[CFUNC:%.*]] = function_ref @IAMStruct1SelfComesLast // CHECK: apply [[CFUNC]]([[X]], [[SELF]]) -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo10IAMStruct1V14selfComesThird1a1b1xys5Int32V_SfSdtFTO +// CHECK-LABEL: sil private [ossa] @$s10cf_members3fooyySdFys5Int32V_SfSdtcSo10IAMStruct1Vcfu14_yAD_SfSdtcfu15_ : $@convention(thin) (Int32, Float, Double, Struct1) -> () { // CHECK: bb0([[X:%.*]] : $Int32, [[Y:%.*]] : $Float, [[Z:%.*]] : $Double, [[SELF:%.*]] : $Struct1): // CHECK: [[CFUNC:%.*]] = function_ref @IAMStruct1SelfComesThird // CHECK: apply [[CFUNC]]([[X]], [[Y]], [[SELF]], [[Z]]) diff --git a/test/SILGen/dynamic_self.swift b/test/SILGen/dynamic_self.swift index cc6c6bc74e2f6..80fdac58c6e9b 100644 --- a/test/SILGen/dynamic_self.swift +++ b/test/SILGen/dynamic_self.swift @@ -266,26 +266,18 @@ class Factory { // CHECK-LABEL: sil hidden [ossa] @$s12dynamic_self22partialApplySelfReturn1c1tyAA7FactoryC_AFmtF : $@convention(thin) (@guaranteed Factory, @thick Factory.Type) -> () func partialApplySelfReturn(c: Factory, t: Factory.Type) { - // CHECK: function_ref @$s12dynamic_self7FactoryC11newInstanceACXDyFTc : $@convention(thin) (@guaranteed Factory) -> @owned @callee_guaranteed () -> @owned Factory _ = c.newInstance - // CHECK: function_ref @$s12dynamic_self7FactoryC11newInstanceACXDyFTc : $@convention(thin) (@guaranteed Factory) -> @owned @callee_guaranteed () -> @owned Factory _ = Factory.newInstance - // CHECK: function_ref @$s12dynamic_self7FactoryC11newInstanceACXDyFTc : $@convention(thin) (@guaranteed Factory) -> @owned @callee_guaranteed () -> @owned Factory + _ = t.newInstance _ = type(of: c).newInstance - // CHECK: function_ref @$s12dynamic_self7FactoryC16classNewInstanceACXDyFZTc : $@convention(thin) (@thick Factory.Type) -> @owned @callee_guaranteed () -> @owned Factory _ = t.classNewInstance - // CHECK: function_ref @$s12dynamic_self7FactoryC16classNewInstanceACXDyFZTc : $@convention(thin) (@thick Factory.Type) -> @owned @callee_guaranteed () -> @owned Factory _ = type(of: c).classNewInstance - // CHECK: function_ref @$s12dynamic_self7FactoryC16classNewInstanceACXDyFZTc : $@convention(thin) (@thick Factory.Type) -> @owned @callee_guaranteed () -> @owned Factory _ = Factory.classNewInstance - // CHECK: function_ref @$s12dynamic_self7FactoryC17staticNewInstanceACXDyFZTc : $@convention(thin) (@thick Factory.Type) -> @owned @callee_guaranteed () -> @owned Factory _ = t.staticNewInstance - // CHECK: function_ref @$s12dynamic_self7FactoryC17staticNewInstanceACXDyFZTc : $@convention(thin) (@thick Factory.Type) -> @owned @callee_guaranteed () -> @owned Factory _ = type(of: c).staticNewInstance - // CHECK: function_ref @$s12dynamic_self7FactoryC17staticNewInstanceACXDyFZTc : $@convention(thin) (@thick Factory.Type) -> @owned @callee_guaranteed () -> @owned Factory _ = Factory.staticNewInstance } diff --git a/test/SILGen/enum.swift b/test/SILGen/enum.swift index 7f1fd191f09f9..e7d0b81bdbbda 100644 --- a/test/SILGen/enum.swift +++ b/test/SILGen/enum.swift @@ -26,26 +26,16 @@ enum Optionable { func Optionable_cases(_ x: Int) { // CHECK: [[METATYPE:%.*]] = metatype $@thin Optionable.Type - // CHECK: [[FN:%.*]] = function_ref @$s4enum10OptionableO4mereyACSicACmFTc - // CHECK-NEXT: [[CTOR:%.*]] = apply [[FN]]([[METATYPE]]) - // CHECK-NEXT: destroy_value [[CTOR]] + // CHECK: [[FN:%.*]] = function_ref @$s4enum16Optionable_casesyySiFAA0B0OSicADmcfu_ _ = Optionable.mere - // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin Optionable.Type - // CHECK-NEXT: [[RES:%.*]] = enum $Optionable, #Optionable.mere!enumelt.1, %0 : $Int + // CHECK: [[METATYPE:%.*]] = metatype $@thin Optionable.Type + // CHECK: [[RES:%.*]] = enum $Optionable, #Optionable.mere!enumelt.1, %0 : $Int _ = Optionable.mere(x) } -// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s4enum10OptionableO4mereyACSicACmF -// CHECK: [[FN:%.*]] = function_ref @$s4enum10OptionableO4mereyACSicACmF -// CHECK-NEXT: [[METHOD:%.*]] = partial_apply [callee_guaranteed] [[FN]](%0) -// CHECK-NEXT: return [[METHOD]] -// CHECK-NEXT: } - -// CHECK-LABEL: sil shared [transparent] [ossa] @$s4enum10OptionableO4mereyACSicACmF -// CHECK: [[RES:%.*]] = enum $Optionable, #Optionable.mere!enumelt.1, %0 : $Int -// CHECK-NEXT: return [[RES]] : $Optionable -// CHECK-NEXT: } +// CHECK-LABEL: sil private [ossa] @$s4enum16Optionable_casesyySiFAA0B0OSicADmcfu_ : $@convention(thin) (@thin Optionable.Type) -> @owned @callee_guaranteed (Int) -> Optionable +// CHECK-LABEL: sil private [ossa] @$s4enum16Optionable_casesyySiFAA0B0OSicADmcfu_ADSicfu0_ : $@convention(thin) (Int, @thin Optionable.Type) -> Optionable { protocol P {} struct S : P {} @@ -60,7 +50,7 @@ enum AddressOnly { func AddressOnly_cases(_ s: S) { // CHECK: [[METATYPE:%.*]] = metatype $@thin AddressOnly.Type - // CHECK: [[FN:%.*]] = function_ref @$s4enum11AddressOnlyO4mereyAcA1P_pcACmFTc + // CHECK: [[FN:%.*]] = function_ref @$s4enum17AddressOnly_casesyyAA1SVFAA0bC0OAA1P_pcAFmcfu_ // CHECK-NEXT: [[CTOR:%.*]] = apply [[FN]]([[METATYPE]]) // CHECK-NEXT: destroy_value [[CTOR]] _ = AddressOnly.mere @@ -99,23 +89,6 @@ func AddressOnly_cases(_ s: S) { // CHECK: return } -// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s4enum11AddressOnlyO4mereyAcA1P_pcACmFTc -// CHECK: [[FN:%.*]] = function_ref @$s4enum11AddressOnlyO4mereyAcA1P_pcACmF -// CHECK-NEXT: [[METHOD:%.*]] = partial_apply [callee_guaranteed] [[FN]](%0) -// CHECK-NEXT: // function_ref -// CHECK-NEXT: [[CANONICAL_THUNK_FN:%.*]] = function_ref @$s4enum1P_pAA11AddressOnlyOIegir_AaB_pADIegnr_TR : $@convention(thin) (@in_guaranteed P, @guaranteed @callee_guaranteed (@in P) -> @out AddressOnly) -> @out AddressOnly -// CHECK-NEXT: [[CANONICAL_THUNK:%.*]] = partial_apply [callee_guaranteed] [[CANONICAL_THUNK_FN]]([[METHOD]]) -// CHECK-NEXT: return [[CANONICAL_THUNK]] : $@callee_guaranteed (@in_guaranteed P) -> @out AddressOnly -// CHECK-NEXT: } - -// CHECK-LABEL: sil shared [transparent] [ossa] @$s4enum11AddressOnlyO4mereyAcA1P_pcACmF : $@convention -// CHECK: bb0([[ARG0:%.*]] : $*AddressOnly, [[ARG1:%.*]] : $*P, [[ARG2:%.*]] : $@thin AddressOnly.Type): -// CHECK: [[RET_DATA:%.*]] = init_enum_data_addr [[ARG0]] : $*AddressOnly, #AddressOnly.mere!enumelt.1 -// CHECK-NEXT: copy_addr [take] [[ARG1]] to [initialization] [[RET_DATA]] : $*P -// CHECK-NEXT: inject_enum_addr [[ARG0]] : $*AddressOnly, #AddressOnly.mere!enumelt.1 -// CHECK: return -// CHECK-NEXT: } // end sil function '$s4enum11AddressOnlyO4mereyAcA1P_pcACmF' - enum PolyOptionable { case nought case mere(T) @@ -172,29 +145,6 @@ struct String { var ptr: AnyObject } enum Foo { case a(P, String) } -// Curry Thunk for Foo.a(_:) -// -// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s4enum3FooO1ayAcA1P_p_AA6StringVtcACmFTc -// CHECK: [[FN:%.*]] = function_ref @$s4enum3FooO1ayAcA1P_p_AA6StringVtcACmF -// CHECK-NEXT: [[METHOD:%.*]] = partial_apply [callee_guaranteed] [[FN]](%0) -// CHECK-NEXT: // function_ref -// CHECK-NEXT: [[CANONICAL_THUNK_FN:%.*]] = function_ref @$s4enum1P_pAA6StringVAA3FooOIegixr_AaB_pAdFIegngr_TR : $@convention(thin) (@in_guaranteed P, @guaranteed String, @guaranteed @callee_guaranteed (@in P, @owned String) -> @out Foo) -> @out Foo -// CHECK-NEXT: [[CANONICAL_THUNK:%.*]] = partial_apply [callee_guaranteed] [[CANONICAL_THUNK_FN]]([[METHOD]]) -// CHECK-NEXT: return [[CANONICAL_THUNK]] -// CHECK-NEXT: } - -// Foo.a(_:) -// CHECK-LABEL: sil shared [transparent] [ossa] @$s4enum3FooO1ayAcA1P_p_AA6StringVtcACmF -// CHECK: bb0([[ARG0:%.*]] : $*Foo, [[ARG1:%.*]] : $*P, [[ARG2:%.*]] : @owned $String, [[ARG3:%.*]] : $@thin Foo.Type): -// CHECK: [[PAYLOAD:%.*]] = init_enum_data_addr [[ARG0]] : $*Foo, #Foo.a!enumelt.1 -// CHECK-NEXT: [[LEFT:%.*]] = tuple_element_addr [[PAYLOAD]] : $*(P, String), 0 -// CHECK-NEXT: [[RIGHT:%.*]] = tuple_element_addr [[PAYLOAD]] : $*(P, String), 1 -// CHECK-NEXT: copy_addr [take] [[ARG1]] to [initialization] [[LEFT]] : $*P -// CHECK-NEXT: store [[ARG2]] to [init] [[RIGHT]] -// CHECK-NEXT: inject_enum_addr [[ARG0]] : $*Foo, #Foo.a!enumelt.1 -// CHECK: return -// CHECK-NEXT: } // end sil function '$s4enum3FooO1ayAcA1P_p_AA6StringVtcACmF' - func Foo_cases() { _ = Foo.a } diff --git a/test/SILGen/enum_curry_thunks.swift b/test/SILGen/enum_curry_thunks.swift index 7325745b24f1f..f5edfd841cbe4 100644 --- a/test/SILGen/enum_curry_thunks.swift +++ b/test/SILGen/enum_curry_thunks.swift @@ -35,17 +35,12 @@ func partialApplyEnumCases(_ x: S, y: C) { _ = PartialApplyEnumPayload.autoclosure } -// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO4leftyACyxq_GxcAEmr0_lFTc : $@convention(thin) (@thin PartialApplyEnumPayload.Type) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2> (@in_guaranteed τ_0_0) -> @out PartialApplyEnumPayload<τ_0_1, τ_0_2> for { -// CHECK-LABEL: sil shared [transparent] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO4leftyACyxq_GxcAEmr0_lF : $@convention(method) (@in T, @thin PartialApplyEnumPayload.Type) -> @out PartialApplyEnumPayload { +// CHECK-LABEL: sil private [ossa] @$s17enum_curry_thunks21partialApplyEnumCases_1yyAA1SV_AA1CVtFAA07PartialeF7PayloadOyAeGGAEcAJmcfu_AjEcfu0_ : $@convention(thin) (S, @thin PartialApplyEnumPayload.Type) -> @owned PartialApplyEnumPayload { -// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO4bothyACyxq_Gx_q_tcAEmr0_lFTc : $@convention(thin) (@thin PartialApplyEnumPayload.Type) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2, τ_0_3> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> @out PartialApplyEnumPayload<τ_0_2, τ_0_3> for { -// CHECK-LABEL: sil shared [transparent] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO4bothyACyxq_Gx_q_tcAEmr0_lF : $@convention(method) (@in T, @in U, @thin PartialApplyEnumPayload.Type) -> @out PartialApplyEnumPayload { +// CHECK-LABEL: sil private [ossa] @$s17enum_curry_thunks21partialApplyEnumCases_1yyAA1SV_AA1CVtFAA07PartialeF7PayloadOyAeGGAE_AGtcAJmcfu1_AjE_AGtcfu2_ : $@convention(thin) (S, C, @thin PartialApplyEnumPayload.Type) -> @owned PartialApplyEnumPayload { -// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO13leftWithLabelyACyxq_Gx_tcAEmr0_lFTc : $@convention(thin) (@thin PartialApplyEnumPayload.Type) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2> (@in_guaranteed τ_0_0) -> @out PartialApplyEnumPayload<τ_0_1, τ_0_2> for { -// CHECK-LABEL: sil shared [transparent] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO13leftWithLabelyACyxq_Gx_tcAEmr0_lF : $@convention(method) (@in T, @thin PartialApplyEnumPayload.Type) -> @out PartialApplyEnumPayload { +// CHECK-LABEL: sil private [ossa] @$s17enum_curry_thunks21partialApplyEnumCases_1yyAA1SV_AA1CVtFAA07PartialeF7PayloadOyAeGGAEcAJmcfu3_AjEcfu4_ : $@convention(thin) (S, @thin PartialApplyEnumPayload.Type) -> @owned PartialApplyEnumPayload { -// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO14tupleWithLabelyACyxq_Gx_q_t_tcAEmr0_lFTc : $@convention(thin) (@thin PartialApplyEnumPayload.Type) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2, τ_0_3> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> @out PartialApplyEnumPayload<τ_0_2, τ_0_3> for { -// CHECK-LABEL: sil shared [transparent] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO14tupleWithLabelyACyxq_Gx_q_t_tcAEmr0_lF : $@convention(method) (@in T, @in U, @thin PartialApplyEnumPayload.Type) -> @out PartialApplyEnumPayload { +// CHECK-LABEL: sil private [ossa] @$s17enum_curry_thunks21partialApplyEnumCases_1yyAA1SV_AA1CVtFAA07PartialeF7PayloadOyAeGGAE_AGt_tcAJmcfu5_AjE_AGt_tcfu6_ : $@convention(thin) (S, C, @thin PartialApplyEnumPayload.Type) -> @owned PartialApplyEnumPayload { -// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO11autoclosureyACyxq_GyyXAcAEmr0_lFTc : $@convention(thin) (@thin PartialApplyEnumPayload.Type) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@guaranteed @callee_guaranteed () -> ()) -> @out PartialApplyEnumPayload<τ_0_0, τ_0_1> for { -// CHECK-LABEL: sil shared [transparent] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO11autoclosureyACyxq_GyyXAcAEmr0_lF : $@convention(method) (@owned @callee_guaranteed () -> (), @thin PartialApplyEnumPayload.Type) -> @out PartialApplyEnumPayload { +// CHECK-LABEL: sil private [ossa] @$s17enum_curry_thunks21partialApplyEnumCases_1yyAA1SV_AA1CVtFAA07PartialeF7PayloadOyAeGGyyXAcAJmcfu7_AJyyXAcfu8_ : $@convention(thin) (@guaranteed @callee_guaranteed () -> (), @thin PartialApplyEnumPayload.Type) -> @owned PartialApplyEnumPayload { diff --git a/test/SILGen/extensions.swift b/test/SILGen/extensions.swift index db5940e163534..f9105b69d9923 100644 --- a/test/SILGen/extensions.swift +++ b/test/SILGen/extensions.swift @@ -37,9 +37,6 @@ func extensionMethodCurrying(_ x: Foo) { _ = x.zang } -// CHECK-LABEL: sil shared [thunk] [ossa] @$s10extensions3FooC4zang{{[_0-9a-zA-Z]*}}F -// CHECK: function_ref @$s10extensions3FooC4zang{{[_0-9a-zA-Z]*}}F - // Extensions of generic types with stored property initializers // CHECK-LABEL: sil hidden [transparent] [ossa] @$s10extensions3BoxV1txSgvpfi : $@convention(thin) () -> @out Optional diff --git a/test/SILGen/extensions_objc.swift b/test/SILGen/extensions_objc.swift index 3a289acb6f718..79a737989a344 100644 --- a/test/SILGen/extensions_objc.swift +++ b/test/SILGen/extensions_objc.swift @@ -28,9 +28,9 @@ func extensionMethodCurrying(_ x: Foo) { _ = x.kay } -// CHECK-LABEL: sil shared [thunk] [ossa] @$s15extensions_objc3FooC3kayyyFTc -// CHECK: function_ref @$s15extensions_objc3FooC3kayyyFTD -// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$s15extensions_objc3FooC3kayyyFTD -// CHECK: bb0([[SELF:%.*]] : @guaranteed $Foo): -// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] -// CHECK: objc_method [[SELF_COPY]] : $Foo, #Foo.kay!1.foreign +// CHECK-LABEL: sil private [ossa] @$s15extensions_objc23extensionMethodCurryingyyAA3FooCFyycADcfu_ : $@convention(thin) (@guaranteed Foo) -> @owned @callee_guaranteed () -> () { +// CHECK: function_ref @$s15extensions_objc23extensionMethodCurryingyyAA3FooCFyycADcfu_yycfu0_ : $@convention(thin) (@guaranteed Foo) -> () + +// CHECK-LABEL: sil private [ossa] @$s15extensions_objc23extensionMethodCurryingyyAA3FooCFyycADcfu_yycfu0_ : $@convention(thin) (@guaranteed Foo) -> () { +// CHECK: objc_method %0 : $Foo, #Foo.kay!1.foreign : (Foo) -> () -> (), $@convention(objc_method) (Foo) -> () + diff --git a/test/SILGen/foreign_errors.swift b/test/SILGen/foreign_errors.swift index 436193992dfad..410f4688a9df8 100644 --- a/test/SILGen/foreign_errors.swift +++ b/test/SILGen/foreign_errors.swift @@ -148,15 +148,15 @@ extension NSObject { } let fn = ErrorProne.fail -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo10ErrorProneC4failyyKFZTcTO : $@convention(thin) (@thick ErrorProne.Type) -> @owned @callee_guaranteed () -> @error Error -// CHECK: [[T0:%.*]] = function_ref @$sSo10ErrorProneC4failyyKFZTO : $@convention(method) (@thick ErrorProne.Type) -> @error Error +// CHECK-LABEL: sil private [ossa] @$s14foreign_errors2fnyyKcvpfiyyKcSo10ErrorProneCmcfu_ : $@convention(thin) (@thick ErrorProne.Type) -> @owned @callee_guaranteed () -> @error Error { +// CHECK: [[T0:%.*]] = function_ref @$s14foreign_errors2fnyyKcvpfiyyKcSo10ErrorProneCmcfu_yyKcfu0_ : $@convention(thin) (@thick ErrorProne.Type) -> @error Error // CHECK-NEXT: [[T1:%.*]] = partial_apply [callee_guaranteed] [[T0]](%0) // CHECK-NEXT: return [[T1]] -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo10ErrorProneC4failyyKFZTO : $@convention(method) (@thick ErrorProne.Type) -> @error Error { -// CHECK: [[SELF:%.*]] = thick_to_objc_metatype %0 : $@thick ErrorProne.Type to $@objc_metatype ErrorProne.Type -// CHECK: [[METHOD:%.*]] = objc_method [[T0]] : $@objc_metatype ErrorProne.Type, #ErrorProne.fail!1.foreign : (ErrorProne.Type) -> () throws -> (), $@convention(objc_method) (Optional>>, @objc_metatype ErrorProne.Type) -> ObjCBool +// CHECK-LABEL: sil private [ossa] @$s14foreign_errors2fnyyKcvpfiyyKcSo10ErrorProneCmcfu_yyKcfu0_ : $@convention(thin) (@thick ErrorProne.Type) -> @error Error { // CHECK: [[TEMP:%.*]] = alloc_stack $Optional +// CHECK: [[SELF:%.*]] = thick_to_objc_metatype %0 : $@thick ErrorProne.Type to $@objc_metatype ErrorProne.Type +// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $@objc_metatype ErrorProne.Type, #ErrorProne.fail!1.foreign : (ErrorProne.Type) -> () throws -> (), $@convention(objc_method) (Optional>>, @objc_metatype ErrorProne.Type) -> ObjCBool // CHECK: [[RESULT:%.*]] = apply [[METHOD]]({{%.*}}, [[SELF]]) // CHECK: cond_br // CHECK: return diff --git a/test/SILGen/functions.swift b/test/SILGen/functions.swift index 5b0f921dc5199..7b96181178e61 100644 --- a/test/SILGen/functions.swift +++ b/test/SILGen/functions.swift @@ -131,8 +131,7 @@ func calls(_ i:Int, j:Int, k:Int) { // -- Use of unapplied struct methods as values. - // CHECK: [[THUNK:%.*]] = function_ref @$s9functions10SomeStructV6method{{[_0-9a-zA-Z]*}}F - // CHECK: [[THUNK_THICK:%.*]] = thin_to_thick_function [[THUNK]] + // CHECK: [[THUNK:%.*]] = function_ref @$s9functions5calls_1j1kyBi64__Bi64_Bi64_tFyBi64_cAA10SomeStructVzcfu_ var stm1 = SomeStruct.method stm1(&st)(i) @@ -159,18 +158,13 @@ func calls(_ i:Int, j:Int, k:Int) { c.method(i) // -- Curry 'self' onto unapplied methods dispatched using class_method. - // CHECK: [[METHOD_CURRY_THUNK:%.*]] = function_ref @$s9functions9SomeClassC6method{{[_0-9a-zA-Z]*}}F + // CHECK: [[METHOD_CURRY_THUNK:%.*]] = function_ref @$s9functions5calls_1j1kyBi64__Bi64_Bi64_tFyBi64_cAA9SomeClassCcfu1_ // CHECK: apply [[METHOD_CURRY_THUNK]] var cm1 = SomeClass.method(c) cm1(i) - // CHECK: [[READC:%.*]] = begin_access [read] [unknown] [[CADDR]] - // CHECK: [[C:%[0-9]+]] = load [copy] [[READC]] - // CHECK: [[READI:%.*]] = begin_access [read] [unknown] [[IADDR]] - // CHECK: [[I:%[0-9]+]] = load [trivial] [[READI]] - // CHECK: [[METHOD:%[0-9]+]] = class_method [[C]] : {{.*}}, #SomeClass.method!1 - // CHECK: apply [[METHOD]]([[I]], [[C]]) - // CHECK: destroy_value [[C]] + // CHECK: [[METHOD_CURRY_THUNK:%.*]] = function_ref @$s9functions5calls_1j1kyBi64__Bi64_Bi64_tFyBi64_cAA9SomeClassCcfu3_ + // CHECK: apply [[METHOD_CURRY_THUNK]] SomeClass.method(c)(i) // -- Curry the Type onto static method argument lists. @@ -355,17 +349,11 @@ func calls(_ i:Int, j:Int, k:Int) { } // -- Curried entry points -// CHECK-LABEL: sil shared [thunk] [ossa] @$s9functions10SomeStructV6method{{[_0-9a-zA-Z]*}}FTc : $@convention(thin) (@inout SomeStruct) -> @owned @callee_guaranteed (Builtin.Int64) -> () { -// CHECK: [[UNCURRIED:%.*]] = function_ref @$s9functions10SomeStructV6method{{[_0-9a-zA-Z]*}}F : $@convention(method) (Builtin.Int64, @inout SomeStruct) -> (){{.*}} // user: %2 -// CHECK: [[CURRIED:%.*]] = partial_apply [callee_guaranteed] [[UNCURRIED]] -// CHECK: return [[CURRIED]] - -// CHECK-LABEL: sil shared [thunk] [ossa] @$s9functions9SomeClassC6method{{[_0-9a-zA-Z]*}}FTc : $@convention(thin) (@guaranteed SomeClass) -> @owned @callee_guaranteed (Builtin.Int64) -> () -// CHECK: bb0(%0 : @guaranteed $SomeClass): -// CHECK: class_method %0 : $SomeClass, #SomeClass.method!1 : (SomeClass) -> (Builtin.Int64) -> () -// CHECK: %2 = copy_value %0 : $SomeClass -// CHECK: %3 = partial_apply [callee_guaranteed] %1(%2) -// CHECK: return %3 +// CHECK-LABEL: sil private [ossa] @$s9functions5calls_1j1kyBi64__Bi64_Bi64_tFyBi64_cAA10SomeStructVzcfu_yBi64_cfu0_ : $@convention(thin) (Builtin.Int64, @inout_aliasable SomeStruct) -> () { +// CHECK: function_ref @$s9functions10SomeStructV6methodyyBi64_F : $@convention(method) (Builtin.Int64, @inout SomeStruct) -> () + +// CHECK-LABEL: sil private [ossa] @$s9functions5calls_1j1kyBi64__Bi64_Bi64_tFyBi64_cAA9SomeClassCcfu1_yBi64_cfu2_ : $@convention(thin) (Builtin.Int64, @guaranteed SomeClass) -> () +// CHECK: class_method %1 : $SomeClass, #SomeClass.method!1 : (SomeClass) -> (Builtin.Int64) -> (), $@convention(method) (Builtin.Int64, @guaranteed SomeClass) -> () func return_func() -> (_ x: Builtin.Int64, _ y: Builtin.Int64) -> Builtin.Int64 { // CHECK: [[FUNC_THIN:%[0-9]+]] = function_ref @$s9functions19standalone_function{{[_0-9a-zA-Z]*}}F : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> Builtin.Int64 @@ -466,14 +454,9 @@ final class r17828355Class { } // The curry thunk for the method should not include a class_method instruction. -// CHECK-LABEL: sil shared [thunk] [ossa] @$s9functions14r17828355ClassC6method -// CHECK: bb0(%0 : @guaranteed $r17828355Class): -// CHECK-NEXT: // function_ref functions.r17828355Class.method(Builtin.Int64) -> () -// CHECK-NEXT: %1 = function_ref @$s9functions14r17828355ClassC6method{{[_0-9a-zA-Z]*}}F : $@convention(method) (Builtin.Int64, @guaranteed r17828355Class) -> () -// CHECK-NEXT: %2 = copy_value %0 -// CHECK-NEXT: partial_apply [callee_guaranteed] %1(%2) : $@convention(method) (Builtin.Int64, @guaranteed r17828355Class) -> () -// CHECK-NEXT: return - +// CHECK-LABEL: sil private [ossa] @$s9functions14r17828355ClassC6methodyyBi64_FyBi64_cACcfu_yBi64_cfu0_ : $@convention(thin) (Builtin.Int64, @guaranteed r17828355Class) -> () { +// CHECK: function_ref @$s9functions14r17828355ClassC6methodyyBi64_F : $@convention(method) (Builtin.Int64, @guaranteed r17828355Class) -> () +// CHECK: } // Swift 1.2 beta 2: Closures nested in closures copy, rather than reference, captured vars. diff --git a/test/SILGen/guaranteed_normal_args_curry_thunks.swift b/test/SILGen/guaranteed_normal_args_curry_thunks.swift index 484efb026e713..4060edc500b66 100644 --- a/test/SILGen/guaranteed_normal_args_curry_thunks.swift +++ b/test/SILGen/guaranteed_normal_args_curry_thunks.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-emit-silgen -parse-as-library -module-name Swift -parse-stdlib %s | %FileCheck %s +// RUN: %target-swift-emit-silgen -parse-as-library -module-name Swift -parse-stdlib %s // This test checks specific codegen related to converting curry thunks to // canonical representations when we are emitting guaranteed normal @@ -97,172 +97,21 @@ struct AddrOnlyStructInitGeneric { // Tests // /////////// -// CHECK-LABEL: sil hidden [ossa] @$ss021testLoadableClassInitB0yyF : $@convention(thin) () -> () { -// CHECK: bb0: -// CHECK: [[THUNK_REF:%.*]] = function_ref @$ss017LoadableClassInitA0CyABs5KlassCcfCTcTd : $@convention(thin) (@thick LoadableClassInitLoadable.Type) -> @owned @callee_guaranteed (@guaranteed Klass) -> @owned LoadableClassInitLoadable -// CHECK: [[CANONICAL_THUNK:%.*]] = apply [[THUNK_REF]]( -// CHECK: [[BORROWED_CANONICAL_THUNK:%.*]] = begin_borrow [[CANONICAL_THUNK]] -// CHECK: [[BORROWED_CANONICAL_THUNK_COPY:%.*]] = copy_value [[BORROWED_CANONICAL_THUNK]] -// CHECK: [[ALLOCATING_INIT:%.*]] = function_ref @$ss5KlassCABycfC : $@convention(method) (@thick Klass.Type) -> @owned Klass -// CHECK: [[SELF:%.*]] = apply [[ALLOCATING_INIT]]( -// CHECK: [[BORROWED_CANONICAL_THUNK:%.*]] = begin_borrow [[BORROWED_CANONICAL_THUNK_COPY]] -// CHECK: apply [[BORROWED_CANONICAL_THUNK]]([[SELF]]) -// CHECK: } // end sil function '$ss021testLoadableClassInitB0yyF' +// There used to be FileCheck tests here. Now that curry thunks are built +// in CSApply, there's no point writing them out in great detail again. +// Let's just make sure we don't hit any assertions or SIL verifier +// failures. -// Curry thunk. -// -// CHECK-LABEL: sil shared [thunk] [ossa] @$ss017LoadableClassInitA0CyABs5KlassCcfCTcTd : $@convention(thin) (@thick LoadableClassInitLoadable.Type) -> @owned @callee_guaranteed (@guaranteed Klass) -> @owned LoadableClassInitLoadable { -// CHECK: [[ALLOCATING_INIT_FN:%.*]] = function_ref @$ss017LoadableClassInitA0CyABs5KlassCcfC : -// CHECK: [[METATYPE_PA_ALLOCATING_INIT_FN:%.*]] = partial_apply [callee_guaranteed] [[ALLOCATING_INIT_FN]]( -// CHECK: [[THUNK_FN:%.*]] = function_ref @$ss5KlassCs017LoadableClassInitB0CIegxo_AbDIeggo_TR : -// CHECK: [[THUNK_PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]([[METATYPE_PA_ALLOCATING_INIT_FN]]) : $@convention(thin) (@guaranteed Klass, @guaranteed @callee_guaranteed (@owned Klass) -> @owned LoadableClassInitLoadable) -> @owned LoadableClassInitLoadable -// CHECK: return [[THUNK_PA]] -// CHECK: } // end sil function '$ss017LoadableClassInitA0CyABs5KlassCcfCTcTd' - -// Reabstraction thunk. -// -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$ss5KlassCs017LoadableClassInitB0CIegxo_AbDIeggo_TR : $@convention(thin) (@guaranteed Klass, @guaranteed @callee_guaranteed (@owned Klass) -> @owned LoadableClassInitLoadable) -> @owned LoadableClassInitLoadable { -// CHECK: bb0([[CLASS:%.*]] : @guaranteed $Klass, [[PA:%.*]] : @guaranteed $@callee_guaranteed (@owned Klass) -> @owned LoadableClassInitLoadable): -// CHECK: [[CLASS_COPY:%.*]] = copy_value [[CLASS]] -// CHECK: [[RESULT:%.*]] = apply [[PA]]([[CLASS_COPY]]) -// CHECK: return [[RESULT]] -// CHECK: } // end sil function '$ss5KlassCs017LoadableClassInitB0CIegxo_AbDIeggo_TR' -func testLoadableClassInitLoadable() { - let x = LoadableClassInitLoadable.init - let y = x(Klass()) -} - -// CHECK-LABEL: sil hidden [ossa] @$ss022testLoadableStructInitB0yyF : $@convention(thin) () -> () { -// CHECK: [[THUNK_REF:%.*]] = function_ref @$ss018LoadableStructInitA0VyABs5KlassCcfCTc : $@convention(thin) (@thin LoadableStructInitLoadable.Type) -> @owned @callee_guaranteed (@guaranteed Klass) -> @owned LoadableStructInitLoadable -// CHECK: [[CANONICAL_THUNK:%.*]] = apply [[THUNK_REF]]( -// CHECK: [[BORROWED_CANONICAL_THUNK:%.*]] = begin_borrow [[CANONICAL_THUNK]] -// CHECK: [[BORROWED_CANONICAL_THUNK_COPY:%.*]] = copy_value [[BORROWED_CANONICAL_THUNK]] -// CHECK: [[ALLOCATING_INIT:%.*]] = function_ref @$ss5KlassCABycfC : $@convention(method) (@thick Klass.Type) -> @owned Klass -// CHECK: [[SELF:%.*]] = apply [[ALLOCATING_INIT]]( -// CHECK: [[BORROWED_CANONICAL_THUNK:%.*]] = begin_borrow [[BORROWED_CANONICAL_THUNK_COPY]] -// CHECK: apply [[BORROWED_CANONICAL_THUNK]]([[SELF]]) -// CHECK: } // end sil function '$ss022testLoadableStructInitB0yyF' - -// Curry thunk. -// -// CHECK-LABEL: sil shared [thunk] [ossa] @$ss018LoadableStructInitA0VyABs5KlassCcfCTc : $@convention(thin) (@thin LoadableStructInitLoadable.Type) -> @owned @callee_guaranteed (@guaranteed Klass) -> @owned LoadableStructInitLoadable { -// CHECK: [[ALLOCATING_INIT_FN:%.*]] = function_ref @$ss018LoadableStructInitA0VyABs5KlassCcfC : -// CHECK: [[METATYPE_PA_ALLOCATING_INIT_FN:%.*]] = partial_apply [callee_guaranteed] [[ALLOCATING_INIT_FN]]( -// CHECK: [[THUNK_FN:%.*]] = function_ref @$ss5KlassCs018LoadableStructInitB0VIegxo_AbDIeggo_TR : $@convention(thin) (@guaranteed Klass, @guaranteed @callee_guaranteed (@owned Klass) -> @owned LoadableStructInitLoadable) -> @owned LoadableStructInitLoadable -// CHECK: [[THUNK_PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]([[METATYPE_PA_ALLOCATING_INIT_FN]]) -// CHECK: return [[THUNK_PA]] -// CHECK: } // end sil function '$ss018LoadableStructInitA0VyABs5KlassCcfCTc' - -// Reabstraction thunk. -// -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$ss5KlassCs018LoadableStructInitB0VIegxo_AbDIeggo_TR : $@convention(thin) (@guaranteed Klass, @guaranteed @callee_guaranteed (@owned Klass) -> @owned LoadableStructInitLoadable) -> @owned LoadableStructInitLoadable { -// CHECK: bb0([[CLASS:%.*]] : @guaranteed $Klass, [[PA:%.*]] : @guaranteed $@callee_guaranteed (@owned Klass) -> @owned LoadableStructInitLoadable): -// CHECK: [[CLASS_COPY:%.*]] = copy_value [[CLASS]] -// CHECK: [[RESULT:%.*]] = apply [[PA]]([[CLASS_COPY]]) -// CHECK: return [[RESULT]] -// CHECK: } // end sil function '$ss5KlassCs018LoadableStructInitB0VIegxo_AbDIeggo_TR' -func testLoadableStructInitLoadable() { - let x = LoadableStructInitLoadable.init - let y = x(Klass()) -} - -// In this case we have a generic type that due to type lowering introduces an -// extra thunk. -// -// CHECK-LABEL: sil hidden [ossa] @$ss37testAddrOnlyStructInitGenericConcreteyyF : $@convention(thin) () -> () { -// CHECK: [[THUNK_REF:%.*]] = function_ref @$ss25AddrOnlyStructInitGenericVyAByxGxcfCTc : $@convention(thin) <τ_0_0> (@thin AddrOnlyStructInitGeneric<τ_0_0>.Type) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out AddrOnlyStructInitGeneric<τ_0_1> for <τ_0_0, τ_0_0> -// CHECK: [[CURRY_THUNK:%.*]] = apply [[THUNK_REF]]( -// CHECK: [[CURRY_THUNK_CONV:%.*]] = convert_function [[CURRY_THUNK]] -// CHECK: [[CANONICAL_THUNK_REF:%.*]] = function_ref @$ss5KlassCs25AddrOnlyStructInitGenericVyABGIegnr_AbEIeggo_TR : $@convention(thin) (@guaranteed Klass, @guaranteed @callee_guaranteed (@in_guaranteed Klass) -> @out AddrOnlyStructInitGeneric) -> @owned AddrOnlyStructInitGeneric -// CHECK: [[CANONICAL_THUNK:%.*]] = partial_apply [callee_guaranteed] [[CANONICAL_THUNK_REF]]([[CURRY_THUNK_CONV]]) : -// CHECK: [[BORROWED_CANONICAL_THUNK:%.*]] = begin_borrow [[CANONICAL_THUNK]] -// CHECK: [[BORROWED_CANONICAL_THUNK_COPY:%.*]] = copy_value [[BORROWED_CANONICAL_THUNK]] -// CHECK: [[ALLOCATING_INIT:%.*]] = function_ref @$ss5KlassCABycfC : $@convention(method) (@thick Klass.Type) -> @owned Klass -// CHECK: [[SELF:%.*]] = apply [[ALLOCATING_INIT]]( -// CHECK: [[BORROWED_CANONICAL_THUNK:%.*]] = begin_borrow [[BORROWED_CANONICAL_THUNK_COPY]] -// CHECK: apply [[BORROWED_CANONICAL_THUNK]]([[SELF]]) - -// Curry thunk -// -// CHECK-LABEL: sil shared [thunk] [ossa] @$ss25AddrOnlyStructInitGenericVyAByxGxcfCTc : $@convention(thin) (@thin AddrOnlyStructInitGeneric.Type) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out AddrOnlyStructInitGeneric<τ_0_1> for { -// CHECK: [[ALLOCATING_INIT_REF:%.*]] = function_ref @$ss25AddrOnlyStructInitGenericVyAByxGxcfC : $@convention(method) <τ_0_0> (@in τ_0_0, @thin AddrOnlyStructInitGeneric<τ_0_0>.Type) -> @out AddrOnlyStructInitGeneric<τ_0_0> -// CHECK: [[ALLOCATING_INIT:%.*]] = partial_apply [callee_guaranteed] [[ALLOCATING_INIT_REF]]( -// CHECK: [[THUNK_REF:%.*]] = function_ref @$sxs25AddrOnlyStructInitGenericVyxGIegir_xACIegnr_lTR : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0, @guaranteed @callee_guaranteed (@in τ_0_0) -> @out AddrOnlyStructInitGeneric<τ_0_0>) -> @out AddrOnlyStructInitGeneric<τ_0_0> -// CHECK: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_REF]]([[ALLOCATING_INIT]]) -// CHECK: [[CONV:%.*]] = convert_function [[THUNK]] -// CHECK: return [[CONV]] -// CHECK: } // end sil function '$ss25AddrOnlyStructInitGenericVyAByxGxcfCTc' - -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sxs25AddrOnlyStructInitGenericVyxGIegir_xACIegnr_lTR : $@convention(thin) (@in_guaranteed T, @guaranteed @callee_guaranteed (@in T) -> @out AddrOnlyStructInitGeneric) -> @out AddrOnlyStructInitGeneric { -// CHECK: bb0([[ARG0:%.*]] : $*AddrOnlyStructInitGeneric, [[ARG1:%.*]] : $*T, [[ARG2:%.*]] : @guaranteed $@callee_guaranteed (@in T) -> @out AddrOnlyStructInitGeneric): -// CHECK: [[STACK:%.*]] = alloc_stack $T -// CHECK: copy_addr [[ARG1]] to [initialization] [[STACK]] : $*T -// CHECK: apply [[ARG2]]([[ARG0]], [[STACK]]) : $@callee_guaranteed (@in T) -> @out AddrOnlyStructInitGeneric -// CHECK: } // end sil function '$sxs25AddrOnlyStructInitGenericVyxGIegir_xACIegnr_lTR' - -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$ss5KlassCs25AddrOnlyStructInitGenericVyABGIegnr_AbEIeggo_TR : $@convention(thin) (@guaranteed Klass, @guaranteed @callee_guaranteed (@in_guaranteed Klass) -> @out AddrOnlyStructInitGeneric) -> @owned AddrOnlyStructInitGeneric { -// CHECK: bb0([[ARG0:%.*]] : @guaranteed $Klass, [[ARG1:%.*]] : @guaranteed $@callee_guaranteed (@in_guaranteed Klass) -> @out AddrOnlyStructInitGeneric): -// CHECK: [[STACK:%.*]] = alloc_stack $Klass -// CHECK: [[ARG0_COPY:%.*]] = copy_value [[ARG0]] -// CHECK: store [[ARG0_COPY]] to [init] [[STACK]] -// CHECK: [[STACK2:%.*]] = alloc_stack $AddrOnlyStructInitGeneric -// CHECK: apply [[ARG1]]([[STACK2]], [[STACK]]) : $@callee_guaranteed (@in_guaranteed Klass) -> @out AddrOnlyStructInitGeneric -// CHECK: [[RESULT:%.*]] = load [take] [[STACK2]] -// CHECK: destroy_addr [[STACK]] -// CHECK: return [[RESULT]] -// CHECK: } // end sil function '$ss5KlassCs25AddrOnlyStructInitGenericVyABGIegnr_AbEIeggo_TR' func testAddrOnlyStructInitGenericConcrete() { let x = AddrOnlyStructInitGeneric.init let y = x(Klass()) } -// CHECK-LABEL: sil hidden [ossa] @$ss029testAddrOnlyStructInitGenericbC01tyx_ts08Protocole7AddressC0RzlF : $@convention(thin) (@in_guaranteed T) -> () { -// CHECK: [[CURRY_THUNK_REF:%.*]] = function_ref @$ss25AddrOnlyStructInitGenericVyAByxGxcfCTc : $@convention(thin) <τ_0_0> (@thin AddrOnlyStructInitGeneric<τ_0_0>.Type) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out AddrOnlyStructInitGeneric<τ_0_1> for <τ_0_0, τ_0_0> -// CHECK: [[CURRY_THUNK:%.*]] = apply [[CURRY_THUNK_REF]]( -// CHECK: [[Y:%.*]] = alloc_stack $AddrOnlyStructInitGeneric, let, name "y" -// CHECK: [[BORROWED_CURRY_THUNK:%.*]] = begin_borrow [[CURRY_THUNK]] -// CHECK: [[COPY_BORROWED_CURRY_THUNK:%.*]] = copy_value [[BORROWED_CURRY_THUNK]] -// CHECK: [[TMP:%.*]] = alloc_stack $T.SubType -// CHECK: [[WITNESS_METHOD:%.*]] = witness_method $T.SubType, #ProtocolInitNoArg.init!allocator.1 : (Self.Type) -> () -> Self : $@convention(witness_method: ProtocolInitNoArg) <τ_0_0 where τ_0_0 : ProtocolInitNoArg> (@thick τ_0_0.Type) -> @out τ_0_0 -// CHECK: apply [[WITNESS_METHOD]]([[TMP]], -// CHECK: [[BORROWED_CURRY_THUNK:%.*]] = begin_borrow [[COPY_BORROWED_CURRY_THUNK]] -// CHECK: apply [[BORROWED_CURRY_THUNK]]([[Y]], [[TMP]]) -// CHECK: } // end sil function '$ss029testAddrOnlyStructInitGenericbC01tyx_ts08Protocole7AddressC0RzlF' func testAddrOnlyStructInitGenericAddrOnly(t: T) { let x = AddrOnlyStructInitGeneric.init let y = x(T.SubType()) } -// CHECK-LABEL: sil hidden [ossa] @$ss20testGenericInitClass1tyx_ts08ProtocolC8LoadableRzlF : $@convention(thin) (@in_guaranteed T) -> () { -// CHECK: [[CURRY_THUNK_REF:%.*]] = function_ref @$ss20ProtocolInitLoadableP1txs5KlassC_tcfCTc : $@convention(thin) <τ_0_0 where τ_0_0 : ProtocolInitLoadable> (@thick τ_0_0.Type) -> @owned @callee_guaranteed @substituted <τ_0_0> (@guaranteed Klass) -> @out τ_0_0 for <τ_0_0> -// CHECK: [[CURRY_THUNK:%.*]] = apply [[CURRY_THUNK_REF]]( -// CHECK: [[Y:%.*]] = alloc_stack $T, let, name "y" -// CHECK: [[BORROWED_CURRY_THUNK:%.*]] = begin_borrow [[CURRY_THUNK]] -// CHECK: [[COPY_BORROWED_CURRY_THUNK:%.*]] = copy_value [[BORROWED_CURRY_THUNK]] -// CHECK: [[ALLOCATING_INIT:%.*]] = function_ref @$ss5KlassCABycfC : $@convention(method) (@thick Klass.Type) -> @owned Klass -// CHECK: [[SELF:%.*]] = apply [[ALLOCATING_INIT]]( -// CHECK: [[BORROWED_CURRY_THUNK:%.*]] = begin_borrow [[COPY_BORROWED_CURRY_THUNK]] -// CHECK: apply [[BORROWED_CURRY_THUNK]]([[Y]], [[SELF]]) -// CHECK: } // end sil function '$ss20testGenericInitClass1tyx_ts08ProtocolC8LoadableRzlF' - -// Curry thunk. -// -// CHECK-LABEL: sil shared [thunk] [ossa] @$ss20ProtocolInitLoadableP1txs5KlassC_tcfCTc : $@convention(thin) (@thick Self.Type) -> @owned @callee_guaranteed @substituted <τ_0_0> (@guaranteed Klass) -> @out τ_0_0 for { -// CHECK: [[WITNESS_METHOD_REF:%.*]] = witness_method $Self, #ProtocolInitLoadable.init!allocator.1 : (Self.Type) -> (Klass) -> Self : $@convention(witness_method: ProtocolInitLoadable) <τ_0_0 where τ_0_0 : ProtocolInitLoadable> (@owned Klass, @thick τ_0_0.Type) -> @out τ_0_0 -// CHECK: [[WITNESS_METHOD:%.*]] = partial_apply [callee_guaranteed] [[WITNESS_METHOD_REF]]( -// CHECK: [[CANONICAL_THUNK_REF:%.*]] = function_ref @$ss5KlassCxIegxr_ABxIeggr_s20ProtocolInitLoadableRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : ProtocolInitLoadable> (@guaranteed Klass, @guaranteed @callee_guaranteed (@owned Klass) -> @out τ_0_0) -> @out τ_0_0 -// CHECK: [[CANONICAL_THUNK:%.*]] = partial_apply [callee_guaranteed] %3(%2) : $@convention(thin) <τ_0_0 where τ_0_0 : ProtocolInitLoadable> (@guaranteed Klass, @guaranteed @callee_guaranteed (@owned Klass) -> @out τ_0_0) -> @out τ_0_0 -// CHECK: [[THUNK_CONV:%.*]] = convert_function [[CANONICAL_THUNK]] -// CHECK: return [[THUNK_CONV]] -// CHECK: } // end sil function '$ss20ProtocolInitLoadableP1txs5KlassC_tcfCTc' - -// Reabstraction thunk. -// -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$ss5KlassCxIegxr_ABxIeggr_s20ProtocolInitLoadableRzlTR : $@convention(thin) (@guaranteed Klass, @guaranteed @callee_guaranteed (@owned Klass) -> @out Self) -> @out Self { -// CHECK: bb0([[ARG0:%.*]] : $*Self, [[ARG1:%.*]] : @guaranteed $Klass, [[ARG2:%.*]] : @guaranteed $@callee_guaranteed (@owned Klass) -> @out Self): -// CHECK: [[ARG1_COPY:%.*]] = copy_value [[ARG1]] -// CHECK: apply [[ARG2]]([[ARG0]], [[ARG1_COPY]]) -// CHECK: } // end sil function '$ss5KlassCxIegxr_ABxIeggr_s20ProtocolInitLoadableRzlTR' func testGenericInitClass(t: T) { let x = T.init let y = x(Klass()) diff --git a/test/SILGen/inlinable_attribute.swift b/test/SILGen/inlinable_attribute.swift index 2714d69c8ee30..8f160e7d29a72 100644 --- a/test/SILGen/inlinable_attribute.swift +++ b/test/SILGen/inlinable_attribute.swift @@ -43,7 +43,8 @@ public class MyCls { case c(MySt) } -// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$s19inlinable_attribute6MyEnumO1cyAcA0C2StVcACmFTc : $@convention(thin) (@thin MyEnum.Type) -> @owned @callee_guaranteed (MySt) -> MyEnum +// CHECK-LABEL: sil shared [serialized] [ossa] @$s19inlinable_attribute16referencesMyEnumyyFAA0dE0OAA0D2StVcADmcfu_ : $@convention(thin) (@thin MyEnum.Type) -> @owned @callee_guaranteed (MySt) -> MyEnum { +// CHECK-LABEL: sil shared [serialized] [ossa] @$s19inlinable_attribute16referencesMyEnumyyFAA0dE0OAA0D2StVcADmcfu_AdFcfu0_ : $@convention(thin) (MySt, @thin MyEnum.Type) -> MyEnum { @inlinable public func referencesMyEnum() { _ = MyEnum.c @@ -64,13 +65,13 @@ public class Horse { public func gallop() {} } -// CHECK-LABEL: sil [serialized] [ossa] @$s19inlinable_attribute15talkAboutAHorse1hyAA5HorseC_tF : $@convention(thin) (@guaranteed Horse) -> () { -// CHECK: function_ref @$s19inlinable_attribute5HorseC6gallopyyFTc +// CHECK-LABEL: sil shared [serialized] [ossa] @$s19inlinable_attribute15talkAboutAHorse1hyAA5HorseC_tFyycAEcfu_ : $@convention(thin) (@guaranteed Horse) -> @owned @callee_guaranteed () -> () { +// CHECK: function_ref @$s19inlinable_attribute15talkAboutAHorse1hyAA5HorseC_tFyycAEcfu_yycfu0_ // CHECK: return // CHECK: } -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$s19inlinable_attribute5HorseC6gallopyyFTc : $@convention(thin) (@guaranteed Horse) -> @owned @callee_guaranteed () -> () { -// CHECK: class_method +// CHECK-LABEL: sil shared [serialized] [ossa] @$s19inlinable_attribute15talkAboutAHorse1hyAA5HorseC_tFyycAEcfu_yycfu0_ : $@convention(thin) (@guaranteed Horse) -> () { +// CHECK: class_method %0 : $Horse, #Horse.gallop!1 : (Horse) -> () -> (), $@convention(method) (@guaranteed Horse) -> () // CHECK: return // CHECK: } diff --git a/test/SILGen/inlinable_attribute_objc.swift b/test/SILGen/inlinable_attribute_objc.swift index 98ab898adc8ac..364d1943c5565 100644 --- a/test/SILGen/inlinable_attribute_objc.swift +++ b/test/SILGen/inlinable_attribute_objc.swift @@ -28,21 +28,6 @@ public class Horse : NSObject { // However, make sure we can reference dynamic thunks and curry thunks // from inlinable scopes -// CHECK-LABEL: sil [serialized] [ossa] @$s24inlinable_attribute_objc15talkAboutAHorse1hyAA5HorseC_tF : $@convention(thin) (@guaranteed Horse) -> () { -// CHECK: function_ref @$s24inlinable_attribute_objc5HorseC6gallopyyFTc : $@convention(thin) (@guaranteed Horse) -> @owned @callee_guaranteed () -> () -// CHECK: return -// CHECK: } - -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$s24inlinable_attribute_objc5HorseC6gallopyyFTc : $@convention(thin) (@guaranteed Horse) -> @owned @callee_guaranteed () -> () -// CHECK: %1 = function_ref @$s24inlinable_attribute_objc5HorseC6gallopyyFTD -// CHECK: return -// CHECK: } - -// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$s24inlinable_attribute_objc5HorseC6gallopyyFTD : $@convention(method) (@guaranteed Horse) -> () -// CHECK: objc_method -// CHECK: return -// CHECK: } - @inlinable public func talkAboutAHorse(h: Horse) { _ = h.gallop } diff --git a/test/SILGen/mangling.swift b/test/SILGen/mangling.swift index 561f8a5701bfe..2d401ff78c260 100644 --- a/test/SILGen/mangling.swift +++ b/test/SILGen/mangling.swift @@ -85,15 +85,6 @@ func uses_clang_struct(r: NSRect) {} // CHECK-LABEL: sil hidden [ossa] @$s8mangling14uses_optionals1xs7UnicodeO6ScalarVSgSiSg_tF func uses_optionals(x: Int?) -> UnicodeScalar? { return nil } -enum GenericUnion { - // CHECK-LABEL: sil shared [transparent] [ossa] @$s8mangling12GenericUnionO3FooyACyxGSicAEmlF - case Foo(Int) -} - -func instantiateGenericUnionConstructor(_ t: T) { - _ = GenericUnion.Foo -} - struct HasVarInit { static var state = true && false } diff --git a/test/SILGen/objc_currying.swift b/test/SILGen/objc_currying.swift index c96b1bf7db486..a06ffef019b66 100644 --- a/test/SILGen/objc_currying.swift +++ b/test/SILGen/objc_currying.swift @@ -13,50 +13,31 @@ func curry_pod(_ x: CurryTest) -> (Int) -> Int { } // CHECK-LABEL: sil hidden [ossa] @$s13objc_currying9curry_podyS2icSo9CurryTestCF : $@convention(thin) (@guaranteed CurryTest) -> @owned @callee_guaranteed (Int) -> Int // CHECK: bb0([[ARG1:%.*]] : @guaranteed $CurryTest): -// CHECK: [[THUNK:%.*]] = function_ref @[[THUNK_FOO_1:\$sSo9CurryTestC3podyS2iFTcTO]] : $@convention(thin) (@guaranteed CurryTest) -> @owned @callee_guaranteed (Int) -> Int +// CHECK: [[THUNK:%.*]] = function_ref @$s13objc_currying9curry_podyS2icSo9CurryTestCFS2icADcfu_ : $@convention(thin) (@guaranteed CurryTest) -> @owned @callee_guaranteed (Int) -> Int // CHECK: [[FN:%.*]] = apply [[THUNK]]([[ARG1]]) // CHECK-NOT: destroy_value // CHECK: return [[FN]] // CHECK: } // end sil function '$s13objc_currying9curry_podyS2icSo9CurryTestCF' -// CHECK: sil shared [serializable] [thunk] [ossa] @[[THUNK_FOO_1]] : $@convention(thin) (@guaranteed CurryTest) -> @owned @callee_guaranteed (Int) -> Int -// CHECK: bb0([[ARG1:%.*]] : @guaranteed $CurryTest): -// CHECK: [[THUNK:%.*]] = function_ref @[[THUNK_FOO_2:\$sSo9CurryTestC3podyS2iFTO]] -// CHECK: [[ARG1_COPY:%.*]] = copy_value [[ARG1]] -// CHECK: [[FN:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[ARG1_COPY]]) -// CHECK-NOT: destroy_value -// CHECK: return [[FN]] -// CHECK: } // end sil function '[[THUNK_FOO_1]]' - -// CHECK: sil shared [serializable] [thunk] [ossa] @[[THUNK_FOO_2]] : $@convention(method) (Int, @guaranteed CurryTest) -> Int +// CHECK: sil private [ossa] @$s13objc_currying9curry_podyS2icSo9CurryTestCFS2icADcfu_S2icfu0_ : $@convention(thin) (Int, @guaranteed CurryTest) -> Int // CHECK: bb0([[ARG1:%.*]] : $Int, [[ARG2:%.*]] : @guaranteed $CurryTest): -// CHECK: [[COPIED_ARG2:%.*]] = copy_value [[ARG2]] -// CHECK: [[METHOD:%.*]] = objc_method [[COPIED_ARG2]] : $CurryTest, #CurryTest.pod!1.foreign -// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[ARG1]], [[COPIED_ARG2]]) -// CHECK: destroy_value [[COPIED_ARG2]] +// CHECK: [[METHOD:%.*]] = objc_method [[ARG2]] : $CurryTest, #CurryTest.pod!1.foreign +// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[ARG1]], [[ARG2]]) // CHECK: return [[RESULT]] -// CHECK: } // end sil function '[[THUNK_FOO_2]]' +// CHECK: } func curry_bridged(_ x: CurryTest) -> (String?) -> String? { return x.bridged } // CHECK-LABEL: sil hidden [ossa] @$s13objc_currying13curry_bridgedySSSgACcSo9CurryTestCF : $@convention(thin) (@guaranteed CurryTest) -> @owned @callee_guaranteed (@guaranteed Optional) -> @owned Optional // CHECK: bb0([[ARG1:%.*]] : @guaranteed $CurryTest): -// CHECK: [[THUNK:%.*]] = function_ref @[[THUNK_BAR_1:\$sSo9CurryTestC7bridgedySSSgADFTcTO]] +// CHECK: [[THUNK:%.*]] = function_ref @$s13objc_currying13curry_bridgedySSSgACcSo9CurryTestCFA2CcAEcfu_ : $@convention(thin) (@guaranteed CurryTest) -> @owned @callee_guaranteed (@guaranteed Optional) -> @owned Optional // CHECK: [[FN:%.*]] = apply [[THUNK]]([[ARG1]]) // CHECK-NOT: destroy_value [[ARG1]] // CHECK: return [[FN]] // CHECK: } // end sil function '$s13objc_currying13curry_bridgedySSSgACcSo9CurryTestCF' -// CHECK: sil shared [serializable] [thunk] [ossa] @[[THUNK_BAR_1]] : $@convention(thin) (@guaranteed CurryTest) -> @owned @callee_guaranteed (@guaranteed Optional) -> @owned Optional -// CHECK: bb0([[ARG1:%.*]] : @guaranteed $CurryTest): -// CHECK: [[THUNK:%.*]] = function_ref @[[THUNK_BAR_2:\$sSo9CurryTestC7bridgedySSSgADFTO]] -// CHECK: [[COPY_ARG1:%.*]] = copy_value [[ARG1]] -// CHECK: [[FN:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[COPY_ARG1]]) -// CHECK: return [[FN]] -// CHECK: } // end sil function '[[THUNK_BAR_1]]' - -// CHECK: sil shared [serializable] [thunk] [ossa] @[[THUNK_BAR_2]] : $@convention(method) (@guaranteed Optional, @guaranteed CurryTest) -> @owned Optional +// CHECK: sil private [ossa] @$s13objc_currying13curry_bridgedySSSgACcSo9CurryTestCFA2CcAEcfu_A2Ccfu0_ : $@convention(thin) (@guaranteed Optional, @guaranteed CurryTest) -> @owned Optional // CHECK: bb0([[OPT_STRING:%.*]] : @guaranteed $Optional, [[SELF:%.*]] : @guaranteed $CurryTest): // CHECK: [[COPY_OPT_STRING:%.*]] = copy_value [[OPT_STRING]] // CHECK: switch_enum [[COPY_OPT_STRING]] : $Optional, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9]+]], @@ -75,9 +56,9 @@ func curry_bridged(_ x: CurryTest) -> (String?) -> String? { // CHECK: br bb3([[OPT_NONE]] : $Optional) // CHECK: bb3([[OPT_NSSTRING:%.*]] : @owned $Optional): -// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] -// CHECK: [[METHOD:%.*]] = objc_method [[SELF_COPY]] : $CurryTest, #CurryTest.bridged!1.foreign -// CHECK: [[RESULT_OPT_NSSTRING:%.*]] = apply [[METHOD]]([[OPT_NSSTRING]], [[SELF_COPY]]) : $@convention(objc_method) (Optional, CurryTest) -> @autoreleased Optional +// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $CurryTest, #CurryTest.bridged!1.foreign +// CHECK: [[RESULT_OPT_NSSTRING:%.*]] = apply [[METHOD]]([[OPT_NSSTRING]], [[SELF]]) : $@convention(objc_method) (Optional, CurryTest) -> @autoreleased Optional +// CHECK: destroy_value [[OPT_NSSTRING]] // CHECK: switch_enum [[RESULT_OPT_NSSTRING]] : $Optional, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9]+]], // CHECK: [[SOME_BB]]([[RESULT_NSSTRING:%.*]] : @owned $NSString): @@ -85,6 +66,7 @@ func curry_bridged(_ x: CurryTest) -> (String?) -> String? { // CHECK: [[REWRAP_RESULT_NSSTRING:%.*]] = enum $Optional, #Optional.some!enumelt.1, [[RESULT_NSSTRING]] // CHECK: [[RESULT_STRING:%.*]] = apply [[BRIDGE_FUNC]]([[REWRAP_RESULT_NSSTRING]] // CHECK: [[WRAPPED_RESULT_STRING:%.*]] = enum $Optional, #Optional.some!enumelt.1, [[RESULT_STRING]] +// CHECK: destroy_value [[REWRAP_RESULT_NSSTRING]] // CHECK: br bb6([[WRAPPED_RESULT_STRING]] : $Optional) // CHECK: bb5: @@ -92,38 +74,28 @@ func curry_bridged(_ x: CurryTest) -> (String?) -> String? { // CHECK: br bb6([[OPT_NONE]] : $Optional) // CHECK: bb6([[FINAL_RESULT:%.*]] : @owned $Optional): -// CHECK: destroy_value [[SELF_COPY]] -// CHECK: destroy_value [[OPT_NSSTRING]] // CHECK: return [[FINAL_RESULT]] : $Optional -// CHECK: } // end sil function '[[THUNK_BAR_2]]' +// CHECK: } func curry_returnsInnerPointer(_ x: CurryTest) -> () -> UnsafeMutableRawPointer? { return x.returnsInnerPointer } // CHECK-LABEL: sil hidden [ossa] @$s13objc_currying25curry_returnsInnerPointerySvSgycSo9CurryTestCF : $@convention(thin) (@guaranteed CurryTest) -> @owned @callee_guaranteed () -> Optional { // CHECK: bb0([[SELF:%.*]] : @guaranteed $CurryTest): -// CHECK: [[THUNK:%.*]] = function_ref @[[THUNK_RETURNSINNERPOINTER:\$sSo9CurryTestC19returnsInnerPointerSvSgyFTcTO]] +// CHECK: [[THUNK:%.*]] = function_ref @$s13objc_currying25curry_returnsInnerPointerySvSgycSo9CurryTestCFACycAEcfu_ : $@convention(thin) (@guaranteed CurryTest) -> @owned @callee_guaranteed () -> Optional // CHECK: [[FN:%.*]] = apply [[THUNK]]([[SELF]]) // CHECK-NOT: destroy_value [[SELF]] // CHECK: return [[FN]] // CHECK: } // end sil function '$s13objc_currying25curry_returnsInnerPointerySvSgycSo9CurryTestCF' -// CHECK: sil shared [serializable] [thunk] [ossa] @[[THUNK_RETURNSINNERPOINTER]] : $@convention(thin) (@guaranteed CurryTest) -> @owned @callee_guaranteed () -> Optional -// CHECK: bb0([[ARG1:%.*]] : @guaranteed -// CHECK: [[THUNK:%.*]] = function_ref @[[THUNK_RETURNSINNERPOINTER_2:\$sSo9CurryTestC19returnsInnerPointerSvSgyFTO]] -// CHECK: [[COPY_ARG1:%.*]] = copy_value [[ARG1]] -// CHECK: [[FN:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[COPY_ARG1]]) -// CHECK: return [[FN]] -// CHECK: } // end sil function '[[THUNK_RETURNSINNERPOINTER]]' - -// CHECK: sil shared [serializable] [thunk] [ossa] @[[THUNK_RETURNSINNERPOINTER_2]] : $@convention(method) (@guaranteed CurryTest) -> Optional +// CHECK: sil private [ossa] @$s13objc_currying25curry_returnsInnerPointerySvSgycSo9CurryTestCFACycAEcfu_ACycfu0_ : $@convention(thin) (@guaranteed CurryTest) -> Optional // CHECK: bb0([[ARG1:%.*]] : @guaranteed $CurryTest): +// CHECK: [[METHOD:%.*]] = objc_method [[ARG1]] : $CurryTest, #CurryTest.returnsInnerPointer!1.foreign // CHECK: [[ARG1_COPY:%.*]] = copy_value [[ARG1]] -// CHECK: [[METHOD:%.*]] = objc_method [[ARG1_COPY]] : $CurryTest, #CurryTest.returnsInnerPointer!1.foreign -// CHECK: [[RES:%.*]] = apply [[METHOD]]([[ARG1_COPY]]) : $@convention(objc_method) (CurryTest) -> @unowned_inner_pointer Optional -// CHECK: autorelease_value +// CHECK: [[RES:%.*]] = apply [[METHOD]]([[ARG1]]) : $@convention(objc_method) (CurryTest) -> @unowned_inner_pointer Optional +// CHECK: autorelease_value [[ARG1_COPY]] // CHECK: return [[RES]] -// CHECK: } // end sil function '[[THUNK_RETURNSINNERPOINTER_2]]' +// CHECK: } // CHECK-LABEL: sil hidden [ossa] @$s13objc_currying19curry_pod_AnyObjectyS2icyXlF : $@convention(thin) (@guaranteed AnyObject) -> @owned @callee_guaranteed (Int) -> Int // CHECK: bb0([[ANY:%.*]] : @guaranteed $AnyObject): @@ -223,4 +195,4 @@ func curry_initializer() -> (Int) -> Gizmo? { // CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo5GizmoC7bellsOnABSgSi_tcfcTO : $@convention(method) (Int, @owned Gizmo) -> @owned Optional { -// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo5GizmoC7bellsOnABSgSi_tcfCTcTd : $@convention(thin) (@thick Gizmo.Type) -> @owned @callee_guaranteed (Int) -> @owned Optional { +// CHECK-LABEL: sil private [ossa] @$s13objc_currying17curry_initializerSo5GizmoCSgSicyFAESicfu_ : $@convention(thin) (Int) -> @owned Optional { diff --git a/test/SILGen/objc_extensions.swift b/test/SILGen/objc_extensions.swift index ed34a30349c63..42c84b3d7e091 100644 --- a/test/SILGen/objc_extensions.swift +++ b/test/SILGen/objc_extensions.swift @@ -114,14 +114,13 @@ func testOverrideProperty(_ obj: Sub) { testOverrideProperty(Sub()) -// CHECK-LABEL: sil shared [thunk] [ossa] @$s15objc_extensions3SubC3fooyyFTc -// CHECK: function_ref @$s15objc_extensions3SubC3fooyyFTD -// CHECK: } // end sil function '$s15objc_extensions3SubC3fooyyFTc' -// CHECK: sil shared [transparent] [serializable] [thunk] [ossa] @$s15objc_extensions3SubC3fooyyFTD -// CHECK: bb0([[SELF:%.*]] : @guaranteed $Sub): -// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] -// CHECK: objc_method [[SELF_COPY]] : $Sub, #Sub.foo!1.foreign -// CHECK: } // end sil function '$s15objc_extensions3SubC3fooyyFTD' +// CHECK-LABEL: sil private [ossa] @$s15objc_extensions9testCurryyyAA3SubCFyycADcfu_ : $@convention(thin) (@guaranteed Sub) -> @owned @callee_guaranteed () -> () +// CHECK: function_ref @$s15objc_extensions9testCurryyyAA3SubCFyycADcfu_yycfu0_ : $@convention(thin) (@guaranteed Sub) -> () +// CHECK: } // end sil function '$s15objc_extensions9testCurryyyAA3SubCFyycADcfu_' + +// CHECK-LABEL: sil private [ossa] @$s15objc_extensions9testCurryyyAA3SubCFyycADcfu_yycfu0_ : $@convention(thin) (@guaranteed Sub) -> () +// CHECK: objc_method %0 : $Sub, #Sub.foo!1.foreign : (Sub) -> () -> (), $@convention(objc_method) (Sub) -> () +// CHECK: } // end sil function '$s15objc_extensions9testCurryyyAA3SubCFyycADcfu_yycfu0_' func testCurry(_ x: Sub) { _ = x.foo } diff --git a/test/SILGen/objc_protocol_native_thunk.swift b/test/SILGen/objc_protocol_native_thunk.swift index f190df85f03bd..b8a13c0ab044f 100644 --- a/test/SILGen/objc_protocol_native_thunk.swift +++ b/test/SILGen/objc_protocol_native_thunk.swift @@ -1,5 +1,5 @@ -// RUN: %target-swift-emit-silgen(mock-sdk: %clang-importer-sdk) %s | %FileCheck %s +// RUN: %target-swift-emit-silgen(mock-sdk: %clang-importer-sdk) %s // REQUIRES: objc_interop import Foundation @@ -11,7 +11,6 @@ import Foundation func c(_: String) {} } -// CHECK-LABEL: sil shared [thunk] [ossa] @$s{{.*}}1P{{.*}}1p{{.*}} : $@convention(method) (@guaranteed String, @guaranteed Self) -> () func foo(x: Bool, y: C & P) -> (String) -> () { return x ? y.c : y.p } diff --git a/test/SILGen/objc_protocols.swift b/test/SILGen/objc_protocols.swift index 5db6d815efc8b..bb370f778e325 100644 --- a/test/SILGen/objc_protocols.swift +++ b/test/SILGen/objc_protocols.swift @@ -44,55 +44,45 @@ func objc_generic(_ x: T) -> (NSObject, NSObject) { // CHECK-LABEL: sil hidden [ossa] @$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlF : $@convention(thin) (@guaranteed T) -> () { func objc_generic_partial_apply(_ x: T) { // CHECK: bb0([[ARG:%.*]] : @guaranteed $T): - // CHECK: [[FN:%.*]] = function_ref @[[THUNK1:\$s14objc_protocols9NSRuncingP5runceSo8NSObjectCyFTcTO]] : - // CHECK: [[METHOD:%.*]] = apply [[FN]]([[ARG]]) - // CHECK: destroy_value [[METHOD]] + // CHECK: [[FN:%.*]] = function_ref @$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxcfu_ _ = x.runce - // CHECK: [[FN:%.*]] = function_ref @[[THUNK1]] : - // CHECK: [[METHOD:%.*]] = partial_apply [callee_guaranteed] [[FN]]() - // CHECK: [[METHOD_CONV:%.*]] = convert_function [[METHOD]] - // CHECK: destroy_value [[METHOD_CONV]] + // CHECK: [[FN:%.*]] = function_ref @$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxcfu1_ _ = T.runce - // CHECK: [[METATYPE:%.*]] = metatype $@thick T.Type - // CHECK: [[FN:%.*]] = function_ref @[[THUNK2:\$s14objc_protocols9NSRuncingP5minceSo8NSObjectCyFZTcTO]] - // CHECK: [[METHOD:%.*]] = apply [[FN]]([[METATYPE]]) - // CHECK: destroy_value [[METHOD:%.*]] + // CHECK: [[FN:%.*]] = function_ref @$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxmcfu3_ _ = T.mince // CHECK-NOT: destroy_value [[ARG]] } // CHECK: } // end sil function '$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlF' -// CHECK: sil shared [thunk] [ossa] @[[THUNK1]] : -// CHECK: bb0([[SELF:%.*]] : @guaranteed $Self): -// CHECK: [[FN:%.*]] = function_ref @[[THUNK1_THUNK:\$s14objc_protocols9NSRuncingP5runceSo8NSObjectCyFTO]] : -// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] -// CHECK: [[METHOD:%.*]] = partial_apply [callee_guaranteed] [[FN]]([[SELF_COPY]]) -// CHECK: return [[METHOD]] -// CHECK: } // end sil function '[[THUNK1]]' - -// CHECK: sil shared [thunk] [ossa] @[[THUNK1_THUNK]] -// CHECK: bb0([[SELF:%.*]] : @guaranteed $Self): -// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] -// CHECK: [[FN:%.*]] = objc_method [[SELF_COPY]] : $Self, #NSRuncing.runce!1.foreign -// CHECK: [[RESULT:%.*]] = apply [[FN]]([[SELF_COPY]]) -// CHECK: destroy_value [[SELF_COPY]] -// CHECK: return [[RESULT]] -// CHECK: } // end sil function '[[THUNK1_THUNK]]' - -// CHECK: sil shared [thunk] [ossa] @[[THUNK2]] : -// CHECK: [[FN:%.*]] = function_ref @[[THUNK2_THUNK:\$s14objc_protocols9NSRuncingP5minceSo8NSObjectCyFZTO]] -// CHECK: [[METHOD:%.*]] = partial_apply [callee_guaranteed] [[FN]](%0) -// CHECK: return [[METHOD]] -// CHECK: } // end sil function '[[THUNK2]]' - -// CHECK: sil shared [thunk] [ossa] @[[THUNK2_THUNK]] : -// CHECK: [[METATYPE:%.*]] = thick_to_objc_metatype %0 -// CHECK: [[FN:%.*]] = objc_method [[METATYPE]] : $@objc_metatype Self.Type, #NSRuncing.mince!1.foreign -// CHECK-NEXT: [[RESULT:%.*]] = apply [[FN]]([[METATYPE]]) -// CHECK-NEXT: return [[RESULT]] -// CHECK: } // end sil function '[[THUNK2_THUNK]]' + +// CHECK: sil private [ossa] @$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxcfu_ : $@convention(thin) (@guaranteed T) -> @owned @callee_guaranteed () -> @owned NSObject { +// CHECK: function_ref @$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxcfu_AEycfu0_ : $@convention(thin) <τ_0_0 where τ_0_0 : NSRuncing> (@guaranteed τ_0_0) -> @owned NSObject +// CHECK: } // end sil function '$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxcfu_' + +// CHECK: sil private [ossa] @$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxcfu_AEycfu0_ : $@convention(thin) (@guaranteed T) -> @owned NSObject { +// CHECK: objc_method %0 : $T, #NSRuncing.runce!1.foreign : (Self) -> () -> NSObject, $@convention(objc_method) <τ_0_0 where τ_0_0 : NSRuncing> (τ_0_0) -> @autoreleased NSObject +// CHECK: } // end sil function '$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxcfu_AEycfu0_' + + +// CHECK: sil private [ossa] @$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxcfu1_ : $@convention(thin) (@guaranteed T) -> @owned @callee_guaranteed () -> @owned NSObject +// CHECK: function_ref @$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxcfu1_AEycfu2_ : $@convention(thin) <τ_0_0 where τ_0_0 : NSRuncing> (@guaranteed τ_0_0) -> @owned NSObject +// CHECK: } // end sil function '$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxcfu1_' + +// CHECK: sil private [ossa] @$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxcfu1_AEycfu2_ : $@convention(thin) (@guaranteed T) -> @owned NSObject +// CHECK: objc_method %0 : $T, #NSRuncing.runce!1.foreign : (Self) -> () -> NSObject, $@convention(objc_method) <τ_0_0 where τ_0_0 : NSRuncing> (τ_0_0) -> @autoreleased NSObject +// CHECK: } // end sil function '$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxcfu1_AEycfu2_' + + +// CHECK-LABEL: sil private [ossa] @$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxmcfu3_ : $@convention(thin) (@thick T.Type) -> @owned @callee_guaranteed () -> @owned NSObject +// CHECK: function_ref @$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxmcfu3_AEycfu4_ : $@convention(thin) <τ_0_0 where τ_0_0 : NSRuncing> (@thick τ_0_0.Type) -> @owned NSObject +// CHECK: } // end sil function '$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxmcfu3_' + +// CHECK-LABEL: sil private [ossa] @$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxmcfu3_AEycfu4_ : $@convention(thin) (@thick T.Type) -> @owned NSObject +// CHECK: objc_method %2 : $@objc_metatype T.Type, #NSRuncing.mince!1.foreign : (Self.Type) -> () -> NSObject, $@convention(objc_method) <τ_0_0 where τ_0_0 : NSRuncing> (@objc_metatype τ_0_0.Type) -> @autoreleased NSObject +// CHECK: } // end sil function '$s14objc_protocols0A22_generic_partial_applyyyxAA9NSRuncingRzlFSo8NSObjectCycxmcfu3_AEycfu4_' + // CHECK-LABEL: sil hidden [ossa] @$s14objc_protocols0A9_protocol{{[_0-9a-zA-Z]*}}F // CHECK: bb0([[THIS:%.*]] : @guaranteed $NSRuncing): @@ -115,15 +105,12 @@ func objc_protocol(_ x: NSRuncing) -> (NSObject, NSObject) { // CHECK-LABEL: sil hidden [ossa] @$s14objc_protocols0A23_protocol_partial_applyyyAA9NSRuncing_pF : $@convention(thin) (@guaranteed NSRuncing) -> () { func objc_protocol_partial_apply(_ x: NSRuncing) { // CHECK: bb0([[ARG:%.*]] : @guaranteed $NSRuncing): - // CHECK: [[OPENED_ARG:%.*]] = open_existential_ref [[ARG]] : $NSRuncing to $[[OPENED:@opened(.*) NSRuncing]] - // CHECK: [[FN:%.*]] = function_ref @$s14objc_protocols9NSRuncingP5runceSo8NSObjectCyFTcTO - // CHECK: [[RESULT:%.*]] = apply [[FN]]<[[OPENED]]>([[OPENED_ARG]]) - // CHECK: destroy_value [[RESULT]] - // CHECK-NOT: destroy_value [[ARG]] + // CHECK: [[FN:%.*]] = function_ref @$s14objc_protocols0A23_protocol_partial_applyyyAA9NSRuncing_pFSo8NSObjectCycAaC_pcfu_ + // CHECK: [[RESULT:%.*]] = apply [[FN]]([[ARG]]) _ = x.runce - // FIXME: rdar://21289579 - // _ = NSRuncing.runce + // rdar://21289579 + _ = NSRuncing.runce } // CHECK: } // end sil function '$s14objc_protocols0A23_protocol_partial_applyyyAA9NSRuncing_pF' diff --git a/test/SILGen/opaque_values_silgen_lib.swift b/test/SILGen/opaque_values_silgen_lib.swift index 23eba1ef120d1..2c9c905a8a143 100644 --- a/test/SILGen/opaque_values_silgen_lib.swift +++ b/test/SILGen/opaque_values_silgen_lib.swift @@ -25,6 +25,19 @@ func s010______PAndS_cases() { _ = PAndSEnum.A } +// Init of Empty protocol + Builtin.NativeObject enum (including opaque tuples as a return value) +// --- +// CHECK-LABEL: sil private [ossa] @$ss21s010______PAndS_casesyyFs0B5SEnumOs6EmptyP_p_SStcACmcfu_ACsAD_p_SStcfu0_ : $@convention(thin) (@in_guaranteed EmptyP, @guaranteed String, @thin PAndSEnum.Type) -> @out PAndSEnum { +// CHECK: bb0([[ARG0:%.*]] : @guaranteed $EmptyP, [[ARG1:%.*]] : @guaranteed $String, [[ARG2:%.*]] : $@thin PAndSEnum.Type): +// CHECK: [[COPY0:%.*]] = copy_value [[ARG0]] +// CHECK: [[COPY1:%.*]] = copy_value [[ARG1]] +// CHECK: [[RTUPLE:%.*]] = tuple ([[COPY0]] : $EmptyP, [[COPY1]] : $String) +// CHECK: [[RETVAL:%.*]] = enum $PAndSEnum, #PAndSEnum.A!enumelt.1, [[RTUPLE]] : $(EmptyP, String) +// CHECK: return [[RETVAL]] : $PAndSEnum +// CHECK-LABEL: } // end sil function '$ss21s010______PAndS_casesyyFs0B5SEnumOs6EmptyP_p_SStcACmcfu_ACsAD_p_SStcfu0_' +enum PAndSEnum { case A(EmptyP, String) } + + // Test emitBuiltinReinterpretCast. // --- // CHECK-LABEL: sil hidden [ossa] @$ss21s020__________bitCast_2toq_x_q_mtr0_lF : $@convention(thin) (@in_guaranteed T, @thick U.Type) -> @out U { @@ -57,21 +70,3 @@ func s020__________bitCast(_ x: T, to type: U.Type) -> U { func s030__________refCast(_ x: T, to: U.Type) -> U { return Builtin.castReference(x) } - -// Init of Empty protocol + Builtin.NativeObject enum (including opaque tuples as a return value) -// --- -// CHECK-LABEL: sil shared [transparent] [ossa] @$ss9PAndSEnumO1AyABs6EmptyP_p_SStcABmF : $@convention(method) (@in EmptyP, @owned String, @thin PAndSEnum.Type) -> @out PAndSEnum { -// CHECK: bb0([[ARG0:%.*]] : @owned $EmptyP, [[ARG1:%.*]] : @owned $String, [[ARG2:%.*]] : $@thin PAndSEnum.Type): -// CHECK: [[RTUPLE:%.*]] = tuple ([[ARG0]] : $EmptyP, [[ARG1]] : $String) -// CHECK: [[RETVAL:%.*]] = enum $PAndSEnum, #PAndSEnum.A!enumelt.1, [[RTUPLE]] : $(EmptyP, String) -// CHECK: return [[RETVAL]] : $PAndSEnum -// CHECK-LABEL: } // end sil function '$ss9PAndSEnumO1AyABs6EmptyP_p_SStcABmF' -// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$ss9PAndSEnumO1AyABs6EmptyP_p_SStcABmFTc : $@convention(thin) (@thin PAndSEnum.Type) -> @owned @callee_guaranteed (@in_guaranteed EmptyP, @guaranteed String) -> @out PAndSEnum { -// CHECK: bb0([[ARG:%.*]] : $@thin PAndSEnum.Type): -// CHECK: [[RETVAL:%.*]] = partial_apply [callee_guaranteed] {{.*}}([[ARG]]) : $@convention(method) (@in EmptyP, @owned String, @thin PAndSEnum.Type) -> @out PAndSEnum -// CHECK: [[CANONICAL_THUNK_FN:%.*]] = function_ref @$ss6EmptyP_pSSs9PAndSEnumOIegixr_sAA_pSSACIegngr_TR : $@convention(thin) (@in_guaranteed EmptyP, @guaranteed String, @guaranteed @callee_guaranteed (@in EmptyP, @owned String) -> @out PAndSEnum) -> @out PAndSEnum -// CHECK: [[CANONICAL_THUNK:%.*]] = partial_apply [callee_guaranteed] [[CANONICAL_THUNK_FN]]([[RETVAL]]) -// CHECK: return [[CANONICAL_THUNK]] : $@callee_guaranteed (@in_guaranteed EmptyP, @guaranteed String) -> @out PAndSEnum -// CHECK-LABEL: } // end sil function '$ss9PAndSEnumO1AyABs6EmptyP_p_SStcABmFTc' -enum PAndSEnum { case A(EmptyP, String) } - diff --git a/test/SILGen/partial_apply_apply.swift b/test/SILGen/partial_apply_apply.swift new file mode 100644 index 0000000000000..1597bd80fa333 --- /dev/null +++ b/test/SILGen/partial_apply_apply.swift @@ -0,0 +1,24 @@ +// RUN: %target-swift-frontend -emit-silgen %s + +// Make sure an unbound method reference which is then immediately +// called can be SILGen'd correctly. + +class C { + func foo(x: Int) {} +} + +protocol P { + func foo(x: Int) +} + +let c = C() + +func doIt(_ c: C, _ p: P ) { + _ = C.foo + _ = C.foo(c) + _ = C.foo(c)(x: 123) + + _ = P.foo + _ = P.foo(p) + _ = P.foo(p)(x: 123) +} diff --git a/test/SILGen/partial_apply_consuming_self.swift b/test/SILGen/partial_apply_consuming_self.swift new file mode 100644 index 0000000000000..f30030c4e0d67 --- /dev/null +++ b/test/SILGen/partial_apply_consuming_self.swift @@ -0,0 +1,22 @@ +// RUN: %target-swift-emit-silgen %s | %FileCheck %s + +class C { + __consuming func consumesSelf() {} +} + +func referencesConsumesSelf(_ c: C) { + _ = C.consumesSelf + C.consumesSelf(c)() +} + +// The method... + +// CHECK-LABEL: sil hidden [ossa] @$s28partial_apply_consuming_self1CC12consumesSelfyyF : $@convention(method) (@owned C) -> () { + +// The curry thunk's outer closure... + +// CHECK-LABEL: sil private [ossa] @$s28partial_apply_consuming_self22referencesConsumesSelfyyAA1CCFyycADncfu_ : $@convention(thin) (@owned C) -> @owned @callee_guaranteed () -> () { + +// The curry thunk's inner closure... + +// CHECK-LABEL: sil private [ossa] @$s28partial_apply_consuming_self22referencesConsumesSelfyyAA1CCFyycADncfu_yycfu0_ : $@convention(thin) (@guaranteed C) -> () { \ No newline at end of file diff --git a/test/SILGen/partial_apply_generic.swift b/test/SILGen/partial_apply_generic.swift index 1a9ee7cee55a8..abf2aa87427b5 100644 --- a/test/SILGen/partial_apply_generic.swift +++ b/test/SILGen/partial_apply_generic.swift @@ -14,81 +14,59 @@ protocol Foo { // CHECK-LABEL: sil hidden [ossa] @$s21partial_apply_generic14getStaticFunc1{{[_0-9a-zA-Z]*}}F func getStaticFunc1(t: T.Type) -> () -> () { -// CHECK: [[REF:%.*]] = function_ref @$s21partial_apply_generic3FooP10staticFunc{{[_0-9a-zA-Z]*}}FZ -// CHECK-NEXT: apply [[REF]](%0) +// CHECK: function_ref @$s21partial_apply_generic14getStaticFunc11tyycxm_tAA3FooRzlFyycxmcfu_ : $@convention(thin) <τ_0_0 where τ_0_0 : Foo> (@thick τ_0_0.Type) -> @owned @callee_guaranteed () -> () return t.staticFunc -// CHECK-NEXT: return } -// CHECK-LABEL: sil shared [thunk] [ossa] @$s21partial_apply_generic3FooP10staticFunc{{[_0-9a-zA-Z]*}}FZ -// CHECK: [[REF:%.*]] = witness_method $Self, #Foo.staticFunc!1 -// CHECK-NEXT: partial_apply [callee_guaranteed] [[REF]](%0) -// CHECK-NEXT: return +// CHECK-LABEL: sil private [ossa] @$s21partial_apply_generic14getStaticFunc11tyycxm_tAA3FooRzlFyycxmcfu_yycfu0_ : $@convention(thin) (@thick T.Type) -> () +// CHECK: witness_method $T, #Foo.staticFunc!1 + // CHECK-LABEL: sil hidden [ossa] @$s21partial_apply_generic14getStaticFunc2{{[_0-9a-zA-Z]*}}F func getStaticFunc2(t: T) -> () -> () { -// CHECK: [[REF:%.*]] = function_ref @$s21partial_apply_generic3FooP10staticFunc{{[_0-9a-zA-Z]*}}FZ -// CHECK: apply [[REF]] +// CHECK: function_ref @$s21partial_apply_generic14getStaticFunc21tyycx_tAA3FooRzlFyycxmcfu_ : $@convention(thin) <τ_0_0 where τ_0_0 : Foo> (@thick τ_0_0.Type) -> @owned @callee_guaranteed () -> () return T.staticFunc -// CHECK-NOT: destroy_addr %0 : $*T -// CHECK-NEXT: return } +// CHECK-LABEL: sil private [ossa] @$s21partial_apply_generic14getStaticFunc21tyycx_tAA3FooRzlFyycxmcfu_yycfu0_ : $@convention(thin) (@thick T.Type) -> () +// CHECK: witness_method $T, #Foo.staticFunc!1 + + // CHECK-LABEL: sil hidden [ossa] @$s21partial_apply_generic16getInstanceFunc1{{[_0-9a-zA-Z]*}}F func getInstanceFunc1(t: T) -> () -> () { -// CHECK-NOT: alloc_stack $T -// CHECK-NOT: copy_addr %0 to [initialization] -// CHECK: [[REF:%.*]] = function_ref @$s21partial_apply_generic3FooP12instanceFunc{{[_0-9a-zA-Z]*}}F -// CHECK-NEXT: apply [[REF]] +// CHECK: function_ref @$s21partial_apply_generic16getInstanceFunc11tyycx_tAA3FooRzlFyycxcfu_ : $@convention(thin) <τ_0_0 where τ_0_0 : Foo> (@in_guaranteed τ_0_0) -> @owned @callee_guaranteed () -> () return t.instanceFunc -// CHECK-NOT: dealloc_stack -// CHECK-NOT: destroy_addr %0 : $*T -// CHECK-NEXT: return } -// CHECK-LABEL: sil shared [thunk] [ossa] @$s21partial_apply_generic3FooP12instanceFunc{{[_0-9a-zA-Z]*}}F -// CHECK: bb0([[ARG:%.*]] : $*Self): -// CHECK: [[REF:%.*]] = witness_method $Self, #Foo.instanceFunc!1 -// CHECK-NEXT: [[STACK:%.*]] = alloc_stack $Self -// CHECK-NEXT: copy_addr [[ARG]] to [initialization] [[STACK]] -// CHECK-NEXT: partial_apply [callee_guaranteed] [[REF]]([[STACK]]) -// CHECK-NEXT: dealloc_stack -// CHECK-NEXT: return +// CHECK-LABEL: sil private [ossa] @$s21partial_apply_generic16getInstanceFunc11tyycx_tAA3FooRzlFyycxcfu_yycfu0_ : $@convention(thin) (@in_guaranteed T) -> () { +// CHECK: witness_method $T, #Foo.instanceFunc!1 : (Self) -> () -> () : $@convention(witness_method: Foo) <τ_0_0 where τ_0_0 : Foo> (@in_guaranteed τ_0_0) -> () + // CHECK-LABEL: sil hidden [ossa] @$s21partial_apply_generic16getInstanceFunc2{{[_0-9a-zA-Z]*}}F func getInstanceFunc2(t: T) -> (T) -> () -> () { -// CHECK: [[REF:%.*]] = function_ref @$s21partial_apply_generic3FooP12instanceFunc{{[_0-9a-zA-Z]*}}F -// CHECK-NEXT: partial_apply [callee_guaranteed] [[REF]]( -// CHECK-NEXT: convert_function +// CHECK: function_ref @$s21partial_apply_generic16getInstanceFunc21tyycxcx_tAA3FooRzlFyycxcfu_ : $@convention(thin) <τ_0_0 where τ_0_0 : Foo> (@in_guaranteed τ_0_0) -> @owned @callee_guaranteed () -> () return T.instanceFunc -// CHECK-NEXT: return } +// CHECK-LABEL: sil private [ossa] @$s21partial_apply_generic16getInstanceFunc21tyycxcx_tAA3FooRzlFyycxcfu_yycfu0_ : $@convention(thin) (@in_guaranteed T) -> () +// CHECK: witness_method $T, #Foo.instanceFunc!1 : (Self) -> () -> () : $@convention(witness_method: Foo) <τ_0_0 where τ_0_0 : Foo> (@in_guaranteed τ_0_0) -> () + + // CHECK-LABEL: sil hidden [ossa] @$s21partial_apply_generic16getInstanceFunc3{{[_0-9a-zA-Z]*}}F func getInstanceFunc3(t: T.Type) -> (T) -> () -> () { -// CHECK: [[REF:%.*]] = function_ref @$s21partial_apply_generic3FooP12instanceFunc{{[_0-9a-zA-Z]*}}F -// CHECK-NEXT: partial_apply [callee_guaranteed] [[REF]]( -// CHECK-NEXT: convert_function +// CHECK: function_ref @$s21partial_apply_generic16getInstanceFunc31tyycxcxm_tAA3FooRzlFyycxcfu_ : $@convention(thin) <τ_0_0 where τ_0_0 : Foo> (@in_guaranteed τ_0_0) -> @owned @callee_guaranteed () -> () return t.instanceFunc -// CHECK-NEXT: return } -// CHECK-LABEL: sil hidden [ossa] @$s21partial_apply_generic23getNonCanonicalSelfFunc1tyq_cxcxm_t7CuddlesQy_RszAA5PandaR_r0_lF : -func getNonCanonicalSelfFunc(t: T.Type) -> (T) -> (U) -> () where U.Cuddles == T { -// CHECK: [[REF:%.*]] = function_ref @$s21partial_apply_generic3FooP21makesSelfNonCanonicalyyqd__7CuddlesQyd__RszAA5PandaRd__lFTc : -// CHECK-NEXT: [[CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[REF]]() -// CHECK-NEXT: [[CLOSURE_CONV:%.*]] = convert_function [[CLOSURE]] +// CHECK-LABEL: sil private [ossa] @$s21partial_apply_generic16getInstanceFunc31tyycxcxm_tAA3FooRzlFyycxcfu_yycfu0_ : $@convention(thin) (@in_guaranteed T) -> () +// CHECK: witness_method $T, #Foo.instanceFunc!1 : (Self) -> () -> () : $@convention(witness_method: Foo) <τ_0_0 where τ_0_0 : Foo> (@in_guaranteed τ_0_0) -> () + + +// CHECK-LABEL: sil hidden [ossa] @$s21partial_apply_generic23getNonCanonicalSelfFunc1tyq_cxcxm_t7CuddlesQy_RszAA5PandaR_r0_lF : $@convention(thin) (@thick T.Type) -> @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> (@owned @callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> () for <τ_0_1>) for { +func getNonCanonicalSelfFunc(t: T.Type) -> (T) -> (U) -> () where U.Cuddles == T { +// CHECK: [[REF:%.*]] = function_ref @$s21partial_apply_generic23getNonCanonicalSelfFunc1tyq_cxcxm_t7CuddlesQy_RszAA5PandaR_r0_lFyq_cxcfu_ : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.Cuddles, τ_0_1 : Panda> (@in_guaranteed τ_0_0) -> @owned @callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> () for <τ_0_1> return t.makesSelfNonCanonical -// CHECK-NEXT: return [[CLOSURE_CONV]] } -// curry thunk of Foo.makesSelfNonCanonical (A1) -> () -// CHECK-LABEL: sil shared [thunk] [ossa] @$s21partial_apply_generic3FooP21makesSelfNonCanonicalyyqd__7CuddlesQyd__RszAA5PandaRd__lFTc : -// CHECK: bb0([[ARG:%.*]] : $*Self): -// CHECK: [[REF:%.*]] = witness_method $Self, #Foo.makesSelfNonCanonical!1 : (Self) -> (T) -> () : $@convention(witness_method: Foo) <τ_0_0><τ_1_0 where τ_0_0 == τ_1_0.Cuddles, τ_1_0 : Panda> (@in_guaranteed τ_1_0, @in_guaranteed τ_0_0) -> () -// CHECK-NEXT: [[STACK:%.*]] = alloc_stack $Self -// CHECK-NEXT: copy_addr [[ARG]] to [initialization] [[STACK]] : $*Self -// CHECK-NEXT: [[CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[REF]]([[STACK]]) -// CHECK-NEXT: [[CLOSURE_CONV:%.*]] = convert_function [[CLOSURE]] -// CHECK-NEXT: dealloc_stack -// CHECK-NEXT: return [[CLOSURE_CONV]] +// CHECK-LABEL: sil private [ossa] @$s21partial_apply_generic23getNonCanonicalSelfFunc1tyq_cxcxm_t7CuddlesQy_RszAA5PandaR_r0_lFyq_cxcfu_yq_cfu0_ : $@convention(thin) (@in_guaranteed U, @in_guaranteed T) -> () { +// CHECK: witness_method $T, #Foo.makesSelfNonCanonical!1 : (Self) -> (T) -> () : $@convention(witness_method: Foo) <τ_0_0><τ_1_0 where τ_0_0 == τ_1_0.Cuddles, τ_1_0 : Panda> (@in_guaranteed τ_1_0, @in_guaranteed τ_0_0) -> () diff --git a/test/SILGen/partial_apply_init.swift b/test/SILGen/partial_apply_init.swift index b50703d90c2ba..d6ae5276f36cb 100644 --- a/test/SILGen/partial_apply_init.swift +++ b/test/SILGen/partial_apply_init.swift @@ -22,45 +22,58 @@ extension P { // CHECK-LABEL: sil hidden [ossa] @$s18partial_apply_init06class_c1_a1_B0{{[_0-9a-zA-Z]*}}F func class_init_partial_apply(c: C.Type) { - // Partial applications at the static metatype use the direct (_TTd) thunk. - // CHECK: function_ref @$s18partial_apply_init1CC{{[_0-9a-zA-Z]*}}fCTcTd + // Partial applications at the static metatype should use a direct reference. + // CHECK: function_ref @$s18partial_apply_init06class_c1_a1_B01cyAA1CCm_tFAESicfu_ : $@convention(thin) (Int) -> @owned C let xC: (Int) -> C = C.init - // CHECK: function_ref @$s18partial_apply_init1CC{{[_0-9a-zA-Z]*}}fCTcTd + // CHECK: function_ref @$s18partial_apply_init06class_c1_a1_B01cyAA1CCm_tFAESdcfu0_ let requiredC: (Double) -> C = C.init - // Partial applications to a dynamic metatype must be dynamically dispatched and use - // the normal thunk. - // CHECK: function_ref @$s18partial_apply_init1CC{{[_0-9a-zA-Z]*}}fC + // Partial applications to a dynamic metatype must be dynamically dispatched, + // CHECK: function_ref @$s18partial_apply_init06class_c1_a1_B01cyAA1CCm_tFAESdcAEmcfu1_ let requiredM: (Double) -> C = c.init } -// CHECK-LABEL: sil shared [thunk] [ossa] @$s18partial_apply_init1CC{{[_0-9a-zA-Z]*}}fCTcTd -// CHECK: function_ref @$s18partial_apply_init1CC{{[_0-9a-zA-Z]*}}fC -// CHECK-LABEL: sil shared [thunk] [ossa] @$s18partial_apply_init1CC{{[_0-9a-zA-Z]*}}fCTcTd -// CHECK: function_ref @$s18partial_apply_init1CC{{[_0-9a-zA-Z]*}}fC -// CHECK-LABEL: sil shared [thunk] [ossa] @$s18partial_apply_init1CC{{[_0-9a-zA-Z]*}}fC -// CHECK: class_method %0 : $@thick C.Type, #C.init!allocator.1 +// CHECK-LABEL: sil private [ossa] @$s18partial_apply_init06class_c1_a1_B01cyAA1CCm_tFAESicfu_ : $@convention(thin) (Int) -> @owned C +// CHECK: function_ref @$s18partial_apply_init1CC1xACSi_tcfC + +// CHECK-LABEL: sil private [ossa] @$s18partial_apply_init06class_c1_a1_B01cyAA1CCm_tFAESdcfu0_ : $@convention(thin) (Double) -> @owned C +// CHECK: function_ref @$s18partial_apply_init1CC8requiredACSd_tcfC + +// CHECK-LABEL: sil private [ossa] @$s18partial_apply_init06class_c1_a1_B01cyAA1CCm_tFAESdcAEmcfu1_AESdcfu2_ : $@convention(thin) (Double, @thick C.Type) -> @owned C +// CHECK: class_method %1 : $@thick C.Type, #C.init!allocator.1 // CHECK-LABEL: sil hidden [ossa] @$s18partial_apply_init010archetype_c1_a1_B0{{[_0-9a-zA-Z]*}}F func archetype_init_partial_apply(t: T.Type) where T: P { // Archetype initializations are always dynamic, whether applied to the type or a metatype. - // CHECK: function_ref @$s18partial_apply_init1CC{{[_0-9a-zA-Z]*}}fC + // CHECK: function_ref @$s18partial_apply_init010archetype_c1_a1_B01tyxm_tAA1CCRbzAA1PRzlFAESdcAEmcfu_ let requiredT: (Double) -> T = T.init - // CHECK: function_ref @$s18partial_apply_init1PP{{[_0-9a-zA-Z]*}}fC + // CHECK: function_ref @$s18partial_apply_init010archetype_c1_a1_B01tyxm_tAA1CCRbzAA1PRzlFxSScxmcfu1_ let protoT: (String) -> T = T.init - // CHECK: function_ref @$s18partial_apply_init1PPAAE{{[_0-9a-zA-Z]*}}fC + // CHECK: function_ref @$s18partial_apply_init010archetype_c1_a1_B01tyxm_tAA1CCRbzAA1PRzlFxSfcxmcfu3_ let protoExtT: (Float) -> T = T.init - // CHECK: function_ref @$s18partial_apply_init1CC{{[_0-9a-zA-Z]*}}fC + // CHECK: function_ref @$s18partial_apply_init010archetype_c1_a1_B01tyxm_tAA1CCRbzAA1PRzlFAESdcAEmcfu5_ let requiredM: (Double) -> T = t.init - // CHECK: function_ref @$s18partial_apply_init1PP{{[_0-9a-zA-Z]*}}fC + // CHECK: function_ref @$s18partial_apply_init010archetype_c1_a1_B01tyxm_tAA1CCRbzAA1PRzlFxSScxmcfu7_ let protoM: (String) -> T = t.init - // CHECK: function_ref @$s18partial_apply_init1PPAAE{{[_0-9a-zA-Z]*}}fC + // CHECK: function_ref @$s18partial_apply_init010archetype_c1_a1_B01tyxm_tAA1CCRbzAA1PRzlFxSfcxmcfu9_ let protoExtM: (Float) -> T = t.init } -// CHECK-LABEL: sil shared [thunk] [ossa] @$s18partial_apply_init1PP{{[_0-9a-zA-Z]*}}fC -// CHECK: witness_method $Self, #P.init!allocator.1 -// CHECK-LABEL: sil shared [thunk] [ossa] @$s18partial_apply_init1PPAAE{{[_0-9a-zA-Z]*}}fC -// CHECK: function_ref @$s18partial_apply_init1PPAAE{{[_0-9a-zA-Z]*}}fC +// CHECK-LABEL: sil private [ossa] @$s18partial_apply_init010archetype_c1_a1_B01tyxm_tAA1CCRbzAA1PRzlFAESdcAEmcfu_AESdcfu0_ : $@convention(thin) (Double, @thick C.Type) -> @owned C +// CHECK: class_method %1 : $@thick C.Type, #C.init!allocator.1 : (C.Type) -> (Double) -> C, $@convention(method) (Double, @thick C.Type) -> @owned C + +// CHECK-LABEL: sil private [ossa] @$s18partial_apply_init010archetype_c1_a1_B01tyxm_tAA1CCRbzAA1PRzlFxSScxmcfu1_xSScfu2_ : $@convention(thin) (@guaranteed String, @thick T.Type) -> @owned T +// CHECK: witness_method $T, #P.init!allocator.1 : (Self.Type) -> (String) -> Self + +// CHECK-LABEL: sil private [ossa] @$s18partial_apply_init010archetype_c1_a1_B01tyxm_tAA1CCRbzAA1PRzlFxSfcxmcfu3_xSfcfu4_ : $@convention(thin) (Float, @thick T.Type) -> @owned T +// CHECK: function_ref @$s18partial_apply_init1PPAAE8protoExtxSf_tcfC : $@convention(method) <τ_0_0 where τ_0_0 : P> (Float, @thick τ_0_0.Type) -> @out τ_0_0 + +// CHECK-LABEL: sil private [ossa] @$s18partial_apply_init010archetype_c1_a1_B01tyxm_tAA1CCRbzAA1PRzlFAESdcAEmcfu5_AESdcfu6_ : $@convention(thin) (Double, @thick C.Type) -> @owned C +// CHECK: class_method %1 : $@thick C.Type, #C.init!allocator.1 : (C.Type) -> (Double) -> C + +// CHECK-LABEL: sil private [ossa] @$s18partial_apply_init010archetype_c1_a1_B01tyxm_tAA1CCRbzAA1PRzlFxSScxmcfu7_xSScfu8_ : $@convention(thin) (@guaranteed String, @thick T.Type) -> @owned T +// CHECK: witness_method $T, #P.init!allocator.1 : (Self.Type) -> (String) -> Self +// CHECK-LABEL: sil private [ossa] @$s18partial_apply_init010archetype_c1_a1_B01tyxm_tAA1CCRbzAA1PRzlFxSfcxmcfu9_xSfcfu10_ : $@convention(thin) (Float, @thick T.Type) -> @owned T +// CHECK: function_ref @$s18partial_apply_init1PPAAE8protoExtxSf_tcfC : $@convention(method) <τ_0_0 where τ_0_0 : P> (Float, @thick τ_0_0.Type) -> @out τ_0_0 \ No newline at end of file diff --git a/test/SILGen/partial_apply_override.swift b/test/SILGen/partial_apply_override.swift index 07fdeaf38a65e..d168c21960266 100644 --- a/test/SILGen/partial_apply_override.swift +++ b/test/SILGen/partial_apply_override.swift @@ -24,16 +24,13 @@ public func convert(strings: [String]) -> [Int] { // CHECK-NEXT: [[ALLOC_CONVERTER:%.*]] = function_ref @$s22partial_apply_override18StringIntConverterCACycfC : // CHECK-NEXT: [[CONVERTER:%.*]] = apply [[ALLOC_CONVERTER]]([[CONVERTER_TYPE]]) // CHECK-NEXT: // function_ref -// CHECK-NEXT: [[CURRY_THUNK:%.*]] = function_ref @$s22partial_apply_override18StringIntConverterC7convert5inputSiSS_tFTc : $@convention(thin) (@guaranteed StringIntConverter) -> @owned @callee_guaranteed (@guaranteed String) -> Int +// CHECK-NEXT: [[CURRY_THUNK:%.*]] = function_ref @$s22partial_apply_override7convert7stringsSaySiGSaySSG_tFSiSScAA18StringIntConverterCcfu_ : $@convention(thin) (@guaranteed StringIntConverter) -> @owned @callee_guaranteed (@guaranteed String) -> Int // CHECK-NEXT: [[CURRY_RESULT:%.*]] = apply [[CURRY_THUNK]]([[CONVERTER]]) -// CHECK-NEXT: destroy_value [[CONVERTER]] : +// CHECK: [[CONVERTED:%.*]] = convert_function [[CURRY_RESULT]] +// CHECK: [[NOESCAPE:%.*]] = convert_escape_to_noescape [not_guaranteed] [[CONVERTED]] +// CHECK: // function_ref +// CHECK-NEXT: [[THUNK:%.*]] = function_ref @$sSSSis5Error_pIggdzo_SSSisAA_pIegnrzo_TR : $@convention(thin) (@in_guaranteed String, @noescape @callee_guaranteed (@guaranteed String) -> (Int, @error Error)) -> (@out Int, @error Error) +// CHECK-NEXT: [[REABSTRACTED:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[NOESCAPE]]) -// CHECK-LABEL: sil shared [thunk] [ossa] @$s22partial_apply_override18StringIntConverterC7convert5inputSiSS_tFTc : -// CHECK-SAME: $@convention(thin) (@guaranteed StringIntConverter) -> @owned @callee_guaranteed (@guaranteed String) -> Int -// CHECK: [[METHOD:%.*]] = class_method %0 : $StringIntConverter, #StringIntConverter.convert!1 : (StringIntConverter) -> (String) -> Int, $@convention(method) (@in_guaranteed String, @guaranteed StringIntConverter) -> @out Int -// CHECK-NEXT: [[SELF_COPY:%.*]] = copy_value %0 : -// CHECK-NEXT: [[BOUND_METHOD:%.*]] = partial_apply [callee_guaranteed] [[METHOD]]([[SELF_COPY]]) -// CHECK-NEXT: // function_ref -// CHECK-NEXT: [[THUNK:%.*]] = function_ref @$sSSSiIegnr_SSSiIeggd_TR : $@convention(thin) (@guaranteed String, @guaranteed @callee_guaranteed (@in_guaranteed String) -> @out Int) -> Int -// CHECK-NEXT: [[REABSTRACTED:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[BOUND_METHOD]]) -// CHECK-NEXT: return [[REABSTRACTED]] +// CHECK-LABEL: sil private [ossa] @$s22partial_apply_override7convert7stringsSaySiGSaySSG_tFSiSScAA18StringIntConverterCcfu_SiSScfu0_ : $@convention(thin) (@guaranteed String, @guaranteed StringIntConverter) -> Int +// CHECK: [[METHOD:%.*]] = class_method %1 : $StringIntConverter, #StringIntConverter.convert!1 : (StringIntConverter) -> (String) -> Int, $@convention(method) (@in_guaranteed String, @guaranteed StringIntConverter) -> @out Int \ No newline at end of file diff --git a/test/SILGen/partial_apply_protocol.swift b/test/SILGen/partial_apply_protocol.swift index af84fdbdae632..49ea224e65b79 100644 --- a/test/SILGen/partial_apply_protocol.swift +++ b/test/SILGen/partial_apply_protocol.swift @@ -18,16 +18,16 @@ protocol Clonable { // CHECK-LABEL: sil hidden [ossa] @$s22partial_apply_protocol12testClonable1cyAA0E0_p_tF : $@convention(thin) (@in_guaranteed Clonable) -> () func testClonable(c: Clonable) { - // CHECK: [[THUNK_FN:%.*]] = function_ref @$sxIegr_22partial_apply_protocol8Clonable_pIegr_AaBRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @out τ_0_0) -> @out Clonable - // CHECK: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]<@opened("{{.*}}") Clonable>({{.*}}) + // CHECK: [[THUNK_FN:%.*]] = function_ref @$s22partial_apply_protocol12testClonable1cyAA0E0_p_tFAaD_pycAaD_pcfu_ : $@convention(thin) (@in_guaranteed Clonable) -> @owned @callee_guaranteed () -> @out Clonable + // CHECK: [[THUNK:%.*]] = apply [[THUNK_FN]]({{.*}}) let _: () -> Clonable = c.clone - // CHECK: [[THUNK_FN:%.*]] = function_ref @$sxSgIegr_22partial_apply_protocol8Clonable_pSgIegr_AbCRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @out Optional<τ_0_0>) -> @out Optional - // CHECK: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]<@opened("{{.*}}") Clonable>({{.*}}) + // CHECK: [[THUNK_FN:%.*]] = function_ref @$s22partial_apply_protocol12testClonable1cyAA0E0_p_tFAaD_pSgycAaD_pcfu1_ : $@convention(thin) (@in_guaranteed Clonable) -> @owned @callee_guaranteed () -> @out Optional + // CHECK: [[THUNK:%.*]] = apply [[THUNK_FN]]({{.*}}) let _: () -> Clonable? = c.maybeClone - // CHECK: [[THUNK_FN:%.*]] = function_ref @$sxXMTIegd_22partial_apply_protocol8Clonable_pXmTIegd_AaBRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @thick τ_0_0.Type) -> @thick Clonable.Type - // CHECK: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]<@opened("{{.*}}") Clonable>({{.*}}) : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @thick τ_0_0.Type) -> @thick Clonable.Type + // CHECK: [[THUNK_FN:%.*]] = function_ref @$s22partial_apply_protocol12testClonable1cyAA0E0_p_tFAaD_pXpycAaD_pcfu3_ : $@convention(thin) (@in_guaranteed Clonable) -> @owned @callee_guaranteed () -> @thick Clonable.Type + // CHECK: [[THUNK:%.*]] = apply [[THUNK_FN]]({{.*}}) let _: () -> Clonable.Type = c.cloneMetatype // CHECK: [[METHOD_FN:%.*]] = witness_method $@opened("{{.*}}") Clonable, #Clonable.getCloneFn!1 @@ -37,8 +37,8 @@ func testClonable(c: Clonable) { // CHECK: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]<@opened("{{.*}}") Clonable>([[CONV_RESULT]]) let _: () -> Clonable = c.getCloneFn() - // CHECK: [[THUNK_FN:%.*]] = function_ref @$sxlyxIsegr_Iego_22partial_apply_protocol8Clonable_pIegr_Iego_AaBRzlTR - // CHECK: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]<@opened("{{.*}}") Clonable>({{.*}}) + // CHECK: [[THUNK_FN:%.*]] = function_ref @$s22partial_apply_protocol12testClonable1cyAA0E0_p_tFAaD_pycycAaD_pcfu5_ + // CHECK: [[THUNK:%.*]] = apply [[THUNK_FN]]({{.*}}) let _: () -> () -> Clonable = c.getCloneFn } @@ -52,48 +52,6 @@ func testClonable(c: Clonable) { // CHECK-NEXT: dealloc_stack [[INNER_RESULT]] // CHECK-NEXT: return [[EMPTY]] -// FIXME: This is horribly inefficient, too much alloc_stack / copy_addr! - -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sxSgIegr_22partial_apply_protocol8Clonable_pSgIegr_AbCRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @out Optional<τ_0_0>) -> @out Optional -// CHECK: bb0(%0 : $*Optional, %1 : @guaranteed $@callee_guaranteed () -> @out Optional<τ_0_0>): -// CHECK-NEXT: [[INNER_RESULT:%.*]] = alloc_stack $Optional<τ_0_0> -// CHECK-NEXT: apply %1([[INNER_RESULT]]) -// CHECK-NEXT: [[OUTER_RESULT:%.*]] = alloc_stack $Optional -// CHECK-NEXT: switch_enum_addr [[INNER_RESULT]] : $*Optional<{{.*}}>, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9]+]], -// CHECK: [[SOME_BB]]: -// CHECK-NEXT: [[INNER_RESULT_ADDR:%.*]] = unchecked_take_enum_data_addr [[INNER_RESULT]] -// CHECK-NEXT: [[SOME_PAYLOAD:%.*]] = alloc_stack $Clonable -// CHECK-NEXT: [[SOME_PAYLOAD_ADDR:%.*]] = init_existential_addr [[SOME_PAYLOAD]] -// CHECK-NEXT: copy_addr [take] [[INNER_RESULT_ADDR]] to [initialization] [[SOME_PAYLOAD_ADDR]] -// CHECK-NEXT: [[OUTER_RESULT_ADDR:%.*]] = init_enum_data_addr [[OUTER_RESULT]] -// CHECK-NEXT: copy_addr [take] [[SOME_PAYLOAD]] to [initialization] [[OUTER_RESULT_ADDR]] -// CHECK-NEXT: inject_enum_addr [[OUTER_RESULT]] -// CHECK-NEXT: dealloc_stack [[SOME_PAYLOAD]] -// CHECK-NEXT: br bb3 -// CHECK: bb2: -// CHECK-NEXT: inject_enum_addr [[OUTER_RESULT]] -// CHECK-NEXT: br bb3 -// CHECK: bb3: -// CHECK-NEXT: copy_addr [take] [[OUTER_RESULT]] to [initialization] %0 -// CHECK-NEXT: [[EMPTY:%.*]] = tuple () -// CHECK-NEXT: dealloc_stack [[OUTER_RESULT]] -// CHECK-NEXT: dealloc_stack [[INNER_RESULT]] -// CHECK-NEXT: return [[EMPTY]] - -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sxXMTIegd_22partial_apply_protocol8Clonable_pXmTIegd_AaBRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @thick τ_0_0.Type) -> @thick Clonable.Type -// CHECK: bb0(%0 : @guaranteed $@callee_guaranteed () -> @thick τ_0_0.Type): -// CHECK-NEXT: [[INNER_RESULT:%.*]] = apply %0() -// CHECK-NEXT: [[OUTER_RESULT:%.*]] = init_existential_metatype [[INNER_RESULT]] -// CHECK-NEXT: return [[OUTER_RESULT]] - -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sxlyxIsegr_Iego_22partial_apply_protocol8Clonable_pIegr_Iego_AaBRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @owned @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <τ_0_0>) -> @owned @callee_guaranteed () -> @out Clonable -// CHECK: bb0(%0 : -// CHECK-NEXT: [[INNER_RESULT:%.*]] = apply %0() -// CHECK-NEXT: [[INNER_RESULT_CONV:%.*]] = convert_function [[INNER_RESULT]] -// CHECK: [[THUNK_FN:%.*]] = function_ref @$sxIegr_22partial_apply_protocol8Clonable_pIegr_AaBRzlTR -// CHECK-NEXT: [[OUTER_RESULT:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]<τ_0_0>([[INNER_RESULT_CONV]]) -// CHECK-NEXT: return [[OUTER_RESULT]] - //===----------------------------------------------------------------------===// // Partial apply of methods returning Self-derived types from generic context // @@ -102,16 +60,16 @@ func testClonable(c: Clonable) { // CHECK-LABEL: sil hidden [ossa] @$s22partial_apply_protocol28testClonableInGenericContext1c1tyAA0E0_p_xtlF : $@convention(thin) (@in_guaranteed Clonable, @in_guaranteed T) -> () func testClonableInGenericContext(c: Clonable, t: T) { - // CHECK: [[THUNK_FN:%.*]] = function_ref @$sxIegr_22partial_apply_protocol8Clonable_pIegr_AaBRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @out τ_0_0) -> @out Clonable - // CHECK: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]<@opened("{{.*}}") Clonable>({{.*}}) + // CHECK: [[THUNK_FN:%.*]] = function_ref @$s22partial_apply_protocol28testClonableInGenericContext1c1tyAA0E0_p_xtlFAaE_pycAaE_pcfu_ : $@convention(thin) (@in_guaranteed Clonable) -> @owned @callee_guaranteed () -> @out Clonable + // CHECK: [[THUNK:%.*]] = apply [[THUNK_FN]]({{.*}}) let _: () -> Clonable = c.clone - // CHECK: [[THUNK_FN:%.*]] = function_ref @$sxSgIegr_22partial_apply_protocol8Clonable_pSgIegr_AbCRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @out Optional<τ_0_0>) -> @out Optional - // CHECK: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]<@opened("{{.*}}") Clonable>({{.*}}) : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @out Optional<τ_0_0>) -> @out Optional + // CHECK: [[THUNK_FN:%.*]] = function_ref @$s22partial_apply_protocol28testClonableInGenericContext1c1tyAA0E0_p_xtlFAaE_pSgycAaE_pcfu1_ : $@convention(thin) (@in_guaranteed Clonable) -> @owned @callee_guaranteed () -> @out Optional // user: %8 + // CHECK: [[THUNK:%.*]] = apply [[THUNK_FN]]({{.*}}) let _: () -> Clonable? = c.maybeClone - // CHECK: [[THUNK_FN:%.*]] = function_ref @$sxXMTIegd_22partial_apply_protocol8Clonable_pXmTIegd_AaBRzlTR : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @thick τ_0_0.Type) -> @thick Clonable.Type - // CHECK: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]<@opened("{{.*}}") Clonable>({{.*}}) : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @thick τ_0_0.Type) -> @thick Clonable.Type + // CHECK: [[THUNK_FN:%.*]] = function_ref @$s22partial_apply_protocol28testClonableInGenericContext1c1tyAA0E0_p_xtlFAaE_pXpycAaE_pcfu3_ : $@convention(thin) (@in_guaranteed Clonable) -> @owned @callee_guaranteed () -> @thick Clonable.Type + // CHECK: [[THUNK:%.*]] = apply [[THUNK_FN]]({{.*}}) let _: () -> Clonable.Type = c.cloneMetatype // CHECK: [[METHOD_FN:%.*]] = witness_method $@opened("{{.*}}") Clonable, #Clonable.getCloneFn!1 : @@ -121,43 +79,15 @@ func testClonableInGenericContext(c: Clonable, t: T) { // CHECK: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]<@opened("{{.*}}") Clonable>([[RESULT_CONV]]) : $@convention(thin) <τ_0_0 where τ_0_0 : Clonable> (@guaranteed @callee_guaranteed () -> @out τ_0_0) -> @out Clonable let _: () -> Clonable = c.getCloneFn() - // CHECK: [[THUNK_FN:%.*]] = function_ref @$sxlyxIsegr_Iego_22partial_apply_protocol8Clonable_pIegr_Iego_AaBRzlTR - // CHECK: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]<@opened("{{.*}}") Clonable>({{.*}}) + // CHECK: [[THUNK_FN:%.*]] = function_ref @$s22partial_apply_protocol28testClonableInGenericContext1c1tyAA0E0_p_xtlFAaE_pycycAaE_pcfu5_ : $@convention(thin) (@in_guaranteed Clonable) -> @owned @callee_guaranteed () -> @owned @callee_guaranteed () -> @out Clonable + // CHECK: [[THUNK:%.*]] = apply [[THUNK_FN]]({{.*}}) let _: () -> () -> Clonable = c.getCloneFn - // CHECK: [[THUNK_FN:%.*]] = function_ref @$sxqd__Iegnr_x22partial_apply_protocol8Clonable_pIegnr_AaBRd__r__lTR : $@convention(thin) <τ_0_0><τ_1_0 where τ_1_0 : Clonable> (@in_guaranteed τ_0_0, @guaranteed @callee_guaranteed (@in_guaranteed τ_0_0) -> @out τ_1_0) -> @out Clonable - // CHECK: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]({{.*}}) : $@convention(thin) <τ_0_0><τ_1_0 where τ_1_0 : Clonable> (@in_guaranteed τ_0_0, @guaranteed @callee_guaranteed (@in_guaranteed τ_0_0) -> @out τ_1_0) -> @out Clonable + // CHECK: [[THUNK_FN:%.*]] = function_ref @$s22partial_apply_protocol28testClonableInGenericContext1c1tyAA0E0_p_xtlFAaE_pxcAaE_pcfu7_ : $@convention(thin) <τ_0_0> (@in_guaranteed Clonable) -> @owned @callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> @out Clonable for <τ_0_0> + // CHECK: [[THUNK:%.*]] = apply [[THUNK_FN]]({{.*}}) let _: (T) -> Clonable = c.genericClone - // CHECK: [[THUNK_FN:%.*]] = function_ref @$sxxlyqd__Isegr_Iegno_x22partial_apply_protocol8Clonable_pIegr_Iegno_AaBRd__r__lTR : - // CHECK: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]({{.*}}) : + // CHECK: [[THUNK_FN:%.*]] = function_ref @$s22partial_apply_protocol28testClonableInGenericContext1c1tyAA0E0_p_xtlFAaE_pycxcAaE_pcfu9_ : $@convention(thin) <τ_0_0> (@in_guaranteed Clonable) -> @owned @callee_guaranteed @substituted <τ_0_0> (@in_guaranteed τ_0_0) -> (@owned @callee_guaranteed () -> @out Clonable) for <τ_0_0> + // CHECK: [[THUNK:%.*]] = apply [[THUNK_FN]]({{.*}}) let _: (T) -> () -> Clonable = c.genericGetCloneFn } - -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sxqd__Iegnr_x22partial_apply_protocol8Clonable_pIegnr_AaBRd__r__lTR : $@convention(thin) <τ_0_0><τ_1_0 where τ_1_0 : Clonable> (@in_guaranteed τ_0_0, @guaranteed @callee_guaranteed (@in_guaranteed τ_0_0) -> @out τ_1_0) -> @out Clonable -// CHECK: bb0(%0 : $*Clonable, %1 : $*τ_0_0, %2 : @guaranteed $@callee_guaranteed (@in_guaranteed τ_0_0) -> @out τ_1_0): -// CHECK-NEXT: [[INNER_RESULT:%.*]] = alloc_stack $τ_1_0 -// CHECK-NEXT: apply %2([[INNER_RESULT]], %1) -// CHECK-NEXT: [[OUTER_RESULT:%.*]] = init_existential_addr %0 -// CHECK-NEXT: copy_addr [take] [[INNER_RESULT]] to [initialization] [[OUTER_RESULT]] -// CHECK-NEXT: [[EMPTY:%.*]] = tuple () -// CHECK-NEXT: dealloc_stack [[INNER_RESULT]] -// CHECK-NEXT: return [[EMPTY]] - -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sxxlyqd__Isegr_Iegno_x22partial_apply_protocol8Clonable_pIegr_Iegno_AaBRd__r__lTR : $@convention(thin) <τ_0_0><τ_1_0 where τ_1_0 : Clonable> (@in_guaranteed τ_0_0, @guaranteed @callee_guaranteed (@in_guaranteed τ_0_0) -> @owned @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <τ_1_0>) -> @owned @callee_guaranteed () -> @out Clonable { -// CHECK: bb0(%0 : $*τ_0_0, %1 : @guaranteed $@callee_guaranteed (@in_guaranteed τ_0_0) -> @owned @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <τ_1_0>): -// CHECK-NEXT: [[RES:%.*]] = apply %1(%0) -// CHECK-NEXT: [[RES_CONV:%.*]] = convert_function [[RES]] -// CHECK: [[THUNK_FN:%.*]] = function_ref @$sqd__Iegr_22partial_apply_protocol8Clonable_pIegr_AaBRd__r__lTR -// CHECK-NEXT: [[RESULT:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]<τ_0_0, τ_1_0>([[RES_CONV]]) -// CHECK-NEXT: return [[RESULT]] - -// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sqd__Iegr_22partial_apply_protocol8Clonable_pIegr_AaBRd__r__lTR : $@convention(thin) <τ_0_0><τ_1_0 where τ_1_0 : Clonable> (@guaranteed @callee_guaranteed () -> @out τ_1_0) -> @out Clonable { -// CHECK: bb0(%0 : $*Clonable, %1 : @guaranteed $@callee_guaranteed () -> @out τ_1_0): -// CHECK-NEXT: [[INNER_RESULT:%.*]] = alloc_stack $τ_1_0 -// CHECK-NEXT: apply %1([[INNER_RESULT]]) -// CHECK-NEXT: [[OUTER_RESULT:%.*]] = init_existential_addr %0 -// CHECK-NEXT: copy_addr [take] [[INNER_RESULT]] to [initialization] [[OUTER_RESULT]] -// CHECK-NEXT: [[EMPTY:%.*]] = tuple () -// CHECK-NEXT: dealloc_stack [[INNER_RESULT:%.*]] -// CHECK-NEXT: return [[EMPTY]] diff --git a/test/SILGen/partial_apply_super.swift b/test/SILGen/partial_apply_super.swift index ef41fc1ca5578..1374afea8bc39 100644 --- a/test/SILGen/partial_apply_super.swift +++ b/test/SILGen/partial_apply_super.swift @@ -40,56 +40,51 @@ public class GenericParent { class Child : Parent { // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super5ChildC6methodyyF : $@convention(method) (@guaranteed Child) -> () // CHECK: bb0([[SELF:%.*]] : @guaranteed $Child): - // CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] - // CHECK: [[CASTED_SELF_COPY:%.*]] = upcast [[SELF_COPY]] : $Child to $Parent - // CHECK: [[SUPER_METHOD:%.*]] = function_ref @$s19partial_apply_super6ParentC6methodyyFTcTd : $@convention(thin) (@guaranteed Parent) -> @owned @callee_guaranteed () -> () - // CHECK: [[PARTIAL_APPLY:%.*]] = apply [[SUPER_METHOD]]([[CASTED_SELF_COPY]]) : $@convention(thin) (@guaranteed Parent) -> @owned @callee_guaranteed () -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super5ChildC6methodyyFyycfu_ : $@convention(thin) (@guaranteed Child) -> () // CHECK: } // end sil function '$s19partial_apply_super5ChildC6methodyyF' override func method() { doFoo(super.method) } + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super5ChildC6methodyyFyycfu_ : $@convention(thin) (@guaranteed Child) -> () + // CHECK: function_ref @$s19partial_apply_super6ParentC6methodyyF : $@convention(method) (@guaranteed Parent) -> () + // CHECK: } // end sil function '$s19partial_apply_super5ChildC6methodyyFyycfu_' + + // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super5ChildC11classMethodyyFZ : $@convention(method) (@thick Child.Type) -> () { - // CHECK: [[CASTED_SELF:%.*]] = upcast %0 : $@thick Child.Type to $@thick Parent.Type - // CHECK: [[SUPER_METHOD:%.*]] = function_ref @$s19partial_apply_super6ParentC11classMethodyyFZTcTd : $@convention(thin) (@thick Parent.Type) -> @owned @callee_guaranteed () -> () - // CHECK: [[PARTIAL_APPLY:%.*]] = apply [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(thin) (@thick Parent.Type) -> @owned @callee_guaranteed () -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super5ChildC11classMethodyyFZyycfu_ : $@convention(thin) (@thick Child.Type) -> () // CHECK: } // end sil function '$s19partial_apply_super5ChildC11classMethodyyFZ' override class func classMethod() { doFoo(super.classMethod) } + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super5ChildC11classMethodyyFZyycfu_ : $@convention(thin) (@thick Child.Type) -> () + // CHECK: function_ref @$s19partial_apply_super6ParentC11classMethodyyFZ : $@convention(method) (@thick Parent.Type) -> () + // CHECK: } // end sil function '$s19partial_apply_super5ChildC11classMethodyyFZyycfu_' + + // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super5ChildC20callFinalSuperMethodyyF : $@convention(method) (@guaranteed Child) -> () - // CHECK: bb0([[SELF:%.*]] : @guaranteed $Child): - // CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] - // CHECK: [[CASTED_SELF_COPY:%.*]] = upcast [[SELF_COPY]] : $Child to $Parent - // CHECK: [[SUPER_METHOD:%.*]] = function_ref @$s19partial_apply_super6ParentC11finalMethodyyFTc : $@convention(thin) (@guaranteed Parent) -> @owned @callee_guaranteed () -> () - // CHECK: [[APPLIED_SELF:%.*]] = apply [[SUPER_METHOD]]([[CASTED_SELF_COPY]]) : $@convention(thin) (@guaranteed Parent) -> @owned @callee_guaranteed () -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[APPLIED_SELF]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super5ChildC20callFinalSuperMethodyyFyycfu_ : $@convention(thin) (@guaranteed Child) -> () // CHECK: } // end sil function '$s19partial_apply_super5ChildC20callFinalSuperMethodyyF' func callFinalSuperMethod() { doFoo(super.finalMethod) } + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super5ChildC20callFinalSuperMethodyyFyycfu_ : $@convention(thin) (@guaranteed Child) -> () + // CHECK: function_ref @$s19partial_apply_super6ParentC11finalMethodyyF : $@convention(method) (@guaranteed Parent) -> () + // CHECK: } // end sil function '$s19partial_apply_super5ChildC20callFinalSuperMethodyyFyycfu_' + + // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super5ChildC25callFinalSuperClassMethodyyFZ : $@convention(method) (@thick Child.Type) -> () - // CHECK: bb0([[ARG:%.*]] : $@thick Child.Type): - // CHECK: [[CASTED_SELF:%.*]] = upcast [[ARG]] : $@thick Child.Type to $@thick Parent.Type - // CHECK: [[SUPER_METHOD:%.*]] = function_ref @$s19partial_apply_super6ParentC16finalClassMethodyyFZTc : $@convention(thin) (@thick Parent.Type) -> @owned @callee_guaranteed () -> () - // CHECK: [[APPLIED_SELF:%.*]] = apply [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(thin) (@thick Parent.Type) -> @owned @callee_guaranteed () -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[APPLIED_SELF]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super5ChildC25callFinalSuperClassMethodyyFZyycfu_ : $@convention(thin) (@thick Child.Type) -> () // CHECK: } // end sil function '$s19partial_apply_super5ChildC25callFinalSuperClassMethodyyFZ' class func callFinalSuperClassMethod() { doFoo(super.finalClassMethod) } + + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super5ChildC25callFinalSuperClassMethodyyFZyycfu_ : $@convention(thin) (@thick Child.Type) -> () + // CHECK: function_ref @$s19partial_apply_super6ParentC16finalClassMethodyyFZ : $@convention(method) (@thick Parent.Type) -> () + // CHECK: } // end sil function '$s19partial_apply_super5ChildC25callFinalSuperClassMethodyyFZyycfu_' } class GenericChild : GenericParent { @@ -97,213 +92,174 @@ class GenericChild : GenericParent { super.init(a: a) } // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super12GenericChildC6methodyyF : $@convention(method) (@guaranteed GenericChild) -> () - // CHECK: bb0([[SELF:%.*]] : @guaranteed $GenericChild): - // CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] - // CHECK: [[CASTED_SELF_COPY:%.*]] = upcast [[SELF_COPY]] : $GenericChild to $GenericParent - // CHECK: [[SUPER_METHOD:%.*]] = function_ref @$s19partial_apply_super13GenericParentC6methodyyFTcTd : $@convention(thin) <τ_0_0> (@guaranteed GenericParent<τ_0_0>) -> @owned @callee_guaranteed () -> () - // CHECK: [[PARTIAL_APPLY:%.*]] = apply [[SUPER_METHOD]]([[CASTED_SELF_COPY]]) : $@convention(thin) <τ_0_0> (@guaranteed GenericParent<τ_0_0>) -> @owned @callee_guaranteed () -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super12GenericChildC6methodyyFyycfu_ : $@convention(thin) <τ_0_0> (@guaranteed GenericChild<τ_0_0>) -> () // CHECK: } // end sil function '$s19partial_apply_super12GenericChildC6methodyyF' override func method() { doFoo(super.method) } + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super12GenericChildC6methodyyFyycfu_ : $@convention(thin) (@guaranteed GenericChild) -> () + // CHECK: function_ref @$s19partial_apply_super13GenericParentC6methodyyF : $@convention(method) <τ_0_0> (@guaranteed GenericParent<τ_0_0>) -> () + // CHECK: } // end sil function '$s19partial_apply_super12GenericChildC6methodyyFyycfu_' + + // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super12GenericChildC11classMethodyyFZ : $@convention(method) (@thick GenericChild.Type) -> () - // CHECK: [[CASTED_SELF:%.*]] = upcast %0 : $@thick GenericChild.Type to $@thick GenericParent.Type - // CHECK: [[SUPER_METHOD:%.*]] = function_ref @$s19partial_apply_super13GenericParentC11classMethodyyFZTcTd : $@convention(thin) <τ_0_0> (@thick GenericParent<τ_0_0>.Type) -> @owned @callee_guaranteed () -> () - // CHECK: [[PARTIAL_APPLY:%.*]] = apply [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(thin) <τ_0_0> (@thick GenericParent<τ_0_0>.Type) -> @owned @callee_guaranteed () -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super12GenericChildC11classMethodyyFZyycfu_ : $@convention(thin) <τ_0_0> (@thick GenericChild<τ_0_0>.Type) -> () // CHECK: } // end sil function '$s19partial_apply_super12GenericChildC11classMethodyyFZ' override class func classMethod() { doFoo(super.classMethod) } + + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super12GenericChildC11classMethodyyFZyycfu_ : $@convention(thin) (@thick GenericChild.Type) -> () + // CHECK: function_ref @$s19partial_apply_super13GenericParentC11classMethodyyFZ : $@convention(method) <τ_0_0> (@thick GenericParent<τ_0_0>.Type) -> () + // CHECK: } // end sil function '$s19partial_apply_super12GenericChildC11classMethodyyFZyycfu_' } class ChildToFixedOutsideParent : OutsideParent { // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super25ChildToFixedOutsideParentC6methodyyF - // CHECK: bb0([[SELF:%.*]] : @guaranteed $ChildToFixedOutsideParent): - // CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] - // CHECK: [[CASTED_SELF_COPY:%.*]] = upcast [[SELF_COPY]] : $ChildToFixedOutsideParent to $OutsideParent - // CHECK: [[BORROWED_CASTED_SELF_COPY:%.*]] = begin_borrow [[CASTED_SELF_COPY]] - // CHECK: [[DOWNCAST_BORROWED_CASTED_SELF_COPY:%.*]] = unchecked_ref_cast [[BORROWED_CASTED_SELF_COPY]] - // CHECK: [[SUPER_METHOD:%.*]] = super_method [[DOWNCAST_BORROWED_CASTED_SELF_COPY]] : $ChildToFixedOutsideParent, #OutsideParent.method!1 : (OutsideParent) -> () -> (), $@convention(method) (@guaranteed OutsideParent) -> () - // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF_COPY]]) : $@convention(method) (@guaranteed OutsideParent) -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super25ChildToFixedOutsideParentC6methodyyFyycfu_ : $@convention(thin) (@guaranteed ChildToFixedOutsideParent) -> () // CHECK: } // end sil function '$s19partial_apply_super25ChildToFixedOutsideParentC6methodyyF' override func method() { doFoo(super.method) } + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super25ChildToFixedOutsideParentC6methodyyFyycfu_ : $@convention(thin) (@guaranteed ChildToFixedOutsideParent) -> () + // CHECK: super_method {{%.*}} : $ChildToFixedOutsideParent, #OutsideParent.method!1 : (OutsideParent) -> () -> (), $@convention(method) (@guaranteed OutsideParent) -> () + // CHECK: } // end sil function '$s19partial_apply_super25ChildToFixedOutsideParentC6methodyyFyycfu_' + + // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super25ChildToFixedOutsideParentC11classMethodyyFZ - // CHECK: [[CASTED_SELF:%.*]] = upcast %0 : $@thick ChildToFixedOutsideParent.Type to $@thick OutsideParent.Type - // CHECK: [[SUPER_METHOD:%.*]] = super_method %0 : $@thick ChildToFixedOutsideParent.Type, #OutsideParent.classMethod!1 : (OutsideParent.Type) -> () -> (), $@convention(method) (@thick OutsideParent.Type) -> (){{.*}} - // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(method) (@thick OutsideParent.Type) -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super25ChildToFixedOutsideParentC11classMethodyyFZyycfu_ : $@convention(thin) (@thick ChildToFixedOutsideParent.Type) -> () // CHECK: } // end sil function '$s19partial_apply_super25ChildToFixedOutsideParentC11classMethodyyFZ' override class func classMethod() { doFoo(super.classMethod) } + + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super25ChildToFixedOutsideParentC11classMethodyyFZyycfu_ : $@convention(thin) (@thick ChildToFixedOutsideParent.Type) -> () + // CHECK: super_method %0 : $@thick ChildToFixedOutsideParent.Type, #OutsideParent.classMethod!1 : (OutsideParent.Type) -> () -> (), $@convention(method) (@thick OutsideParent.Type) -> () + // CHECK: } // end sil function '$s19partial_apply_super25ChildToFixedOutsideParentC11classMethodyyFZyycfu_' } class ChildToResilientOutsideParent : ResilientOutsideParent { // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super29ChildToResilientOutsideParentC6methodyyF : $@convention - // CHECK: bb0([[SELF:%.*]] : @guaranteed $ChildToResilientOutsideParent): - // CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] - // CHECK: [[CASTED_SELF_COPY:%.*]] = upcast [[SELF_COPY]] : $ChildToResilientOutsideParent to $ResilientOutsideParent - // CHECK: [[BORROWED_CASTED_SELF_COPY:%.*]] = begin_borrow [[CASTED_SELF_COPY]] - // CHECK: [[DOWNCAST_BORROWED_CASTED_SELF_COPY:%.*]] = unchecked_ref_cast [[BORROWED_CASTED_SELF_COPY]] - // CHECK: [[SUPER_METHOD:%.*]] = super_method [[DOWNCAST_BORROWED_CASTED_SELF_COPY]] : $ChildToResilientOutsideParent, #ResilientOutsideParent.method!1 : (ResilientOutsideParent) -> () -> (), $@convention(method) (@guaranteed ResilientOutsideParent) -> () - // CHECK: end_borrow [[BORROWED_CASTED_SELF_COPY]] - // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF_COPY]]) : $@convention(method) (@guaranteed ResilientOutsideParent) -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super29ChildToResilientOutsideParentC6methodyyFyycfu_ : $@convention(thin) (@guaranteed ChildToResilientOutsideParent) -> () // CHECK: } // end sil function '$s19partial_apply_super29ChildToResilientOutsideParentC6methodyyF' override func method() { doFoo(super.method) } + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super29ChildToResilientOutsideParentC6methodyyFyycfu_ : $@convention(thin) (@guaranteed ChildToResilientOutsideParent) -> () + // CHECK: super_method {{%.*}} : $ChildToResilientOutsideParent, #ResilientOutsideParent.method!1 : (ResilientOutsideParent) -> () -> (), $@convention(method) (@guaranteed ResilientOutsideParent) -> () + // CHECK: } // end sil function '$s19partial_apply_super29ChildToResilientOutsideParentC6methodyyFyycfu_' + + // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super29ChildToResilientOutsideParentC11classMethodyyFZ - // CHECK: [[CASTED_SELF:%.*]] = upcast %0 : $@thick ChildToResilientOutsideParent.Type to $@thick ResilientOutsideParent.Type - // CHECK: [[SUPER_METHOD:%.*]] = super_method %0 : $@thick ChildToResilientOutsideParent.Type, #ResilientOutsideParent.classMethod!1 : (ResilientOutsideParent.Type) -> () -> (), $@convention(method) (@thick ResilientOutsideParent.Type) -> () - // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(method) (@thick ResilientOutsideParent.Type) -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super29ChildToResilientOutsideParentC11classMethodyyFZyycfu_ : $@convention(thin) (@thick ChildToResilientOutsideParent.Type) -> () // CHECK: } // end sil function '$s19partial_apply_super29ChildToResilientOutsideParentC11classMethodyyFZ' override class func classMethod() { doFoo(super.classMethod) } + + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super29ChildToResilientOutsideParentC11classMethodyyFZyycfu_ : $@convention(thin) (@thick ChildToResilientOutsideParent.Type) -> () + // CHECK: super_method %0 : $@thick ChildToResilientOutsideParent.Type, #ResilientOutsideParent.classMethod!1 : (ResilientOutsideParent.Type) -> () -> (), $@convention(method) (@thick ResilientOutsideParent.Type) -> () + // CHECK: } // end sil function '$s19partial_apply_super29ChildToResilientOutsideParentC11classMethodyyFZyycfu_' } class GrandchildToFixedOutsideChild : OutsideChild { // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super29GrandchildToFixedOutsideChildC6methodyyF - // CHECK: bb0([[SELF:%.*]] : @guaranteed $GrandchildToFixedOutsideChild): - // CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] - // CHECK: [[CASTED_SELF_COPY:%.*]] = upcast [[SELF_COPY]] : $GrandchildToFixedOutsideChild to $OutsideChild - // CHECK: [[BORROWED_CASTED_SELF_COPY:%.*]] = begin_borrow [[CASTED_SELF_COPY]] - // CHECK: [[DOWNCAST_BORROWED_CASTED_SELF_COPY:%.*]] = unchecked_ref_cast [[BORROWED_CASTED_SELF_COPY]] - // CHECK: [[SUPER_METHOD:%.*]] = super_method [[DOWNCAST_BORROWED_CASTED_SELF_COPY]] : $GrandchildToFixedOutsideChild, #OutsideChild.method!1 : (OutsideChild) -> () -> (), $@convention(method) (@guaranteed OutsideChild) -> () - // CHECK: end_borrow [[BORROWED_CASTED_SELF_COPY]] - // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF_COPY]]) : $@convention(method) (@guaranteed OutsideChild) -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super29GrandchildToFixedOutsideChildC6methodyyFyycfu_ : $@convention(thin) (@guaranteed GrandchildToFixedOutsideChild) -> () // CHECK: } // end sil function '$s19partial_apply_super29GrandchildToFixedOutsideChildC6methodyyF' override func method() { doFoo(super.method) } + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super29GrandchildToFixedOutsideChildC6methodyyFyycfu_ : $@convention(thin) (@guaranteed GrandchildToFixedOutsideChild) -> () + // CHECK: super_method {{%.*}} : $GrandchildToFixedOutsideChild, #OutsideChild.method!1 : (OutsideChild) -> () -> (), $@convention(method) (@guaranteed OutsideChild) -> () + // CHECK: } // end sil function '$s19partial_apply_super29GrandchildToFixedOutsideChildC6methodyyFyycfu_' + + // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super29GrandchildToFixedOutsideChildC11classMethodyyFZ - // CHECK: [[CASTED_SELF:%.*]] = upcast %0 : $@thick GrandchildToFixedOutsideChild.Type to $@thick OutsideChild.Type - // CHECK: [[SUPER_METHOD:%.*]] = super_method %0 : $@thick GrandchildToFixedOutsideChild.Type, #OutsideChild.classMethod!1 : (OutsideChild.Type) -> () -> (), $@convention(method) (@thick OutsideChild.Type) -> () - // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(method) (@thick OutsideChild.Type) -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super29GrandchildToFixedOutsideChildC11classMethodyyFZyycfu_ : $@convention(thin) (@thick GrandchildToFixedOutsideChild.Type) -> () // CHECK: } // end sil function '$s19partial_apply_super29GrandchildToFixedOutsideChildC11classMethodyyFZ' override class func classMethod() { doFoo(super.classMethod) } + + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super29GrandchildToFixedOutsideChildC11classMethodyyFZyycfu_ : $@convention(thin) (@thick GrandchildToFixedOutsideChild.Type) -> () + // CHECK: super_method %0 : $@thick GrandchildToFixedOutsideChild.Type, #OutsideChild.classMethod!1 : (OutsideChild.Type) -> () -> (), $@convention(method) (@thick OutsideChild.Type) -> () + // CHECK: } // end sil function '$s19partial_apply_super29GrandchildToFixedOutsideChildC11classMethodyyFZyycfu_ } class GrandchildToResilientOutsideChild : ResilientOutsideChild { // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super33GrandchildToResilientOutsideChildC6methodyyF - // CHECK: bb0([[SELF:%.*]] : @guaranteed $GrandchildToResilientOutsideChild): - // CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] - // CHECK: [[CASTED_SELF_COPY:%.*]] = upcast [[SELF_COPY]] : $GrandchildToResilientOutsideChild to $ResilientOutsideChild - // CHECK: [[BORROWED_CASTED_SELF_COPY:%.*]] = begin_borrow [[CASTED_SELF_COPY]] - // CHECK: [[DOWNCAST_BORROWED_CASTED_SELF_COPY:%.*]] = unchecked_ref_cast [[BORROWED_CASTED_SELF_COPY]] - // CHECK: [[SUPER_METHOD:%.*]] = super_method [[DOWNCAST_BORROWED_CASTED_SELF_COPY]] : $GrandchildToResilientOutsideChild, #ResilientOutsideChild.method!1 : (ResilientOutsideChild) -> () -> (), $@convention(method) (@guaranteed ResilientOutsideChild) -> () - // CHEC: end_borrow [[BORROWED_CASTED_SELF_COPY]] - // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF_COPY]]) : $@convention(method) (@guaranteed ResilientOutsideChild) -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super33GrandchildToResilientOutsideChildC6methodyyFyycfu_ : $@convention(thin) (@guaranteed GrandchildToResilientOutsideChild) -> () // CHECK: } // end sil function '$s19partial_apply_super33GrandchildToResilientOutsideChildC6methodyyF' override func method() { doFoo(super.method) } + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super33GrandchildToResilientOutsideChildC6methodyyFyycfu_ : $@convention(thin) (@guaranteed GrandchildToResilientOutsideChild) -> () + // CHECK: super_method {{%.*}} : $GrandchildToResilientOutsideChild, #ResilientOutsideChild.method!1 : (ResilientOutsideChild) -> () -> (), $@convention(method) (@guaranteed ResilientOutsideChild) -> () + // CHECK: } // end sil function '$s19partial_apply_super33GrandchildToResilientOutsideChildC6methodyyFyycfu_' + // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super33GrandchildToResilientOutsideChildC11classMethodyyFZ - // CHECK: [[CASTED_SELF:%.*]] = upcast %0 : $@thick GrandchildToResilientOutsideChild.Type to $@thick ResilientOutsideChild.Type - // CHECK: [[SUPER_METHOD:%.*]] = super_method %0 : $@thick GrandchildToResilientOutsideChild.Type, #ResilientOutsideChild.classMethod!1 : (ResilientOutsideChild.Type) -> () -> (), $@convention(method) (@thick ResilientOutsideChild.Type) -> () - // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(method) (@thick ResilientOutsideChild.Type) -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super33GrandchildToResilientOutsideChildC11classMethodyyFZyycfu_ : $@convention(thin) (@thick GrandchildToResilientOutsideChild.Type) -> () // CHECK: } // end sil function '$s19partial_apply_super33GrandchildToResilientOutsideChildC11classMethodyyFZ' override class func classMethod() { doFoo(super.classMethod) } + + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super33GrandchildToResilientOutsideChildC11classMethodyyFZyycfu_ : $@convention(thin) (@thick GrandchildToResilientOutsideChild.Type) -> () + // CHECK: super_method %0 : $@thick GrandchildToResilientOutsideChild.Type, #ResilientOutsideChild.classMethod!1 : (ResilientOutsideChild.Type) -> () -> (), $@convention(method) (@thick ResilientOutsideChild.Type) -> () + // CHECK: } // end sil function '$s19partial_apply_super33GrandchildToResilientOutsideChildC11classMethodyyFZyycfu_' } class GenericChildToFixedGenericOutsideParent : GenericOutsideParent { // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super019GenericChildToFixedD13OutsideParentC6methodyyF - // CHECK: bb0([[SELF:%.*]] : @guaranteed $GenericChildToFixedGenericOutsideParent): - // CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] - // CHECK: [[CASTED_SELF_COPY:%.*]] = upcast [[SELF_COPY]] : $GenericChildToFixedGenericOutsideParent to $GenericOutsideParent - // CHECK: [[BORROWED_CASTED_SELF_COPY:%.*]] = begin_borrow [[CASTED_SELF_COPY]] - // CHECK: [[DOWNCAST_BORROWED_CASTED_SELF_COPY:%.*]] = unchecked_ref_cast [[BORROWED_CASTED_SELF_COPY]] - // CHECK: [[SUPER_METHOD:%.*]] = super_method [[DOWNCAST_BORROWED_CASTED_SELF_COPY]] : $GenericChildToFixedGenericOutsideParent, #GenericOutsideParent.method!1 : (GenericOutsideParent) -> () -> (), $@convention(method) <τ_0_0> (@guaranteed GenericOutsideParent<τ_0_0>) -> () - // CHECK: end_borrow [[BORROWED_CASTED_SELF_COPY]] - // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF_COPY]]) : $@convention(method) <τ_0_0> (@guaranteed GenericOutsideParent<τ_0_0>) -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super019GenericChildToFixedD13OutsideParentC6methodyyFyycfu_ : $@convention(thin) <τ_0_0> (@guaranteed GenericChildToFixedGenericOutsideParent<τ_0_0>) -> () // CHECK: } // end sil function '$s19partial_apply_super019GenericChildToFixedD13OutsideParentC6methodyyF' override func method() { doFoo(super.method) } + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super019GenericChildToFixedD13OutsideParentC6methodyyFyycfu_ : $@convention(thin) (@guaranteed GenericChildToFixedGenericOutsideParent) -> () + // CHECK: super_method {{%.*}} : $GenericChildToFixedGenericOutsideParent, #GenericOutsideParent.method!1 : (GenericOutsideParent) -> () -> (), $@convention(method) <τ_0_0> (@guaranteed GenericOutsideParent<τ_0_0>) -> () + // CHECK: } // end sil function '$s19partial_apply_super019GenericChildToFixedD13OutsideParentC6methodyyFyycfu_' + + // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super019GenericChildToFixedD13OutsideParentC11classMethodyyFZ - // CHECK: [[CASTED_SELF:%.*]] = upcast %0 : $@thick GenericChildToFixedGenericOutsideParent.Type to $@thick GenericOutsideParent.Type - // CHECK: [[SUPER_METHOD:%.*]] = super_method %0 : $@thick GenericChildToFixedGenericOutsideParent.Type, #GenericOutsideParent.classMethod!1 : (GenericOutsideParent.Type) -> () -> (), $@convention(method) <τ_0_0> (@thick GenericOutsideParent<τ_0_0>.Type) -> () - // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(method) <τ_0_0> (@thick GenericOutsideParent<τ_0_0>.Type) -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super019GenericChildToFixedD13OutsideParentC11classMethodyyFZyycfu_ : $@convention(thin) <τ_0_0> (@thick GenericChildToFixedGenericOutsideParent<τ_0_0>.Type) -> () // CHECK: } // end sil function '$s19partial_apply_super019GenericChildToFixedD13OutsideParentC11classMethodyyFZ' override class func classMethod() { doFoo(super.classMethod) } + + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super019GenericChildToFixedD13OutsideParentC11classMethodyyFZyycfu_ : $@convention(thin) (@thick GenericChildToFixedGenericOutsideParent.Type) -> () + // CHECK: super_method %0 : $@thick GenericChildToFixedGenericOutsideParent.Type, #GenericOutsideParent.classMethod!1 : (GenericOutsideParent.Type) -> () -> (), $@convention(method) <τ_0_0> (@thick GenericOutsideParent<τ_0_0>.Type) -> () + // CHECK: } // end sil function '$s19partial_apply_super019GenericChildToFixedD13OutsideParentC11classMethodyyFZyycfu_' } class GenericChildToResilientGenericOutsideParent : ResilientGenericOutsideParent { // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super023GenericChildToResilientD13OutsideParentC6methodyyF - // CHECK: bb0([[SELF:%.*]] : @guaranteed $GenericChildToResilientGenericOutsideParent): - // CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]] - // CHECK: [[CASTED_SELF_COPY:%.*]] = upcast [[SELF_COPY]] : $GenericChildToResilientGenericOutsideParent to $ResilientGenericOutsideParent - // CHECK: [[BORROWED_CASTED_SELF_COPY:%.*]] = begin_borrow [[CASTED_SELF_COPY]] - // CHECK: [[DOWNCAST_BORROWED_CASTED_SELF_COPY:%.*]] = unchecked_ref_cast [[BORROWED_CASTED_SELF_COPY]] - // CHECK: [[SUPER_METHOD:%.*]] = super_method [[DOWNCAST_BORROWED_CASTED_SELF_COPY]] : $GenericChildToResilientGenericOutsideParent, #ResilientGenericOutsideParent.method!1 : (ResilientGenericOutsideParent) -> () -> (), $@convention(method) <τ_0_0> (@guaranteed ResilientGenericOutsideParent<τ_0_0>) -> () - // CHECK: end_borrow [[BORROWED_CASTED_SELF_COPY]] - // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF_COPY]]) : $@convention(method) <τ_0_0> (@guaranteed ResilientGenericOutsideParent<τ_0_0>) -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super023GenericChildToResilientD13OutsideParentC6methodyyFyycfu_ : $@convention(thin) <τ_0_0> (@guaranteed GenericChildToResilientGenericOutsideParent<τ_0_0>) -> () // CHECK: } // end sil function '$s19partial_apply_super023GenericChildToResilientD13OutsideParentC6methodyyF' override func method() { doFoo(super.method) } + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super023GenericChildToResilientD13OutsideParentC6methodyyFyycfu_ : $@convention(thin) (@guaranteed GenericChildToResilientGenericOutsideParent) -> () + // CHECK: super_method %5 : $GenericChildToResilientGenericOutsideParent, #ResilientGenericOutsideParent.method!1 : (ResilientGenericOutsideParent) -> () -> (), $@convention(method) <τ_0_0> (@guaranteed ResilientGenericOutsideParent<τ_0_0>) -> () + // CHECK: } // end sil function '$s19partial_apply_super023GenericChildToResilientD13OutsideParentC6methodyyFyycfu_' + + // CHECK-LABEL: sil hidden [ossa] @$s19partial_apply_super023GenericChildToResilientD13OutsideParentC11classMethodyyFZ - // CHECK: [[CASTED_SELF:%.*]] = upcast %0 : $@thick GenericChildToResilientGenericOutsideParent.Type to $@thick ResilientGenericOutsideParent.Type - // CHECK: [[SUPER_METHOD:%.*]] = super_method %0 : $@thick GenericChildToResilientGenericOutsideParent.Type, #ResilientGenericOutsideParent.classMethod!1 : (ResilientGenericOutsideParent.Type) -> () -> (), $@convention(method) <τ_0_0> (@thick ResilientGenericOutsideParent<τ_0_0>.Type) -> () - // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(method) <τ_0_0> (@thick ResilientGenericOutsideParent<τ_0_0>.Type) -> () - // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]] - // CHECK: [[DOFOO:%.*]] = function_ref @$s19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () - // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () + // CHECK: function_ref @$s19partial_apply_super023GenericChildToResilientD13OutsideParentC11classMethodyyFZyycfu_ : $@convention(thin) <τ_0_0> (@thick GenericChildToResilientGenericOutsideParent<τ_0_0>.Type) -> () // CHECK: } // end sil function '$s19partial_apply_super023GenericChildToResilientD13OutsideParentC11classMethodyyFZ' override class func classMethod() { doFoo(super.classMethod) } + + // CHECK-LABEL: sil private [ossa] @$s19partial_apply_super023GenericChildToResilientD13OutsideParentC11classMethodyyFZyycfu_ : $@convention(thin) (@thick GenericChildToResilientGenericOutsideParent.Type) -> () + // CHECK: super_method %0 : $@thick GenericChildToResilientGenericOutsideParent.Type, #ResilientGenericOutsideParent.classMethod!1 : (ResilientGenericOutsideParent.Type) -> () -> (), $@convention(method) <τ_0_0> (@thick ResilientGenericOutsideParent<τ_0_0>.Type) -> ( + // CHECK: } // end sil function '$s19partial_apply_super023GenericChildToResilientD13OutsideParentC11classMethodyyFZyycfu_' } diff --git a/test/SILGen/partial_apply_throws.swift b/test/SILGen/partial_apply_throws.swift new file mode 100644 index 0000000000000..761ea6407bcd6 --- /dev/null +++ b/test/SILGen/partial_apply_throws.swift @@ -0,0 +1,15 @@ +// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s + +class C { + func foo() throws { } +} + +_ = C.foo + +// CHECK-LABEL: sil private [ossa] @$s20partial_apply_throwsyyKcAA1CCcfu_ : $@convention(thin) (@guaranteed C) -> @owned @callee_guaranteed () -> @error Error { + +// CHECK-LABEL: sil private [ossa] @$s20partial_apply_throwsyyKcAA1CCcfu_yyKcfu0_ : $@convention(thin) (@guaranteed C) -> @error Error { +// CHECK: [[FN:%.*]] = class_method %0 : $C, #C.foo!1 : (C) -> () throws -> (), $@convention(method) (@guaranteed C) -> @error Error +// CHECK: try_apply [[FN]](%0) +// CHECK: return +// CHECK: throw \ No newline at end of file diff --git a/test/SILOptimizer/closure_lifetime_fixup.swift b/test/SILOptimizer/closure_lifetime_fixup.swift index d852385f97873..99da3689f35c6 100644 --- a/test/SILOptimizer/closure_lifetime_fixup.swift +++ b/test/SILOptimizer/closure_lifetime_fixup.swift @@ -96,11 +96,12 @@ public func dontCrash(test: Bool, body: @escaping ((In) -> Out, In) -> } // CHECK-LABEL: sil @$s22closure_lifetime_fixup28to_stack_of_convert_function1pySvSg_tF -// CHECK: [[PA:%.*]] = partial_apply [callee_guaranteed] [on_stack] -// CHECK: [[MD:%.*]] = mark_dependence [[PA]] -// CHECK: [[CVT:%.*]] = convert_function [[MD]] +// CHECK: [[FN:%.*]] = function_ref @$s22closure_lifetime_fixup28to_stack_of_convert_function1pySvSg_tFSSSvcfu_ : $@convention(thin) (UnsafeMutableRawPointer) -> @owned String +// CHECK: [[PA:%.*]] = thin_to_thick_function [[FN]] +// CHECK: [[CVT:%.*]] = convert_function [[PA]] +// CHECK: [[CVT2:%.*]] = convert_escape_to_noescape [[CVT]] // CHECK: [[REABSTRACT:%.*]] = function_ref @$sSvSSs5Error_pIgyozo_SvSSsAA_pIegnrzo_TR -// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[REABSTRACT]]([[CVT]]) +// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[REABSTRACT]]([[CVT2]]) // CHECK: [[CF2:%.*]] = convert_function [[PA2]] // CHECK: [[MAP:%.*]] = function_ref @$sSq3mapyqd__Sgqd__xKXEKlF // CHECK: try_apply [[MAP]]({{.*}}, [[CF2]], {{.*}}) diff --git a/test/SILOptimizer/dead_partial_apply_arg.swift b/test/SILOptimizer/dead_partial_apply_arg.swift index 88ac6a07f6302..dc41ef2a5fa04 100644 --- a/test/SILOptimizer/dead_partial_apply_arg.swift +++ b/test/SILOptimizer/dead_partial_apply_arg.swift @@ -5,19 +5,23 @@ // unused metatype) to a thin_to_thick_function extension Int32 { - -// This function has an unused metatype argument. - -// CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @$ss5Int32V4testE8lessthan3lhs3rhsSbAB_ABtFZ : $@convention(method) (Int32, Int32, @thin Int32.Type) -> Bool + // This function has an unused metatype argument. public static func lessthan (lhs: Int32, rhs: Int32) -> Bool { return lhs < rhs } } // CHECK-LABEL: sil hidden @$s4test6callitSbs5Int32V_ADtcyF : $@convention(thin) () -> @owned @callee_guaranteed (Int32, Int32) -> Bool -// CHECK: [[F:%[0-9]+]] = function_ref @$ss5Int32V4testE8lessthan3lhs3rhsSbAB_ABtFZTf4nnd_n +// CHECK: [[F:%[0-9]+]] = function_ref @$s4test6callitSbs5Int32V_ADtcyFSbAD_ADtcADmcfu_SbAD_ADtcfu0_Tf4nnd_n : $@convention(thin) (Int32, Int32) -> Bool // CHECK: [[R:%[0-9]+]] = thin_to_thick_function [[F]] // CHECK: return [[R]] + +// The function gets inlined into the curry thunk, and the +// unused metatype argument deleted. + +// CHECK-LABEL: sil private @$s4test6callitSbs5Int32V_ADtcyFSbAD_ADtcADmcfu_SbAD_ADtcfu0_Tf4nnd_n : $@convention(thin) (Int32, Int32) -> Bool +// CHECK: builtin "cmp_slt_Int32"(%6 : $Builtin.Int32, %7 : $Builtin.Int32) : $Builtin.Int1 +// CHECK: return func callit() -> (Int32, Int32) -> Bool { return (Int32.lessthan) } diff --git a/test/SILOptimizer/specialize_opaque_type_archetypes.swift b/test/SILOptimizer/specialize_opaque_type_archetypes.swift index 0a189c1ed9042..c83372ea4bd78 100644 --- a/test/SILOptimizer/specialize_opaque_type_archetypes.swift +++ b/test/SILOptimizer/specialize_opaque_type_archetypes.swift @@ -412,9 +412,9 @@ func testIt(cl: (Int64) throws -> T) { // CHECK-LABEL: sil shared [noinline] @$s1A16testPartialApplyyyxAA2P4RzlFAA2PAV_Tg5 // CHECK: [[PA:%.*]] = alloc_stack $PA // CHECK: store %0 to [[PA]] : $*PA -// CHECK: [[F:%.*]] = function_ref @$s1A2PAVAA2P4A2aDP3fooy2ATQzs5Int64VFTW : -// CHECK: [[C:%.*]] = partial_apply [callee_guaranteed] [[F]]([[PA]]) -// CHECK: convert_function [[C]] : +// CHECK: [[F:%.*]] = function_ref @$s1A16testPartialApplyyyxAA2P4RzlF2ATQzs5Int64Vcxcfu_AeGcfu0_AA2PAV_TG5 : $@convention(thin) (Int64, @in_guaranteed PA) -> @out Int64 +// CHECK: [[C:%.*]] = partial_apply [callee_guaranteed] [[F]]([[PA]]) : $@convention(thin) (Int64, @in_guaranteed PA) -> @out Int64 +// CHECK: convert_function [[C]] : $@callee_guaranteed (Int64) -> @out Int64 to $@callee_guaranteed @substituted <τ_0_0> (Int64) -> (@out τ_0_0, @error Error) for @inline(never) func testPartialApply(_ t: T) { let fun = t.foo diff --git a/validation-test/compiler_crashers/28682-swift-lowering-silgenfunction-emitopenexistential.swift b/validation-test/compiler_crashers_fixed/28682-swift-lowering-silgenfunction-emitopenexistential.swift similarity index 87% rename from validation-test/compiler_crashers/28682-swift-lowering-silgenfunction-emitopenexistential.swift rename to validation-test/compiler_crashers_fixed/28682-swift-lowering-silgenfunction-emitopenexistential.swift index 1ebece10eba8f..d9387046198b1 100644 --- a/validation-test/compiler_crashers/28682-swift-lowering-silgenfunction-emitopenexistential.swift +++ b/validation-test/compiler_crashers_fixed/28682-swift-lowering-silgenfunction-emitopenexistential.swift @@ -5,7 +5,7 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: %target-swift-frontend %s -emit-ir protocol P{} extension P{ func a(){ diff --git a/validation-test/compiler_crashers/28689-swift-lowering-silgenfunction-emitopenexistential.swift b/validation-test/compiler_crashers_fixed/28689-swift-lowering-silgenfunction-emitopenexistential.swift similarity index 88% rename from validation-test/compiler_crashers/28689-swift-lowering-silgenfunction-emitopenexistential.swift rename to validation-test/compiler_crashers_fixed/28689-swift-lowering-silgenfunction-emitopenexistential.swift index 61b44bdb9d456..3b6ab8bce31d5 100644 --- a/validation-test/compiler_crashers/28689-swift-lowering-silgenfunction-emitopenexistential.swift +++ b/validation-test/compiler_crashers_fixed/28689-swift-lowering-silgenfunction-emitopenexistential.swift @@ -5,7 +5,7 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: %target-swift-frontend %s -emit-ir // non-fuzz protocol a {