// RUN: %target-swift-frontend -O -Xllvm -sil-inline-generics=false -Xllvm -sil-disable-pass=ObjectOutliner %s -emit-sil -sil-verify-all | %FileCheck %s // Make sure that we completely inline/devirtualize/substitute all the way down // to unknown1. // CHECK-LABEL: sil {{.*}}@main // CHECK: bb0({{.*}}): // CHECK: function_ref @unknown1 // CHECK: apply // CHECK: apply // CHECK: return struct Int32 {} @_silgen_name("unknown1") func unknown1() -> () protocol P { func doSomething(_ x : Int32) } struct X {} class B : P { func doSomething(_ x : Int32) { unknown1() } } func doSomething(_ p : P, _ x : Int32) { p.doSomething(x) } func doSomething2(_ t : T, _ x : Int32) { t.doSomething(x) } func driver() { var b2 = B() var x = Int32() doSomething(b2, x) doSomething2(b2, x) } driver() // Failure to devirtualize a protocol method // applied to an opened existential blocks implementation of // DataProtocol. public protocol ContiguousBytes { func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R } extension Array : ContiguousBytes {} extension ContiguousArray : ContiguousBytes {} @inline(never) func takesPointer(_ p: UnsafeRawBufferPointer) {} // In specialized testWithUnsafeBytes(_:), the conditional case and call to withUnsafeBytes must be eliminated. // Normally, we expect Array.withUnsafeBytes to be inlined so we would see: // [[TAKES_PTR:%.*]] = function_ref @$s30devirt_specialized_conformance12takesPointeryySWF : $@convention(thin) (UnsafeRawBufferPointer) -> () // apply [[TAKES_PTR]](%{{.*}}) : $@convention(thin) (UnsafeRawBufferPointer) -> () // But the inlining isn't consistent across builds with and without debug info. // // CHECK-LABEL: sil shared [noinline] @$s30devirt_specialized_conformance19testWithUnsafeBytesyyxlFSayypG_Tg5 : $@convention(thin) (@guaranteed Array) -> () { // CHECK: bb0 // CHECK-NOT: witness_method // CHECK-LABEL: } // end sil function '$s30devirt_specialized_conformance19testWithUnsafeBytesyyxlFSayypG_Tg5' @inline(never) func testWithUnsafeBytes(_ t: T) { if let cb = t as? ContiguousBytes { cb.withUnsafeBytes { takesPointer($0) } } } testWithUnsafeBytes([])