Skip to content

Commit 484d676

Browse files
committed
Handle labeled singleton tuples in the setter value argument.
This can get introduced by somewhat pathological behavior in the importer combined with SILGenApply's reliance on parallel tuple destructuring. Both of these should be fixed, but this patch is much simpler. rdar://34913800
1 parent e2183cc commit 484d676

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

lib/SILGen/ArgumentSource.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,26 @@ void ArgumentSource::rewriteType(CanType newType) & {
5959
Storage.get<RValueStorage>(StoredKind).Value.rewriteType(newType);
6060
return;
6161
case Kind::Expr:
62-
Expr *expr = Storage.get<Expr*>(StoredKind);
63-
if (expr->getType()->isEqual(newType)) return;
62+
Expr *&expr = Storage.get<Expr*>(StoredKind);
63+
CanType oldType = expr->getType()->getCanonicalType();
64+
65+
// Usually nothing is required.
66+
if (oldType == newType) return;
67+
68+
// Sometimes we need to wrap the expression in a single-element tuple.
69+
// This is only necessary because we don't break down the argument list
70+
// when dealing with SILGenApply.
71+
if (auto newTuple = dyn_cast<TupleType>(newType)) {
72+
if (newTuple->getNumElements() == 1 &&
73+
newTuple.getElementType(0) == oldType) {
74+
expr = TupleExpr::create(newType->getASTContext(),
75+
SourceLoc(), expr, {}, {}, SourceLoc(),
76+
/*trailing closure*/ false,
77+
/*implicit*/ true, newType);
78+
return;
79+
}
80+
}
81+
6482
llvm_unreachable("unimplemented! hope it doesn't happen");
6583
}
6684
llvm_unreachable("bad kind");

test/SILGen/Inputs/usr/include/BridgeTestFoundation.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,7 @@ void escapeNonnullBlock(void (^_Nonnull block)(void));
8989
void noescapeBlockAlias(__attribute__((noescape)) dispatch_block_t block);
9090
void noescapeNonnullBlockAlias(__attribute__((noescape)) _Nonnull dispatch_block_t block);
9191
void escapeBlockAlias(dispatch_block_t block);
92+
93+
@interface ObjectWithSplitProperty : NSObject
94+
@property (nonatomic, setter=private_setFlagForSomething:) BOOL flagForSomething;
95+
@end

test/SILGen/objc_properties.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,11 @@ class HasLazyProperty : NSObject, HasProperty {
248248
// CHECK-LABEL: sil hidden @_T015objc_properties15HasLazyPropertyC6windowSo8NSObjectCSgvg : $@convention(method) (@guaranteed HasLazyProperty) -> @owned Optional<NSObject> {
249249
// CHECK: class_method %0 : $HasLazyProperty, #HasLazyProperty.instanceMethod!1 : (HasLazyProperty) -> () -> NSObject?
250250
// CHECK: return
251+
252+
// The way we import this setter splits the name into the parameter list,
253+
// which can cause fits for SILGenApply the way it's currently implemented.
254+
// CHECK-LABEL: sil hidden @_T015objc_properties26testPropSetWithPreposition
255+
func testPropSetWithPreposition(object: ObjectWithSplitProperty?) {
256+
// CHECK: #ObjectWithSplitProperty.flagForSomething!setter.1.foreign : (ObjectWithSplitProperty) -> (Bool) -> (), $@convention(objc_method) (ObjCBool, ObjectWithSplitProperty) -> ()
257+
object?.flagForSomething = false
258+
}

0 commit comments

Comments
 (0)