Skip to content

Commit 4531c7b

Browse files
committed
dying on assert in emitNativeToCBridgedNonoptionalValue
1 parent 3e578a8 commit 4531c7b

File tree

3 files changed

+102
-56
lines changed

3 files changed

+102
-56
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 99 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4148,6 +4148,7 @@ RValue CallEmission::applyNormalCall(SGFContext C) {
41484148
cast<FunctionType>(calleeTypeInfo.substResultType).getResult();
41494149
}
41504150

4151+
assert(callSite.hasValue());
41514152
ResultPlanPtr resultPlan = ResultPlanBuilder::computeResultPlan(
41524153
SGF, calleeTypeInfo, callSite->Loc, uncurriedContext);
41534154

@@ -6255,20 +6256,12 @@ static ManagedValue emitDynamicPartialApply(SILGenFunction &SGF,
62556256
return result;
62566257
}
62576258

6258-
RValue SILGenFunction::emitDynamicMemberRef(SILLocation loc, SILValue operand,
6259+
RValue SILGenFunction::emitDynamicMemberRef(SILLocation loc,
6260+
ManagedValue operandMV,
62596261
ConcreteDeclRef memberRef,
62606262
CanType refTy, SGFContext C) {
62616263
assert(refTy->isOptional());
62626264

6263-
if (!memberRef.getDecl()->isInstanceMember()) {
6264-
auto metatype = operand->getType().castTo<MetatypeType>();
6265-
assert(metatype->getRepresentation() == MetatypeRepresentation::Thick);
6266-
metatype = CanMetatypeType::get(metatype.getInstanceType(),
6267-
MetatypeRepresentation::ObjC);
6268-
operand = B.createThickToObjCMetatype(
6269-
loc, operand, SILType::getPrimitiveObjectType(metatype));
6270-
}
6271-
62726265
// Create the continuation block.
62736266
SILBasicBlock *contBB = createBasicBlock();
62746267

@@ -6280,74 +6273,127 @@ RValue SILGenFunction::emitDynamicMemberRef(SILLocation loc, SILValue operand,
62806273

62816274
const TypeLowering &optTL = getTypeLowering(refTy);
62826275
auto loweredOptTy = optTL.getLoweredType();
6283-
62846276
SILValue optTemp = emitTemporaryAllocation(loc, loweredOptTy);
62856277

6286-
// Create the branch.
6278+
// Prepare for the has-member case
6279+
auto memberDecl = memberRef.getDecl();
6280+
62876281
FuncDecl *memberFunc;
6288-
if (auto *VD = dyn_cast<VarDecl>(memberRef.getDecl())) {
6282+
if (auto *VD = dyn_cast<VarDecl>(memberDecl)) {
62896283
memberFunc = VD->getOpaqueAccessor(AccessorKind::Get);
62906284
} else {
6291-
memberFunc = cast<FuncDecl>(memberRef.getDecl());
6285+
memberFunc = cast<FuncDecl>(memberDecl);
62926286
}
6293-
auto member = SILDeclRef(memberFunc, SILDeclRef::Kind::Func)
6294-
.asForeign();
6287+
auto member = SILDeclRef(memberFunc, SILDeclRef::Kind::Func).asForeign();
6288+
auto operand = operandMV.getValue();
6289+
6290+
// adjust operand
6291+
if (!memberDecl->isInstanceMember()) {
6292+
auto metatype = operand->getType().castTo<MetatypeType>();
6293+
assert(metatype->getRepresentation() == MetatypeRepresentation::Thick);
6294+
metatype = CanMetatypeType::get(metatype.getInstanceType(),
6295+
MetatypeRepresentation::ObjC);
6296+
operand = B.createThickToObjCMetatype(
6297+
loc, operand, SILType::getPrimitiveObjectType(metatype));
6298+
operandMV = ManagedValue::forUnmanaged(operand);
6299+
}
6300+
6301+
// Create the branch to test whether the member exists.
62956302
B.createDynamicMethodBranch(loc, operand, member, hasMemberBB, noMemberBB);
62966303

62976304
// Create the has-member branch.
62986305
{
62996306
B.emitBlock(hasMemberBB);
63006307

63016308
FullExpr hasMemberScope(Cleanups, CleanupLocation(loc));
6309+
FormalEvaluationScope writebackScope(*this);
63026310

6303-
// The argument to the has-member block is the uncurried method.
6304-
const CanType valueTy = refTy.getOptionalObjectType();
6305-
CanFunctionType methodTy;
6311+
// -------------
63066312

6307-
// For a computed variable, we want the getter.
6308-
if (isa<VarDecl>(memberRef.getDecl())) {
6309-
// FIXME: Verify ExtInfo state is correct, not working by accident.
6310-
CanFunctionType::ExtInfo info;
6311-
methodTy = CanFunctionType::get({}, valueTy, info);
6312-
} else {
6313-
methodTy = cast<FunctionType>(valueTy);
6314-
}
6313+
// If the member exists, then we need to wrap that function-value in an
6314+
// optional. To get the function-value, we partially-apply `self` to the
6315+
// method.
63156316

6316-
// Build a partially-applied foreign formal type.
6317-
// TODO: instead of building this and then potentially converting, we
6318-
// should just build a single thunk.
6319-
auto foreignMethodTy =
6320-
getPartialApplyOfDynamicMethodFormalType(SGM, member, memberRef);
6317+
CanType protocolSelfType = operand->getType().getASTType();
6318+
Callee callee = Callee::forWitnessMethod(*this, protocolSelfType, member,
6319+
memberRef.getSubstitutions(), loc);
63216320

6322-
// FIXME: Verify ExtInfo state is correct, not working by accident.
6323-
CanFunctionType::ExtInfo info;
6324-
FunctionType::Param arg(operand->getType().getASTType());
6325-
auto memberFnTy = CanFunctionType::get({arg}, methodTy, info);
6321+
CallEmission emission(*this, std::move(callee), std::move(writebackScope));
63266322

6327-
auto loweredMethodTy = getDynamicMethodLoweredType(SGM.M, member,
6328-
memberFnTy);
6329-
SILValue memberArg =
6330-
hasMemberBB->createPhiArgument(loweredMethodTy, OwnershipKind::Owned);
6323+
CanType operandTy = operand->getType().getASTType();
6324+
FunctionType::Param selfArg(operandTy);
6325+
6326+
// emission.addSelfParam(loc,
6327+
// ArgumentSource(loc, RValue(*this, loc, operandTy, operandMV)), selfArg);
6328+
6329+
PreparedArguments preparedArgs;
6330+
preparedArgs.emplace({selfArg});
6331+
// SmallVector<AnyFunctionType::Param> params;
6332+
// PreparedArguments preparedArgs(params);
6333+
preparedArgs.addArbitrary(ArgumentSource(loc, RValue(*this, loc, operandTy, operandMV)));
6334+
6335+
emission.addCallSite(CallSite(loc, std::move(preparedArgs)));
6336+
6337+
RValue resultRV = emission.apply();
6338+
6339+
6340+
// if ()
63316341

6332-
// Create the result value.
6333-
Scope applyScope(Cleanups, CleanupLocation(loc));
6334-
ManagedValue result = emitDynamicPartialApply(
6335-
*this, loc, memberArg, operand, foreignMethodTy, methodTy);
63366342

6337-
RValue resultRV;
6338-
if (isa<VarDecl>(memberRef.getDecl())) {
6339-
resultRV =
6340-
emitMonomorphicApply(loc, result, {}, foreignMethodTy.getResult(),
6341-
valueTy, ApplyOptions(), None, None);
6342-
} else {
6343-
resultRV = RValue(*this, loc, valueTy, result);
6344-
}
6343+
6344+
6345+
6346+
6347+
// -------------
6348+
6349+
// The argument to the has-member block is the uncurried method.
6350+
// const CanType valueTy = refTy.getOptionalObjectType();
6351+
// CanFunctionType methodTy;
6352+
//
6353+
// // For a computed variable, we want the getter.
6354+
// if (isa<VarDecl>(memberRef.getDecl())) {
6355+
// // FIXME: Verify ExtInfo state is correct, not working by accident.
6356+
// CanFunctionType::ExtInfo info;
6357+
// methodTy = CanFunctionType::get({}, valueTy, info);
6358+
// } else {
6359+
// methodTy = cast<FunctionType>(valueTy);
6360+
// }
6361+
//
6362+
// // Build a partially-applied foreign formal type.
6363+
// // TODO: instead of building this and then potentially converting, we
6364+
// // should just build a single thunk.
6365+
// auto foreignMethodTy =
6366+
// getPartialApplyOfDynamicMethodFormalType(SGM, member, memberRef);
6367+
//
6368+
// // FIXME: Verify ExtInfo state is correct, not working by accident.
6369+
// CanFunctionType::ExtInfo info;
6370+
// FunctionType::Param arg(operand->getType().getASTType());
6371+
// auto memberFnTy = CanFunctionType::get({arg}, methodTy, info);
6372+
//
6373+
// auto loweredMethodTy = getDynamicMethodLoweredType(SGM.M, member,
6374+
// memberFnTy);
6375+
// SILValue memberArg =
6376+
// hasMemberBB->createPhiArgument(loweredMethodTy, OwnershipKind::Owned);
6377+
//
6378+
// // Create the result value.
6379+
// Scope applyScope(Cleanups, CleanupLocation(loc));
6380+
// ManagedValue result = emitDynamicPartialApply(
6381+
// *this, loc, memberArg, operand, foreignMethodTy, methodTy);
6382+
//
6383+
// RValue resultRV;
6384+
// if (isa<VarDecl>(memberRef.getDecl())) {
6385+
// resultRV =
6386+
// emitMonomorphicApply(loc, result, {}, foreignMethodTy.getResult(),
6387+
// valueTy, ApplyOptions(), None, None);
6388+
// } else {
6389+
// resultRV = RValue(*this, loc, valueTy, result);
6390+
// }
63456391

63466392
// Package up the result in an optional.
63476393
emitInjectOptionalValueInto(loc, {loc, std::move(resultRV)}, optTemp,
63486394
optTL);
63496395

6350-
applyScope.pop();
6396+
// applyScope.pop();
63516397
// Branch to the continuation block.
63526398
B.createBranch(loc, contBB);
63536399
}

lib/SILGen/SILGenExpr.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2274,7 +2274,7 @@ RValue RValueEmitter::visitDynamicMemberRefExpr(DynamicMemberRefExpr *E,
22742274
assert(!E->isImplicitlyThrows() && "an distributed-actor-isolated @objc member?");
22752275

22762276
// Emit the operand (the base).
2277-
SILValue Operand = SGF.emitRValueAsSingleValue(E->getBase()).getValue();
2277+
ManagedValue Operand = SGF.emitRValueAsSingleValue(E->getBase());
22782278

22792279
// Emit the member reference.
22802280
return SGF.emitDynamicMemberRef(E, Operand, E->getMember(),
@@ -2930,7 +2930,7 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM,
29302930

29312931
if (isa<VarDecl>(property)) {
29322932
resultRValue =
2933-
subSGF.emitDynamicMemberRef(loc, baseSubstValue.getValue(), declRef,
2933+
subSGF.emitDynamicMemberRef(loc, baseSubstValue, declRef,
29342934
propertyType, SGFContext());
29352935
} else {
29362936
assert(isa<SubscriptDecl>(property));

lib/SILGen/SILGenFunction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1758,7 +1758,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
17581758
bool isSuppressed);
17591759

17601760
/// Emit a dynamic member reference.
1761-
RValue emitDynamicMemberRef(SILLocation loc, SILValue operand,
1761+
RValue emitDynamicMemberRef(SILLocation loc, ManagedValue operand,
17621762
ConcreteDeclRef memberRef, CanType refTy,
17631763
SGFContext C);
17641764

0 commit comments

Comments
 (0)