// RUN: %target-swift-emit-silgen -Xllvm -sil-print-types -module-name constrained_extensions -primary-file %s | %FileCheck %s // RUN: %target-swift-emit-sil -Xllvm -sil-print-types -module-name constrained_extensions -O -primary-file %s > /dev/null // RUN: %target-swift-emit-ir -module-name constrained_extensions -primary-file %s > /dev/null extension Array where Element == Int { // CHECK-LABEL: sil [ossa] @$sSa22constrained_extensionsSiRszlE1xSaySiGyt_tcfC : $@convention(method) (@thin Array.Type) -> @owned Array public init(x: ()) { self.init() } // CHECK-LABEL: sil [ossa] @$sSa22constrained_extensionsSiRszlE16instancePropertySivg : $@convention(method) (@guaranteed Array) -> Int // CHECK-LABEL: sil [ossa] @$sSa22constrained_extensionsSiRszlE16instancePropertySivs : $@convention(method) (Int, @inout Array) -> () // CHECK-LABEL: sil [transparent] [serialized] [ossa] @$sSa22constrained_extensionsSiRszlE16instancePropertySivM : $@yield_once @convention(method) (@inout Array) -> @yields @inout Int public var instanceProperty: Element { get { return self[0] } set { self[0] = newValue } } // CHECK-LABEL: sil [ossa] @$sSa22constrained_extensionsSiRszlE14instanceMethodSiyF : $@convention(method) (@guaranteed Array) -> Int public func instanceMethod() -> Element { return instanceProperty } // CHECK-LABEL: sil [ossa] @$sSa22constrained_extensionsSiRszlE14instanceMethod1eS2i_tF : $@convention(method) (Int, @guaranteed Array) -> Int public func instanceMethod(e: Element) -> Element { return e } // CHECK-LABEL: sil [ossa] @$sSa22constrained_extensionsSiRszlE14staticPropertySivgZ : $@convention(method) (@thin Array.Type) -> Int public static var staticProperty: Element { return Array(x: ()).instanceProperty } // CHECK-LABEL: sil [ossa] @$sSa22constrained_extensionsSiRszlE12staticMethodSiyFZ : $@convention(method) (@thin Array.Type) -> Int public static func staticMethod() -> Element { return staticProperty } // CHECK-LABEL: sil non_abi [serialized] [ossa] @$sSa22constrained_extensionsSiRszlE12staticMethod1eS2iSg_tFZfA_ : $@convention(thin) () -> Optional // CHECK-LABEL: sil [ossa] @$sSa22constrained_extensionsSiRszlE12staticMethod1eS2iSg_tFZ : $@convention(method) (Optional, @thin Array.Type) -> Int public static func staticMethod(e: Element? = (nil)) -> Element { return e! } // CHECK-LABEL: sil [ossa] @$sSa22constrained_extensionsSiRszlEySiyt_tcig : $@convention(method) (@guaranteed Array) -> Int public subscript(i: ()) -> Element { return self[0] } // CHECK-LABEL: sil [ossa] @$sSa22constrained_extensionsSiRszlE21inoutAccessOfPropertyyyF : $@convention(method) (@inout Array) -> () public mutating func inoutAccessOfProperty() { func increment(x: inout Element) { x += 1 } increment(x: &instanceProperty) } } extension Dictionary where Key == Int { // CHECK-LABEL: sil [ossa] @$sSD22constrained_extensionsSiRszrlE1xSDySiq_Gyt_tcfC : $@convention(method) (@thin Dictionary.Type) -> @owned Dictionary { public init(x: ()) { self.init() } // CHECK-LABEL: sil [ossa] @$sSD22constrained_extensionsSiRszrlE16instancePropertyq_vg : $@convention(method) (@guaranteed Dictionary) -> @out Value // CHECK-LABEL: sil [ossa] @$sSD22constrained_extensionsSiRszrlE16instancePropertyq_vs : $@convention(method) (@in Value, @inout Dictionary) -> () // CHECK-LABEL: sil [transparent] [serialized] [ossa] @$sSD22constrained_extensionsSiRszrlE16instancePropertyq_vM : $@yield_once @convention(method) (@inout Dictionary) -> @yields @inout Value public var instanceProperty: Value { get { return self[0]! } set { self[0] = newValue } } // CHECK-LABEL: sil [ossa] @$sSD22constrained_extensionsSiRszrlE14instanceMethodq_yF : $@convention(method) (@guaranteed Dictionary) -> @out Value public func instanceMethod() -> Value { return instanceProperty } // CHECK-LABEL: sil [ossa] @$sSD22constrained_extensionsSiRszrlE14instanceMethod1vq_q__tF : $@convention(method) (@in_guaranteed Value, @guaranteed Dictionary) -> @out Value public func instanceMethod(v: Value) -> Value { return v } // CHECK-LABEL: sil [ossa] @$sSD22constrained_extensionsSiRszrlE12staticMethodSiyFZ : $@convention(method) (@thin Dictionary.Type) -> Int public static func staticMethod() -> Key { return staticProperty } // CHECK-LABEL: sil [ossa] @$sSD22constrained_extensionsSiRszrlE14staticPropertySivgZ : $@convention(method) (@thin Dictionary.Type) -> Int public static var staticProperty: Key { return 0 } // CHECK-LABEL: sil non_abi [serialized] [ossa] @$sSD22constrained_extensionsSiRszrlE12staticMethod1k1vq_SiSg_q_SgtFZfA_ : $@convention(thin) () -> Optional // CHECK-LABEL: sil non_abi [serialized] [ossa] @$sSD22constrained_extensionsSiRszrlE12staticMethod1k1vq_SiSg_q_SgtFZfA0_ : $@convention(thin) () -> @out Optional // CHECK-LABEL: sil [ossa] @$sSD22constrained_extensionsSiRszrlE12staticMethod1k1vq_SiSg_q_SgtFZ : $@convention(method) (Optional, @in_guaranteed Optional, @thin Dictionary.Type) -> @out Value public static func staticMethod(k: Key? = (nil), v: Value? = (nil)) -> Value { return v! } // CHECK-LABEL: sil [ossa] @$sSD22constrained_extensionsSiRszrlE17callsStaticMethodq_yFZ : $@convention(method) (@thin Dictionary.Type) -> @out Value public static func callsStaticMethod() -> Value { return staticMethod() } // CHECK-LABEL: sil [ossa] @$sSD22constrained_extensionsSiRszrlE16callsConstructorq_yFZ : $@convention(method) (@thin Dictionary.Type) -> @out Value public static func callsConstructor() -> Value { return Dictionary(x: ()).instanceMethod() } // CHECK-LABEL: sil [ossa] @$sSD22constrained_extensionsSiRszrlEyq_yt_tcig : $@convention(method) (@guaranteed Dictionary) -> @out Value public subscript(i: ()) -> Value { return self[0]! } // CHECK-LABEL: sil [ossa] @$sSD22constrained_extensionsSiRszrlE21inoutAccessOfPropertyyyF : $@convention(method) (@inout Dictionary) -> () public mutating func inoutAccessOfProperty() { func increment(x: inout Value) { } increment(x: &instanceProperty) } } public class GenericClass {} extension GenericClass where Y == () { // CHECK-LABEL: sil [ossa] @$s22constrained_extensions12GenericClassCAAytRs_rlE5valuexvg : $@convention(method) (@guaranteed GenericClass) -> @out X // CHECK-LABEL: sil [ossa] @$s22constrained_extensions12GenericClassCAAytRs_rlE5valuexvs : $@convention(method) (@in X, @guaranteed GenericClass) -> () // CHECK-LABEL: sil [transparent] [serialized] [ossa] @$s22constrained_extensions12GenericClassCAAytRs_rlE5valuexvM : $@yield_once @convention(method) (@guaranteed GenericClass) -> @yields @inout X public var value: X { get { while true {} } set {} } // CHECK-LABEL: sil [ossa] @$s22constrained_extensions12GenericClassCAAytRs_rlE5emptyytvg : $@convention(method) (@guaranteed GenericClass) -> () // CHECK-LABEL: sil [ossa] @$s22constrained_extensions12GenericClassCAAytRs_rlE5emptyytvs : $@convention(method) (@guaranteed GenericClass) -> () // CHECK-LABEL: sil [transparent] [serialized] [ossa] @$s22constrained_extensions12GenericClassCAAytRs_rlE5emptyytvM : $@yield_once @convention(method) (@guaranteed GenericClass) -> @yields @inout () public var empty: Y { get { return () } set {} } // CHECK-LABEL: sil [ossa] @$s22constrained_extensions12GenericClassCAAytRs_rlEyxyt_tcig : $@convention(method) (@guaranteed GenericClass) -> @out X // CHECK-LABEL: sil [ossa] @$s22constrained_extensions12GenericClassCAAytRs_rlEyxyt_tcis : $@convention(method) (@in X, @guaranteed GenericClass) -> () // CHECK-LABEL: sil [transparent] [serialized] [ossa] @$s22constrained_extensions12GenericClassCAAytRs_rlEyxyt_tciM : $@yield_once @convention(method) (@guaranteed GenericClass) -> @yields @inout X public subscript(_: Y) -> X { get { while true {} } set {} } // CHECK-LABEL: sil [ossa] @$s22constrained_extensions12GenericClassCAAytRs_rlEyyxcig : $@convention(method) (@in_guaranteed X, @guaranteed GenericClass) -> () // CHECK-LABEL: sil [ossa] @$s22constrained_extensions12GenericClassCAAytRs_rlEyyxcis : $@convention(method) (@in X, @guaranteed GenericClass) -> () // CHECK-LABEL: sil [transparent] [serialized] [ossa] @$s22constrained_extensions12GenericClassCAAytRs_rlEyyxciM : $@yield_once @convention(method) (@in_guaranteed X, @guaranteed GenericClass) -> @yields @inout () public subscript(_: X) -> Y { get { while true {} } set {} } } protocol VeryConstrained {} struct AnythingGoes { // CHECK-LABEL: sil hidden [transparent] [ossa] @$s22constrained_extensions12AnythingGoesV13meaningOfLifexSgvpfi : $@convention(thin) () -> @out Optional var meaningOfLife: T? = nil } extension AnythingGoes where T : VeryConstrained { // CHECK-LABEL: sil hidden [ossa] @$s22constrained_extensions12AnythingGoesVA2A15VeryConstrainedRzlE13fromExtensionACyxGyt_tcfC : $@convention(method) (@thin AnythingGoes.Type) -> @out AnythingGoes { // CHECK: [[RESULT:%.*]] = struct_element_addr {{%.*}} : $*AnythingGoes, #AnythingGoes.meaningOfLife // CHECK: [[INIT:%.*]] = function_ref @$s22constrained_extensions12AnythingGoesV13meaningOfLifexSgvpfi : $@convention(thin) <τ_0_0> () -> @out Optional<τ_0_0> // CHECK: apply [[INIT]]([[RESULT]]) : $@convention(thin) <τ_0_0> () -> @out Optional<τ_0_0> // CHECK: return init(fromExtension: ()) {} } extension Array where Element == Int { struct Nested { // CHECK-LABEL: sil hidden [transparent] [ossa] @$sSa22constrained_extensionsSiRszlE6NestedV1eSiSgvpfi : $@convention(thin) () -> Optional var e: Element? = nil // CHECK-LABEL: sil hidden [ossa] @$sSa22constrained_extensionsSiRszlE6NestedV10hasDefault1eySiSg_tFfA_ : $@convention(thin) () -> Optional // CHECK-LABEL: sil hidden [ossa] @$sSa22constrained_extensionsSiRszlE6NestedV10hasDefault1eySiSg_tF : $@convention(method) (Optional, @inout Array.Nested) -> () mutating func hasDefault(e: Element? = (nil)) { self.e = e } } } extension Array where Element == AnyObject { class NestedClass { // CHECK-LABEL: sil hidden [ossa] @$sSa22constrained_extensionsyXlRszlE11NestedClassCfd : $@convention(method) (@guaranteed Array.NestedClass) -> @owned Builtin.NativeObject // CHECK-LABEL: sil hidden [ossa] @$sSa22constrained_extensionsyXlRszlE11NestedClassCfD : $@convention(method) (@owned Array.NestedClass) -> () deinit { } // CHECK-LABEL: sil hidden [exact_self_class] [ossa] @$sSa22constrained_extensionsyXlRszlE11NestedClassCACyyXl_GycfC : $@convention(method) (@thick Array.NestedClass.Type) -> @owned Array.NestedClass // CHECK-LABEL: sil hidden [ossa] @$sSa22constrained_extensionsyXlRszlE11NestedClassCACyyXl_Gycfc : $@convention(method) (@owned Array.NestedClass) -> @owned Array.NestedClass } class DerivedClass : NestedClass { // CHECK-LABEL: sil hidden [transparent] [ossa] @$sSa22constrained_extensionsyXlRszlE12DerivedClassC1eyXlSgvpfi : $@convention(thin) () -> @owned Optional // CHECK-LABEL: sil hidden [ossa] @$sSa22constrained_extensionsyXlRszlE12DerivedClassCfE : $@convention(method) (@guaranteed Array.DerivedClass) -> () var e: Element? = nil } enum NestedEnum { case hay case grain func makeHay() -> NestedEnum { return .hay } } } func referenceNestedTypes() { _ = Array.NestedClass() _ = Array.DerivedClass() } struct S { struct X {} } // CHECK-LABEL: sil hidden [ossa] @$s22constrained_extensions1SVAASiRszlEyAC1XVySi_GSicir : $@yield_once @convention(method) (Int, S) -> @yields S.X extension S { subscript(index:Int) -> X { _read { fatalError() } } } // https://github.com/swiftlang/swift/issues/74648 protocol HasX { var x: Int { get set } } extension S: HasX where T == Int { var x: Int { get { 3 } set { } } } // CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s22constrained_extensions1SVySiGAA4HasXA2aEP1xSivMTW : $@yield_once @convention(witness_method: HasX) @substituted <τ_0_0> (@inout τ_0_0) -> @yields @inout Int for > { // CHECK: [[WITNESS_FN:%.*]] = function_ref @$s22constrained_extensions1SVAASiRszlE1xSivM : $@yield_once @convention(method) (@inout S) -> @yields @inout Int // CHECK: begin_apply [[WITNESS_FN]](%0) : $@yield_once @convention(method) (@inout S) -> @yields @inout Int // CHECK: yield // CHECK: unwind