Skip to content

Commit 54b0d9f

Browse files
author
Joe Shajrawi
authored
Merge pull request #8291 from shajrawi/optional_cast
Optional cast of opaque values
2 parents 846f698 + 9790333 commit 54b0d9f

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3334,8 +3334,9 @@ RValue RValueEmitter::visitOptionalEvaluationExpr(OptionalEvaluationExpr *E,
33343334

33353335
// Form the optional using address operations if the type is address-only or
33363336
// if we already have an address to use.
3337-
bool isByAddress = usingProvidedContext || optTL.isAddressOnly();
3338-
3337+
bool isByAddress = ((usingProvidedContext || optTL.isAddressOnly()) &&
3338+
SGF.silConv.useLoweredAddresses());
3339+
33393340
std::unique_ptr<TemporaryInitialization> optTemp;
33403341
if (!usingProvidedContext && isByAddress) {
33413342
// Allocate the temporary for the Optional<T> if we didn't get one from the
@@ -3357,7 +3358,7 @@ RValue RValueEmitter::visitOptionalEvaluationExpr(OptionalEvaluationExpr *E,
33573358
RestoreOptionalFailureDest restoreFailureDest(SGF,
33583359
JumpDest(failureBB, SGF.Cleanups.getCleanupsDepth(), E));
33593360

3360-
SILValue NormalArgument;
3361+
SILValue NormalArgument = nullptr;
33613362
if (emitOptimizedOptionalEvaluation(E, NormalArgument, optInit, *this)) {
33623363
// Already emitted code for this.
33633364
} else if (isByAddress) {
@@ -3383,7 +3384,7 @@ RValue RValueEmitter::visitOptionalEvaluationExpr(OptionalEvaluationExpr *E,
33833384
failureBB->eraseFromParent();
33843385

33853386
// The value we provide is the one we've already got.
3386-
if (!isByAddress)
3387+
if (!isByAddress && NormalArgument)
33873388
return RValue(SGF, E,
33883389
SGF.emitManagedRValueWithCleanup(NormalArgument, optTL));
33893390

test/SILGen/opaque_values_silgen.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,34 @@ func s360________guardEnum<T>(_ e: IndirectEnum<T>) {
710710
}
711711
}
712712

713+
// Tests contextual init() of opaque value types
714+
// ---
715+
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s370_____optToOptCastxSgSQyxGlF : $@convention(thin) <T> (@in Optional<T>) -> @out Optional<T> {
716+
// CHECK: bb0([[ARG:%.*]] : $Optional<T>):
717+
// CHECK: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
718+
// CHECK: [[COPY__ARG:%.*]] = copy_value [[BORROWED_ARG]]
719+
// CHECK: end_borrow [[BORROWED_ARG]] from [[ARG]] : $Optional<T>, $Optional<T>
720+
// CHECK: destroy_value [[ARG]]
721+
// CHECK: return [[COPY__ARG]] : $Optional<T>
722+
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s370_____optToOptCastxSgSQyxGlF'
723+
func s370_____optToOptCast<T>(_ x : T!) -> T? {
724+
return x
725+
}
726+
727+
// Tests casting optional opaques to optional opaques
728+
// ---
729+
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s380___contextualInitySiSgF : $@convention(thin) (Optional<Int>) -> () {
730+
// CHECK: bb0([[ARG:%.*]] : $Optional<Int>):
731+
// CHECK: [[ALLOC_OF_BOX:%.*]] = alloc_box ${ var Optional<Int> }, var
732+
// CHECK: [[PROJ_BOX:%.*]] = project_box [[ALLOC_OF_BOX]]
733+
// CHECK: store [[ARG]] to [trivial] [[PROJ_BOX]] : $*Optional<Int>
734+
// CHECK: destroy_value [[ALLOC_OF_BOX]]
735+
// CHECK: return %{{.*}} : $()
736+
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s380___contextualInitySiSgF'
737+
func s380___contextualInit(_ a : Int?) {
738+
var x: Int! = a
739+
}
740+
713741
// Tests conditional value casts and correspondingly generated reabstraction thunk, with <T> types
714742
// ---
715743
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s999_____condTFromAnyyyp_xtlF : $@convention(thin) <T> (@in Any, @in T) -> () {

0 commit comments

Comments
 (0)