// RUN: %empty-directory(%t) // RUN: %target-swift-frontend -target %target-swift-5.9-abi-triple -emit-module-path %t/print_synthesized_extensions.swiftmodule -emit-module-doc -emit-module-doc-path %t/print_synthesized_extensions.swiftdoc %s // RUN: %target-swift-ide-test -annotate-print -print-module -synthesize-extension -print-interface -no-empty-line-between-members -module-to-print=print_synthesized_extensions -I %t -source-filename=%s -target=%target-swift-5.9-abi-triple > %t.syn.txt // RUN: %FileCheck %s -check-prefix=CHECK1 < %t.syn.txt // RUN: %FileCheck %s -check-prefix=CHECK2 < %t.syn.txt // RUN: %FileCheck %s -check-prefix=CHECK3 < %t.syn.txt // RUN: %FileCheck %s -check-prefix=CHECK4 < %t.syn.txt // RUN: %FileCheck %s -check-prefix=CHECK5 < %t.syn.txt // RUN: %FileCheck %s -check-prefix=CHECK6 < %t.syn.txt // RUN: %FileCheck %s -check-prefix=CHECK7 < %t.syn.txt // RUN: %FileCheck %s -check-prefix=CHECK8 < %t.syn.txt // RUN: %FileCheck %s -check-prefix=CHECK9 < %t.syn.txt // RUN: %FileCheck %s -check-prefix=CHECK10 < %t.syn.txt // RUN: %FileCheck %s -check-prefix=CHECK11 < %t.syn.txt // RUN: %FileCheck %s -check-prefix=CHECK12 < %t.syn.txt // RUN: %FileCheck %s -check-prefix=CHECK13 < %t.syn.txt // RUN: %FileCheck %s -check-prefix=CHECK14 < %t.syn.txt // RUN: %FileCheck %s -check-prefix=CHECK15 < %t.syn.txt // RUN: %FileCheck %s -check-prefix=CHECK16 < %t.syn.txt // RUN: %FileCheck %s -check-prefix=CHECK17 < %t.syn.txt public protocol P1 { associatedtype T1 associatedtype T2 func f1(t : T1) -> T1 func f2(t : T2) -> T2 } public extension P1 where T1 == Int { func p1IntFunc(i : Int) -> Int {return 0} } public extension P1 where T1 : P3 { func p3Func(i : Int) -> Int {return 0} } public protocol P2 { associatedtype P2T1 } public extension P2 where P2T1 : P2{ public func p2member() {} } public protocol P3 {} public extension P1 where T1 : P2 { public func ef1(t : T1) {} public func ef2(t : T2) {} } public extension P1 where T1 == P3, T2 : P3 { public func ef3(t : T1) {} public func ef4(t : T1) {} } public extension P1 where T2 : P3 { public func ef5(t : T2) {} } public struct S2 {} public struct S1 : P1, P2 { public typealias T1 = T public typealias T2 = S2 public typealias P2T1 = T public func f1(t : T1) -> T1 { return t } public func f2(t : T2) -> T2 { return t } } public struct S3 : P1 { public typealias T1 = (T, T) public typealias T2 = (T, T) public func f1(t : T1) -> T1 { return t } public func f2(t : T2) -> T2 { return t } } public struct S4 : P1 { public typealias T1 = Int public typealias T2 = Int public func f1(t : T1) -> T1 { return t } public func f2(t : T2) -> T2 { return t } } public struct S5 : P3 {} public struct S6 : P1 { public typealias T1 = S5 public typealias T2 = S5 public func f1(t : T1) -> T1 { return t } public func f2(t : T2) -> T2 { return t } } public extension S6 { public func f3() {} } public struct S7 { public struct S8 : P1 { public typealias T1 = S5 public typealias T2 = S5 public func f1(t : T1) -> T1 { return t } public func f2(t : T2) -> T2 { return t } } } public extension P1 where T1 == S9 { public func S9IntFunc() {} } public struct S9 : P3 {} public struct S10 : P1 { public typealias T1 = S9 public typealias T2 = S9 public func f1(t : T1) -> T1 { return t } public func f2(t : T2) -> T2 { return t } } public protocol P4 {} /// Extension on P4Func1 public extension P4 { func P4Func1() {} } /// Extension on P4Func2 public extension P4 { func P4Func2() {} } public struct S11 : P4 {} public extension S6 { public func fromActualExtension() {} } public protocol P5 { associatedtype T1 /// This is picked func foo1() } public extension P5 { /// This is not picked public func foo1() {} } public extension P5 where T1 == Int { /// This is picked public func foo2() {} } public extension P5 { /// This is not picked public func foo2() {} } public extension P5 { /// This is not picked public func foo3() {} } public extension P5 where T1 : Comparable{ /// This is picked public func foo3() {} } public extension P5 where T1 : Comparable { /// This is picked public func foo4() {} } public extension P5 where T1 : AnyObject { /// This should not crash public func foo5() {} } public extension P5 { /// This is not picked public func foo4() {} } public struct S12 : P5{ public typealias T1 = Int public func foo1() {} } public protocol P6 { func foo1() func foo2() } public extension P6 { public func foo1() {} } public protocol P7 { associatedtype T1 func f1(t: T1) } public extension P7 { public func nomergeFunc(t: T1) -> T1 { return t } public func f1(t: T1) -> T1 { return t } } public struct S13 {} extension S13 : P5 { public typealias T1 = Int public func foo1() {} } // CHECK1: extension S1 where T : print_synthesized_extensions.P2 { // CHECK1-NEXT: public func p2member() // CHECK1-NEXT: public func ef1(t: T) // CHECK1-NEXT: public func ef2(t: print_synthesized_extensions.S2) // CHECK1-NEXT: } // CHECK2: extension S1 where T : print_synthesized_extensions.P3 { // CHECK2-NEXT: public func p3Func(i: Int) -> Int // CHECK2-NEXT: } // CHECK3: extension S1 where T == Int { // CHECK3-NEXT: public func p1IntFunc(i: Int) -> Int // CHECK3-NEXT: } // CHECK4: extension S1 where T == print_synthesized_extensions.S9<Int> { // CHECK4-NEXT: public func S9IntFunc() // CHECK4-NEXT: } // CHECK5: public struct S10 : print_synthesized_extensions.P1 { // CHECK5-NEXT: public typealias T1 = print_synthesized_extensions.S9<Int> // CHECK5-NEXT: public typealias T2 = print_synthesized_extensions.S9<Int> // CHECK5-NEXT: public func f1(t: print_synthesized_extensions.S10.T1) -> print_synthesized_extensions.S10.T1 // CHECK5-NEXT: public func f2(t: print_synthesized_extensions.S10.T2) -> print_synthesized_extensions.S10.T2 // CHECK5-NEXT: public func p3Func(i: Int) -> Int // CHECK5-NEXT: public func ef5(t: print_synthesized_extensions.S9<Int>) // CHECK5-NEXT: public func S9IntFunc() // CHECK5-NEXT: } // CHECK6: /// Extension on P4Func1 // CHECK6-NEXT: extension S11 { // CHECK6-NEXT: public func P4Func1() // CHECK6-NEXT: } // CHECK7: /// Extension on P4Func2 // CHECK7-NEXT: extension S11 { // CHECK7-NEXT: public func P4Func2() // CHECK7-NEXT: } // CHECK8: public struct S4<T> : print_synthesized_extensions.P1 { // CHECK8-NEXT: public typealias T1 = Int // CHECK8-NEXT: public typealias T2 = Int // CHECK8-NEXT: public func f1(t: print_synthesized_extensions.S4<T>.T1) -> print_synthesized_extensions.S4<T>.T1 // CHECK8-NEXT: public func f2(t: print_synthesized_extensions.S4<T>.T2) -> print_synthesized_extensions.S4<T>.T2 // CHECK8-NEXT: public func p1IntFunc(i: Int) -> Int // CHECK8-NEXT: } // CHECK9: public struct S6<T> : print_synthesized_extensions.P1 { // CHECK9-NEXT: public typealias T1 = print_synthesized_extensions.S5 // CHECK9-NEXT: public typealias T2 = print_synthesized_extensions.S5 // CHECK9-NEXT: public func f1(t: print_synthesized_extensions.S6<T>.T1) -> print_synthesized_extensions.S6<T>.T1 // CHECK9-NEXT: public func f2(t: print_synthesized_extensions.S6<T>.T2) -> print_synthesized_extensions.S6<T>.T2 // CHECK9-NEXT: public func f3() // CHECK9-NEXT: public func fromActualExtension() // CHECK9-NEXT: public func p3Func(i: Int) -> Int // CHECK9-NEXT: public func ef5(t: print_synthesized_extensions.S5) // CHECK9-NEXT: } // CHECK10: extension S7.S8 { // CHECK10-NEXT: public func p3Func(i: Int) -> Int // CHECK10-NEXT: public func ef5(t: print_synthesized_extensions.S5) // CHECK10-NEXT: } // CHECK11: public struct S12 : print_synthesized_extensions.P5 { // CHECK11-NEXT: public typealias T1 = Int // CHECK11-NEXT: /// This is picked // CHECK11-NEXT: public func foo1() // CHECK11-NEXT: /// This is picked // CHECK11-NEXT: public func foo2() // CHECK11-NEXT: /// This is picked // CHECK11-NEXT: public func foo3() // CHECK11-NEXT: /// This is picked // CHECK11-NEXT: public func foo4() // CHECK11-NEXT: } // CHECK12: public protocol P6 { // CHECK12-NEXT: func foo1() // CHECK12-NEXT: func foo2() // CHECK12-NEXT: } // CHECK13: public protocol P7 { // CHECK13-NEXT: associatedtype T1 // CHECK13-NEXT: func f1(t: Self.T1) // CHECK13-NEXT: } // CHECK13: extension P7 { // CHECK13-NEXT: public func nomergeFunc(t: Self.T1) -> Self.T1 // CHECK13-NEXT: public func f1(t: Self.T1) -> Self.T1 // CHECK13-NEXT: } // CHECK14: public struct S13 { // CHECK14-NEXT: /// This is picked // CHECK14-NEXT: public func foo2() // CHECK14-NEXT: /// This is picked // CHECK14-NEXT: public func foo3() // CHECK14-NEXT: /// This is picked // CHECK14-NEXT: public func foo4() // CHECK14-NEXT: } // rdar://76868074: Make sure we print the extensions for C. public class C {} public class D {} public class E {} extension C where T : D { public func foo() {} } public protocol P8 { associatedtype T } extension P8 where T : D { public func bar() {} } extension P8 where T : E { public func baz() {} } extension C : P8 {} // CHECK15: public class C<T> { // CHECK15-NEXT: } // CHECK15: extension C : print_synthesized_extensions.P8 { // CHECK15-NEXT: } // CHECK15: extension C where T : print_synthesized_extensions.D { // CHECK15-NEXT: public func foo() // CHECK15-NEXT: public func bar() // CHECK15-NEXT: } // CHECK15: extension C where T : print_synthesized_extensions.E { // CHECK15-NEXT: public func baz() // CHECK15-NEXT: } // CHECK15: extension P8 where Self.T : print_synthesized_extensions.D { // CHECK15-NEXT: public func bar() // CHECK15-NEXT: } // CHECK15: extension P8 where Self.T : print_synthesized_extensions.E { // CHECK15-NEXT: public func baz() // CHECK15-NEXT: } // For this class, make sure we mirror the extension P8 where T : D, but not // the extension P8 where T : E. public class F {} extension F : P8 {} // CHECK16: public class F<T> where T : print_synthesized_extensions.D { // CHECK16-NEXT: public func bar() // CHECK16-NEXT: } // CHECK16-NOT: extension F where T : print_synthesized_extensions.E { // Parameter packs public protocol P14 {} extension P14 { public func foo(_: repeat each T) {} } public struct S14 {} extension S14 : P14 where repeat each T: Hashable {} // CHECK17: extension S14 { // CHECK17-NEXT: public func fooT>(_: repeat each T) where Pack{repeat each T} : Equatable // CHECK17-NEXT: }