Skip to content

Commit 12caf91

Browse files
authored
Merge pull request #11277 from atrick/borrow_guaranteed
2 parents bf3c6cc + cb55eda commit 12caf91

File tree

2 files changed

+58
-6
lines changed

2 files changed

+58
-6
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2921,9 +2921,10 @@ class ArgEmitter {
29212921
return;
29222922
}
29232923

2924-
if (SGF.F.getModule().getOptions().EnableSILOwnership) {
2925-
if (param.isDirectGuaranteed() &&
2926-
value.getOwnershipKind() == ValueOwnershipKind::Owned) {
2924+
if (SGF.F.getModule().getOptions().EnableSILOwnership
2925+
&& value.getOwnershipKind() == ValueOwnershipKind::Owned) {
2926+
if (param.isDirectGuaranteed() || (!SGF.silConv.useLoweredAddresses()
2927+
&& param.isIndirectInGuaranteed())) {
29272928
value = value.borrow(SGF, loc);
29282929
Args.push_back(value);
29292930
return;

test/SILGen/opaque_ownership.swift

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -enable-sil-opaque-values -enable-sil-ownership -emit-sorted-sil -Xllvm -sil-full-demangle -emit-silgen -parse-stdlib -parse-as-library %s | %FileCheck %s
1+
// RUN: %target-swift-frontend -enable-sil-opaque-values -enable-sil-ownership -emit-sorted-sil -Xllvm -sil-full-demangle -emit-silgen -parse-stdlib -parse-as-library -module-name Swift %s | %FileCheck %s
22

33
public protocol UnkeyedDecodingContainer {
44
var isAtEnd: Builtin.Int1 { get }
@@ -10,7 +10,7 @@ public protocol Decoder {
1010

1111
// Test open_existential_value ownership
1212
// ---
13-
// CHECK-LABEL: sil @_T016opaque_ownership11takeDecoderBi1_AA0D0_p4from_tKF : $@convention(thin) (@in Decoder) -> (Builtin.Int1, @error Builtin.NativeObject) {
13+
// CHECK-LABEL: sil @_T0s11takeDecoderBi1_s0B0_p4from_tKF : $@convention(thin) (@in Decoder) -> (Builtin.Int1, @error Builtin.NativeObject) {
1414
// CHECK: bb0(%0 : @owned $Decoder):
1515
// CHECK: [[BORROW1:%.*]] = begin_borrow %0 : $Decoder
1616
// CHECK: [[OPENED:%.*]] = open_existential_value [[BORROW1]] : $Decoder to $@opened("{{.*}}") Decoder
@@ -27,8 +27,59 @@ public protocol Decoder {
2727
// CHECK: destroy_value [[RET1]] : $UnkeyedDecodingContainer
2828
// CHECK: destroy_value %0 : $Decoder
2929
// CHECK: return [[RET2]] : $Builtin.Int1
30-
// CHECK-LABEL: } // end sil function '_T016opaque_ownership11takeDecoderBi1_AA0D0_p4from_tKF'
30+
// CHECK-LABEL: } // end sil function '_T0s11takeDecoderBi1_s0B0_p4from_tKF'
3131
public func takeDecoder(from decoder: Decoder) throws -> Builtin.Int1 {
3232
let container = try decoder.unkeyedContainer()
3333
return container.isAtEnd
3434
}
35+
36+
public enum Optional<Wrapped> {
37+
case none
38+
case some(Wrapped)
39+
}
40+
41+
public protocol IP {}
42+
43+
public protocol Seq {
44+
associatedtype Iterator : IP
45+
46+
func makeIterator() -> Iterator
47+
}
48+
49+
extension Seq where Self.Iterator == Self {
50+
public func makeIterator() -> Self {
51+
return self
52+
}
53+
}
54+
55+
public struct EnumIter<Base : IP> : IP, Seq {
56+
internal var _base: Base
57+
58+
public typealias Iterator = EnumIter<Base>
59+
}
60+
61+
// Test passing a +1 RValue to @in_guaranteed.
62+
// ---
63+
// CHECK-LABEL: sil @_T0s7EnumSeqV12makeIterators0A4IterVy0D0QzGyF : $@convention(method) <Base where Base : Seq> (@in_guaranteed EnumSeq<Base>) -> @out EnumIter<Base.Iterator> {
64+
// CHECK: bb0(%0 : @guaranteed $EnumSeq<Base>):
65+
// CHECK: [[FN:%.*]] = function_ref @_T0s8EnumIterVAByxGx5_base_tcfC : $@convention(method) <τ_0_0 where τ_0_0 : IP> (@in τ_0_0, @thin EnumIter<τ_0_0>.Type) -> @out EnumIter<τ_0_0>
66+
// CHECK: [[MT:%.*]] = metatype $@thin EnumIter<Base.Iterator>.Type
67+
// CHECK: [[WT:%.*]] = witness_method $Base, #Seq.makeIterator!1 : <Self where Self : Seq> (Self) -> () -> Self.Iterator : $@convention(witness_method) <τ_0_0 where τ_0_0 : Seq> (@in_guaranteed τ_0_0) -> @out τ_0_0.Iterator
68+
// CHECK: [[FIELD:%.*]] = struct_extract %0 : $EnumSeq<Base>, #EnumSeq._base
69+
// CHECK: [[COPY:%.*]] = copy_value [[FIELD]] : $Base
70+
// CHECK: [[BORROW:%.*]] = begin_borrow [[COPY]] : $Base
71+
// CHECK: [[ITER:%.*]] = apply [[WT]]<Base>([[BORROW]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : Seq> (@in_guaranteed τ_0_0) -> @out τ_0_0.Iterator
72+
// CHECK: end_borrow [[BORROW]] from [[COPY]] : $Base, $Base
73+
// CHECK: destroy_value [[COPY]] : $Base
74+
// CHECK: [[RET:%.*]] = apply [[FN]]<Base.Iterator>([[ITER]], [[MT]]) : $@convention(method) <τ_0_0 where τ_0_0 : IP> (@in τ_0_0, @thin EnumIter<τ_0_0>.Type) -> @out EnumIter<τ_0_0>
75+
// CHECK: return [[RET]] : $EnumIter<Base.Iterator>
76+
// CHECK-LABEL: } // end sil function '_T0s7EnumSeqV12makeIterators0A4IterVy0D0QzGyF'
77+
public struct EnumSeq<Base : Seq> : Seq {
78+
public typealias Iterator = EnumIter<Base.Iterator>
79+
80+
internal var _base: Base
81+
82+
public func makeIterator() -> Iterator {
83+
return EnumIter(_base: _base.makeIterator())
84+
}
85+
}

0 commit comments

Comments
 (0)