Skip to content

Commit 1e30925

Browse files
author
Joe Shajrawi
authored
Merge pull request #8031 from shajrawi/error_opaque_mode
Add special corner case: support for Error type under opaque value mode
2 parents b4cf37b + cb197d5 commit 1e30925

File tree

6 files changed

+56
-18
lines changed

6 files changed

+56
-18
lines changed

include/swift/AST/Types.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,9 @@ class alignas(1 << TypeAlignInBits) TypeBase {
483483
/// anywhere in the type, use \c hasOpenedExistential.
484484
bool isOpenedExistential();
485485

486+
/// Determine whether the type is an opened existential type with Error inside
487+
bool isOpenedExistentialWithError();
488+
486489
/// Retrieve the set of opened existential archetypes that occur
487490
/// within this type.
488491
void getOpenedExistentials(SmallVectorImpl<ArchetypeType *> &opened);
@@ -4414,6 +4417,19 @@ inline bool TypeBase::isOpenedExistential() {
44144417
return false;
44154418
}
44164419

4420+
inline bool TypeBase::isOpenedExistentialWithError() {
4421+
if (!hasOpenedExistential())
4422+
return false;
4423+
4424+
CanType T = getCanonicalType();
4425+
if (auto archetype = dyn_cast<ArchetypeType>(T)) {
4426+
auto openedExistentialType = archetype->getOpenedExistentialType();
4427+
return (!openedExistentialType.isNull() &&
4428+
openedExistentialType->isExistentialWithError());
4429+
}
4430+
return false;
4431+
}
4432+
44174433
inline ClassDecl *TypeBase::getClassOrBoundGenericClass() {
44184434
return getCanonicalType().getClassOrBoundGenericClass();
44194435
}

include/swift/SIL/SILFunctionConventions.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,8 @@ inline bool SILModuleConventions::isIndirectSILParam(SILParameterInfo param,
353353

354354
case ParameterConvention::Indirect_In:
355355
case ParameterConvention::Indirect_In_Guaranteed:
356-
return loweredAddresses;
356+
return (loweredAddresses ||
357+
param.getType()->isOpenedExistentialWithError());
357358
case ParameterConvention::Indirect_Inout:
358359
case ParameterConvention::Indirect_InoutAliasable:
359360
return true;
@@ -365,7 +366,8 @@ inline bool SILModuleConventions::isIndirectSILResult(SILResultInfo result,
365366
bool loweredAddresses) {
366367
switch (result.getConvention()) {
367368
case ResultConvention::Indirect:
368-
return loweredAddresses;
369+
return (loweredAddresses ||
370+
result.getType()->isOpenedExistentialWithError());
369371
case ResultConvention::Owned:
370372
case ResultConvention::Unowned:
371373
case ResultConvention::UnownedInnerPointer:

lib/SIL/SILVerifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2304,7 +2304,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
23042304

23052305
CanType resultInstanceTy = OEI->getType().getSwiftRValueType();
23062306

2307-
require(OEI->getType().isAddress() || !fnConv.useLoweredAddresses(),
2307+
require(OEI->getType().isAddress(),
23082308
"open_existential_box result must be an address");
23092309

23102310
auto archetype = getOpenedArchetypeOf(resultInstanceTy);

lib/SIL/TypeLowering.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,12 +1099,6 @@ namespace {
10991099
OpaqueValueTypeLowering(SILType type)
11001100
: LeafLoadableTypeLowering(type, IsAddressOnly, IsReferenceCounted) {}
11011101

1102-
// --- Same as LoadableTypeLowering.
1103-
void emitDestroyAddress(SILBuilder &B, SILLocation loc,
1104-
SILValue addr) const override {
1105-
llvm_unreachable("destroy address");
1106-
}
1107-
11081102
void emitCopyInto(SILBuilder &B, SILLocation loc,
11091103
SILValue src, SILValue dest, IsTake_t isTake,
11101104
IsInitialization_t isInit) const override {

lib/SILGen/SILGenConvert.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -836,9 +836,8 @@ SILGenFunction::emitOpenExistential(
836836
assert(existentialType.isObject());
837837
// NB: Don't forward the cleanup, because consuming a boxed value won't
838838
// consume the box reference.
839-
archetypeMV = ManagedValue::forUnmanaged(
840-
B.createOpenExistentialBox(loc, existentialValue.getValue(),
841-
loweredOpenedType));
839+
archetypeMV = ManagedValue::forUnmanaged(B.createOpenExistentialBox(
840+
loc, existentialValue.getValue(), loweredOpenedType.getAddressType()));
842841
// The boxed value can't be assumed to be uniquely referenced. We can never
843842
// consume it.
844843
// TODO: We could use isUniquelyReferenced to shorten the duration of

test/SILGen/opaque_values_silgen.swift

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -336,11 +336,15 @@ func s210______compErasure(_ x: Foo & Error) -> Error {
336336
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s220_____openExistBoxSSs5Error_pF : $@convention(thin) (@owned Error) -> @owned String {
337337
// CHECK: bb0([[ARG:%.*]] : $Error):
338338
// CHECK: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
339-
// CHECK: [[OPAQUE_ARG:%.*]] = open_existential_box [[BORROWED_ARG]] : $Error to $@opened({{.*}}) Error
340-
// CHECK: [[RET_STRING:%.*]] = apply{{.*}}<@opened({{.*}}) Error>([[OPAQUE_ARG]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : Error> (@in_guaranteed τ_0_0) -> @owned String
339+
// CHECK: [[OPAQUE_ARG:%.*]] = open_existential_box [[BORROWED_ARG]] : $Error to $*@opened({{.*}}) Error
340+
// CHECK: [[ALLOC_OPEN:%.*]] = alloc_stack $@opened({{.*}}) Error
341+
// CHECK: copy_addr [[OPAQUE_ARG]] to [initialization] [[ALLOC_OPEN]] : $*@opened({{.*}}) Error
342+
// CHECK: [[LOAD_ALLOC:%.*]] = load [take] [[ALLOC_OPEN]]
343+
// CHECK: destroy_value [[LOAD_ALLOC]]
344+
// CHECK: dealloc_stack [[ALLOC_OPEN]]
341345
// CHECK: end_borrow [[BORROWED_ARG]] from [[ARG]]
342346
// CHECK: destroy_value [[ARG]] : $Error
343-
// CHECK: return [[RET_STRING]] : $String
347+
// CHECK: return {{.*}} : $String
344348
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s220_____openExistBoxSSs5Error_pF'
345349
func s220_____openExistBox(_ x: Error) -> String {
346350
return x._domain
@@ -365,9 +369,32 @@ func s230______condFromAny(_ x: Any) {
365369
}
366370
}
367371

372+
// Tests LValue of error types / existential boxes
373+
// ---
374+
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s240_____propOfLValueSSs5Error_pF : $@convention(thin) (@owned Error) -> @owned String {
375+
// CHECK: bb0([[ARG:%.*]] : $Error):
376+
// CHECK: [[ALLOC_OF_BOX:%.*]] = alloc_box ${ var Error }
377+
// CHECK: [[PROJ_BOX:%.*]] = project_box [[ALLOC_OF_BOX]]
378+
// CHECK: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
379+
// CHECK: [[COPY_ARG:%.*]] = copy_value [[BORROWED_ARG]]
380+
// CHECK: store [[COPY_ARG]] to [init] [[PROJ_BOX]]
381+
// CHECK: end_borrow [[BORROWED_ARG]] from [[ARG]]
382+
// CHECK: [[LOAD_BOX:%.*]] = load [copy] [[PROJ_BOX]]
383+
// CHECK: [[OPAQUE_ARG:%.*]] = open_existential_box [[LOAD_BOX]] : $Error to $*@opened({{.*}}) Error
384+
// CHECK: [[LOAD_OPAQUE:%.*]] = load [copy] [[OPAQUE_ARG]]
385+
// CHECK: [[ALLOC_OPEN:%.*]] = alloc_stack $@opened({{.*}}) Error
386+
// CHECK: store [[LOAD_OPAQUE]] to [init] [[ALLOC_OPEN]]
387+
// CHECK: [[RET_VAL:%.*]] = apply {{.*}}<@opened({{.*}}) Error>([[ALLOC_OPEN]])
388+
// CHECK: return [[RET_VAL]] : $String
389+
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s240_____propOfLValueSSs5Error_pF'
390+
func s240_____propOfLValue(_ x: Error) -> String {
391+
var x = x
392+
return x._domain
393+
}
394+
368395
// Tests conditional value casts and correspondingly generated reabstraction thunk, with <T> types
369396
// ---
370-
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s240_____condTFromAnyyyp_xtlF : $@convention(thin) <T> (@in Any, @in T) -> () {
397+
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s250_____condTFromAnyyyp_xtlF : $@convention(thin) <T> (@in Any, @in T) -> () {
371398
// CHECK: bb0([[ARG0:%.*]] : $Any, [[ARG1:%.*]] : $T):
372399
// CHECK: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG0]]
373400
// CHECK: [[COPY__ARG:%.*]] = copy_value [[BORROWED_ARG]]
@@ -377,8 +404,8 @@ func s230______condFromAny(_ x: Any) {
377404
// CHECK: partial_apply [[THUNK_REF]]<T>([[THUNK_PARAM]])
378405
// CHECK: bb6:
379406
// CHECK: return %{{.*}} : $()
380-
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s240_____condTFromAnyyyp_xtlF'
381-
func s240_____condTFromAny<T>(_ x: Any, _ y: T) {
407+
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s250_____condTFromAnyyyp_xtlF'
408+
func s250_____condTFromAny<T>(_ x: Any, _ y: T) {
382409
if let f = x as? (Int, T) -> (Int, T) {
383410
f(42, y)
384411
}

0 commit comments

Comments
 (0)