Skip to content

Commit f27a58c

Browse files
committed
Fix property wrapper crasher
Due to insufficiently robust argument emission code, certain combinations of language features could cause a call to a property wrapper backing initalizer to have mismatched argument types, causing an assertion failure in SILGenApply. This commit moves SILGenFunction::emitApplyOfPropertyWrapperBackingInitializer() into SILGenApply so it can use CallEmission and PreparedArguments to emit the call with full generality. Fixes rdar://problem/55995892.
1 parent 1a1f731 commit f27a58c

File tree

3 files changed

+48
-40
lines changed

3 files changed

+48
-40
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5006,6 +5006,44 @@ RValue SILGenFunction::emitApplyMethod(SILLocation loc, ConcreteDeclRef declRef,
50065006
return emission.apply(C);
50075007
}
50085008

5009+
RValue SILGenFunction::emitApplyOfPropertyWrapperBackingInitializer(
5010+
SILLocation loc,
5011+
VarDecl *var,
5012+
RValue &&originalValue,
5013+
SGFContext C) {
5014+
SILDeclRef constant(var, SILDeclRef::Kind::PropertyWrapperBackingInitializer);
5015+
5016+
SubstitutionMap subs;
5017+
auto varDC = var->getInnermostDeclContext();
5018+
if (auto genericSig = varDC->getGenericSignatureOfContext()) {
5019+
subs = SubstitutionMap::get(
5020+
genericSig,
5021+
[&](SubstitutableType *type) {
5022+
if (auto gp = type->getAs<GenericTypeParamType>()) {
5023+
return F.mapTypeIntoContext(gp);
5024+
}
5025+
5026+
return Type(type);
5027+
},
5028+
LookUpConformanceInModule(varDC->getParentModule()));
5029+
}
5030+
5031+
FormalEvaluationScope writebackScope(*this);
5032+
5033+
auto callee = Callee::forDirect(*this, constant, subs, loc);
5034+
auto substFnType = callee.getSubstFormalType();
5035+
5036+
CallEmission emission(*this, std::move(callee), std::move(writebackScope));
5037+
5038+
PreparedArguments args(substFnType->getAs<AnyFunctionType>()->getParams());
5039+
args.add(loc, std::move(originalValue));
5040+
emission.addCallSite(loc, std::move(args),
5041+
substFnType->getResult()->getCanonicalType(),
5042+
/*throws=*/false);
5043+
5044+
return emission.apply(C);
5045+
}
5046+
50095047
/// Emit a literal that applies the various initializers.
50105048
RValue SILGenFunction::emitLiteral(LiteralExpr *literal, SGFContext C) {
50115049
ConcreteDeclRef builtinInit;

lib/SILGen/SILGenExpr.cpp

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2235,46 +2235,6 @@ RValue SILGenFunction::emitApplyOfStoredPropertyInitializer(
22352235
subs, {}, calleeTypeInfo, ApplyOptions::None, C);
22362236
}
22372237

2238-
RValue SILGenFunction::emitApplyOfPropertyWrapperBackingInitializer(
2239-
SILLocation loc,
2240-
VarDecl *var,
2241-
RValue &&originalValue,
2242-
SGFContext C) {
2243-
SILDeclRef constant(var, SILDeclRef::Kind::PropertyWrapperBackingInitializer);
2244-
auto fnRef = ManagedValue::forUnmanaged(emitGlobalFunctionRef(loc, constant));
2245-
auto fnType = fnRef.getType().castTo<SILFunctionType>();
2246-
2247-
SubstitutionMap subs;
2248-
auto varDC = var->getInnermostDeclContext();
2249-
if (auto genericSig = varDC->getGenericSignatureOfContext()) {
2250-
subs = SubstitutionMap::get(
2251-
genericSig,
2252-
[&](SubstitutableType *type) {
2253-
if (auto gp = type->getAs<GenericTypeParamType>()) {
2254-
return F.mapTypeIntoContext(gp);
2255-
}
2256-
2257-
return Type(type);
2258-
},
2259-
LookUpConformanceInModule(varDC->getParentModule()));
2260-
}
2261-
2262-
auto substFnType = fnType->substGenericArgs(SGM.M, subs);
2263-
2264-
CanType resultType =
2265-
F.mapTypeIntoContext(var->getPropertyWrapperBackingPropertyType())
2266-
->getCanonicalType();
2267-
AbstractionPattern origResultType(resultType);
2268-
CalleeTypeInfo calleeTypeInfo(substFnType, origResultType, resultType);
2269-
ResultPlanPtr resultPlan =
2270-
ResultPlanBuilder::computeResultPlan(*this, calleeTypeInfo, loc, C);
2271-
ArgumentScope argScope(*this, loc);
2272-
SmallVector<ManagedValue, 2> args;
2273-
std::move(originalValue).getAll(args);
2274-
return emitApply(std::move(resultPlan), std::move(argScope), loc, fnRef, subs,
2275-
args, calleeTypeInfo, ApplyOptions::None, C);
2276-
}
2277-
22782238
RValue RValueEmitter::visitDestructureTupleExpr(DestructureTupleExpr *E,
22792239
SGFContext C) {
22802240
// Emit the sub-expression tuple and destructure it into elements.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-module -o %t -enable-library-evolution %S/Inputs/property_wrapper_defs.swift
3+
// RUN: %target-swift-emit-silgen -primary-file %s -I %t -enable-library-evolution
4+
import property_wrapper_defs
5+
6+
// rdar://problem/55995892
7+
// This is a crash that occurs only with -enable-library-evolution.
8+
9+
public enum E { case a }
10+
struct M { @MyPublished private var e = E.a }

0 commit comments

Comments
 (0)