Merge pull request #7918 from slavapestov/silgen-apply-cleanup
SILGen: Remove SubstFormalType computation
diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp
index dbc9b5d..fefc5ec 100644
--- a/lib/SILGen/SILGenApply.cpp
+++ b/lib/SILGen/SILGenApply.cpp
@@ -32,12 +32,10 @@
using namespace Lowering;
/// Retrieve the type to use for a method found via dynamic lookup.
-static CanAnyFunctionType getDynamicMethodFormalType(SILGenModule &SGM,
- SILValue proto,
+static CanAnyFunctionType getDynamicMethodFormalType(SILValue proto,
ValueDecl *member,
- SILDeclRef methodName,
Type memberType) {
- auto &ctx = SGM.getASTContext();
+ auto &ctx = member->getASTContext();
CanType selfTy;
if (member->isInstanceMember()) {
selfTy = ctx.TheUnknownObjectType;
@@ -189,9 +187,6 @@
SILValue SelfValue;
SubstitutionList Substitutions;
CanAnyFunctionType OrigFormalInterfaceType;
- CanFunctionType SubstFormalType;
- Optional<SILLocation> SpecializeLoc;
- bool HasSubstitutions = false;
Optional<SmallVector<ManagedValue, 2>> Captures;
// The pointer back to the AST node that produced the callee.
@@ -201,28 +196,24 @@
Callee(ManagedValue indirectValue,
CanAnyFunctionType origFormalType,
- CanFunctionType substFormalType,
SILLocation L)
: kind(Kind::IndirectValue),
IndirectValue(indirectValue),
OrigFormalInterfaceType(origFormalType),
- SubstFormalType(substFormalType),
Loc(L)
{}
static CanAnyFunctionType getConstantFormalInterfaceType(SILGenFunction &gen,
- SILDeclRef fn) {
+ SILDeclRef fn) {
return gen.SGM.Types.getConstantInfo(fn.atUncurryLevel(0))
.FormalInterfaceType;
}
Callee(SILGenFunction &gen, SILDeclRef standaloneFunction,
- CanFunctionType substFormalType,
SILLocation l)
: kind(Kind::StandaloneFunction), Constant(standaloneFunction),
OrigFormalInterfaceType(getConstantFormalInterfaceType(gen,
standaloneFunction)),
- SubstFormalType(substFormalType),
Loc(l)
{
}
@@ -231,170 +222,86 @@
SILGenFunction &gen,
SILValue selfValue,
SILDeclRef methodName,
- CanFunctionType substFormalType,
SILLocation l)
: kind(methodKind), Constant(methodName), SelfValue(selfValue),
OrigFormalInterfaceType(getConstantFormalInterfaceType(gen, methodName)),
- SubstFormalType(substFormalType),
Loc(l)
{
}
- /// Build a clause that looks like 'origParamType' but uses 'selfType'
- /// in place of the underlying archetype.
- static CanType buildSubstSelfType(CanType origParamType, CanType selfType,
- ASTContext &ctx) {
- assert(!isa<LValueType>(origParamType) && "Self can't be @lvalue");
- if (auto lv = dyn_cast<InOutType>(origParamType)) {
- selfType = buildSubstSelfType(lv.getObjectType(), selfType, ctx);
- return CanInOutType::get(selfType);
- }
-
- if (auto tuple = dyn_cast<TupleType>(origParamType)) {
- assert(tuple->getNumElements() == 1);
- selfType = buildSubstSelfType(tuple.getElementType(0), selfType, ctx);
-
- auto field = tuple->getElement(0).getWithType(selfType);
- return CanType(TupleType::get(field, ctx));
- }
-
- assert(isa<MetatypeType>(origParamType) == isa<MetatypeType>(selfType));
- assert(origParamType->getRValueInstanceType()->isTypeParameter());
- assert(selfType->getRValueInstanceType()->is<ArchetypeType>());
-
- return selfType;
- }
-
CanArchetypeType getWitnessMethodSelfType() const {
- return cast<ArchetypeType>(SubstFormalType.getInput()
+ return cast<ArchetypeType>(getSubstFormalType().getInput()
->getRValueInstanceType()
->getCanonicalType());
}
CanSILFunctionType getSubstFunctionType(SILGenModule &SGM,
CanSILFunctionType origFnType) const {
- if (!HasSubstitutions) return origFnType;
-
return origFnType->substGenericArgs(SGM.M, Substitutions);
}
- /// Add the 'self' clause back to the substituted formal type of
- /// this protocol method.
- void addProtocolSelfToFormalType(SILGenModule &SGM, SILDeclRef name,
- CanType protocolSelfType) {
- // The result types of the expressions yielding protocol values
- // (reflected in SubstFormalType) reflect an implicit level of
- // function application, including some extra polymorphic
- // substitution.
- HasSubstitutions = true;
-
- auto &ctx = SGM.getASTContext();
-
- // Add the 'self' parameter back. We want it to look like a
- // substitution of the appropriate clause from the original type.
- auto selfType = OrigFormalInterfaceType.getInput();
- auto substSelfType =
- buildSubstSelfType(selfType, protocolSelfType, ctx);
-
- auto extInfo = FunctionType::ExtInfo(FunctionType::Representation::Thin,
- /*throws*/ OrigFormalInterfaceType->throws());
-
- SubstFormalType = CanFunctionType::get(substSelfType, SubstFormalType,
- extInfo);
- }
-
/// Add the 'self' type to the substituted function type of this
/// dynamic callee.
- void addDynamicCalleeSelfToFormalType(SILGenModule &SGM,
- CanAnyFunctionType substFormalType) {
+ void addDynamicCalleeSelfToFormalType(Type substFormalType) {
assert(kind == Kind::DynamicMethod);
- // Add the dynamic self type to the substituted type. Even if the dynamic
- // callee came from a generic ObjC class, when we find it on AnyObject the
- // parameters should be substituted with their upper bound types.
OrigFormalInterfaceType
- = getDynamicMethodFormalType(SGM, SelfValue,
+ = getDynamicMethodFormalType(SelfValue,
Constant.getDecl(),
- Constant, substFormalType);
+ substFormalType);
assert(!OrigFormalInterfaceType->hasTypeParameter());
-
- // Add a self clause to the substituted type.
- auto selfType = OrigFormalInterfaceType.getInput();
- SubstFormalType
- = CanFunctionType::get(selfType, SubstFormalType,
- OrigFormalInterfaceType->getExtInfo());
}
public:
static Callee forIndirect(ManagedValue indirectValue,
CanAnyFunctionType origFormalType,
- CanFunctionType substFormalType,
SILLocation l) {
- return Callee(indirectValue,
- origFormalType,
- substFormalType,
- l);
+ return Callee(indirectValue, origFormalType, l);
}
static Callee forDirect(SILGenFunction &gen, SILDeclRef c,
- CanFunctionType substFormalType,
SILLocation l) {
- return Callee(gen, c, substFormalType, l);
+ return Callee(gen, c, l);
}
static Callee forEnumElement(SILGenFunction &gen, SILDeclRef c,
- CanFunctionType substFormalType,
SILLocation l) {
assert(isa<EnumElementDecl>(c.getDecl()));
- return Callee(Kind::EnumElement, gen, SILValue(),
- c, substFormalType, l);
+ return Callee(Kind::EnumElement, gen, SILValue(), c, l);
}
static Callee forClassMethod(SILGenFunction &gen, SILValue selfValue,
SILDeclRef name,
- CanFunctionType substFormalType,
SILLocation l) {
- return Callee(Kind::ClassMethod, gen, selfValue, name,
- substFormalType, l);
+ return Callee(Kind::ClassMethod, gen, selfValue, name, l);
}
static Callee forSuperMethod(SILGenFunction &gen, SILValue selfValue,
SILDeclRef name,
- CanFunctionType substFormalType,
SILLocation l) {
while (auto *UI = dyn_cast<UpcastInst>(selfValue))
selfValue = UI->getOperand();
- return Callee(Kind::SuperMethod, gen, selfValue, name,
- substFormalType, l);
+ return Callee(Kind::SuperMethod, gen, selfValue, name, l);
}
static Callee forArchetype(SILGenFunction &gen,
SILValue optOpeningInstruction,
CanType protocolSelfType,
SILDeclRef name,
- CanFunctionType substFormalType,
SILLocation l) {
- Callee callee(Kind::WitnessMethod, gen, optOpeningInstruction, name,
- substFormalType, l);
- callee.addProtocolSelfToFormalType(gen.SGM, name, protocolSelfType);
+ Callee callee(Kind::WitnessMethod, gen, optOpeningInstruction, name, l);
return callee;
}
static Callee forDynamic(SILGenFunction &gen, SILValue proto,
- SILDeclRef name, CanFunctionType substFormalType,
+ SILDeclRef name, Type substFormalType,
SILLocation l) {
- Callee callee(Kind::DynamicMethod, gen, proto, name,
- substFormalType, l);
- callee.addDynamicCalleeSelfToFormalType(gen.SGM, substFormalType);
+ Callee callee(Kind::DynamicMethod, gen, proto, name, l);
+ callee.addDynamicCalleeSelfToFormalType(substFormalType);
return callee;
}
Callee(Callee &&) = default;
Callee &operator=(Callee &&) = default;
- void setSubstitutions(SILGenFunction &gen,
- SILLocation loc,
- SubstitutionList newSubs) {
+ void setSubstitutions(SubstitutionList newSubs) {
assert(Substitutions.empty() && "Already have substitutions?");
Substitutions = newSubs;
-
- SpecializeLoc = loc;
- HasSubstitutions = true;
}
void setCaptures(SmallVectorImpl<ManagedValue> &&captures) {
@@ -416,7 +323,13 @@
}
CanFunctionType getSubstFormalType() const {
- return SubstFormalType;
+ if (auto *gft = OrigFormalInterfaceType->getAs<GenericFunctionType>()) {
+ return cast<FunctionType>(
+ gft->substGenericArgs(getSubstitutions())
+ ->getCanonicalType());
+ }
+
+ return cast<FunctionType>(OrigFormalInterfaceType);
}
unsigned getNaturalUncurryLevel() const {
@@ -452,7 +365,7 @@
case Kind::IndirectValue:
assert(level == 0 && "can't curry indirect function");
mv = IndirectValue;
- assert(!HasSubstitutions);
+ assert(Substitutions.empty());
break;
case Kind::StandaloneFunction: {
@@ -566,8 +479,9 @@
constant = Constant.atUncurryLevel(level);
// Lower the substituted type from the AST, which should have any generic
// parameters in the original signature erased to their upper bounds.
- auto objcFormalType = SubstFormalType.withExtInfo(
- SubstFormalType->getExtInfo()
+ auto substFormalType = getSubstFormalType();
+ auto objcFormalType = substFormalType.withExtInfo(
+ substFormalType->getExtInfo()
.withSILRepresentation(SILFunctionTypeRepresentation::ObjCMethod));
auto fnType = gen.SGM.M.Types
.getUncachedSILFunctionTypeForConstant(*constant, objcFormalType);
@@ -655,7 +569,6 @@
SILGenFunction &gen;
SILLocation loc;
ArgumentSource &selfValue;
- CanFunctionType substFnType;
SILParameterInfo selfParam;
AbstractFunctionDecl *fd;
ProtocolDecl *protocol;
@@ -663,9 +576,8 @@
public:
ArchetypeCalleeBuilder(SILGenFunction &gen, SILLocation loc,
- SILDeclRef inputConstant, ArgumentSource &selfValue,
- CanFunctionType substFnType)
- : gen(gen), loc(loc), selfValue(selfValue), substFnType(substFnType),
+ SILDeclRef inputConstant, ArgumentSource &selfValue)
+ : gen(gen), loc(loc), selfValue(selfValue),
selfParam(), fd(cast<AbstractFunctionDecl>(inputConstant.getDecl())),
protocol(cast<ProtocolDecl>(fd->getDeclContext())),
constant(inputConstant.asForeign(protocol->isObjC())) {}
@@ -687,11 +599,7 @@
setSelfValueToAddress(selfLoc, address);
}
- // The protocol self is implicitly decurried.
- substFnType = cast<FunctionType>(substFnType.getResult());
-
- return Callee::forArchetype(gen, openingSite, getSelfType(), constant,
- substFnType, loc);
+ return Callee::forArchetype(gen, openingSite, getSelfType(), constant, loc);
}
private:
@@ -773,10 +681,9 @@
static Callee prepareArchetypeCallee(SILGenFunction &gen, SILLocation loc,
SILDeclRef constant,
ArgumentSource &selfValue,
- CanFunctionType substFnType,
SubstitutionList &substitutions) {
// Construct an archetype call.
- ArchetypeCalleeBuilder Builder{gen, loc, constant, selfValue, substFnType};
+ ArchetypeCalleeBuilder Builder{gen, loc, constant, selfValue};
return Builder.build();
}
@@ -863,70 +770,18 @@
visit(e);
}
- /// Get the type of the function for substitution purposes.
- ///
- /// \param otherCtorRefUsesAllocating If true, the OtherConstructorDeclRef
- /// refers to the initializing
- CanFunctionType getSubstFnType(bool otherCtorRefUsesAllocating = false) {
- // TODO: optimize this if there are no specializes in play
- auto getSiteType = [&](ApplyExpr *site, bool otherCtorRefUsesAllocating) {
- if (otherCtorRefUsesAllocating) {
- // We have a reference to an initializing constructor, but we will
- // actually be using the allocating constructor. Update the type
- // appropriately.
- // FIXME: Re-derive the type from the declaration + substitutions?
- auto ctorRef = cast<OtherConstructorDeclRefExpr>(site->getSemanticFn());
- auto fnType = ctorRef->getType()->castTo<FunctionType>();
- auto selfTy = MetatypeType::get(
- fnType->getInput()->getInOutObjectType());
- return CanFunctionType::get(selfTy->getCanonicalType(),
- fnType->getResult()->getCanonicalType(),
- fnType->getExtInfo());
- }
-
- return cast<FunctionType>(site->getFn()->getType()->getCanonicalType());
- };
-
- CanFunctionType fnType;
-
- auto addSite = [&](ApplyExpr *site, bool otherCtorRefUsesAllocating) {
- auto siteType = getSiteType(site, otherCtorRefUsesAllocating);
-
- // If this is the first call site, use its formal type directly.
- if (!fnType) {
- fnType = siteType;
- return;
- }
-
- fnType = CanFunctionType::get(siteType.getInput(), fnType,
- siteType->getExtInfo());
- };
-
- for (auto callSite : CallSites) {
- addSite(callSite, false);
- }
-
- // The self application might be a DynamicMemberRefExpr.
- if (auto selfApply = dyn_cast_or_null<ApplyExpr>(SelfApplyExpr)) {
- addSite(selfApply, otherCtorRefUsesAllocating);
- }
-
- assert(fnType && "found no call sites?");
- return fnType;
- }
-
/// Fall back to an unknown, indirect callee.
void visitExpr(Expr *e) {
ManagedValue fn = SGF.emitRValueAsSingleValue(e);
auto origType = cast<AnyFunctionType>(e->getType()->getCanonicalType());
- setCallee(Callee::forIndirect(fn, origType, getSubstFnType(), e));
+ setCallee(Callee::forIndirect(fn, origType, e));
}
void visitLoadExpr(LoadExpr *e) {
// TODO: preserve the function pointer at its original abstraction level
ManagedValue fn = SGF.emitRValueAsSingleValue(e);
auto origType = cast<AnyFunctionType>(e->getType()->getCanonicalType());
- setCallee(Callee::forIndirect(fn, origType, getSubstFnType(), e));
+ setCallee(Callee::forIndirect(fn, origType, e));
}
/// Add a call site to the curry.
@@ -1005,7 +860,6 @@
// to the +0 value in memory. We just pass in the address since
// archetypes are address-only.
- auto substFnType = getSubstFnType();
assert(!CallSites.empty());
ApplyExpr *thisCallSite = CallSites.back();
CallSites.pop_back();
@@ -1039,7 +893,7 @@
// Prepare the callee. This can modify both selfValue and subs.
Callee theCallee = prepareArchetypeCallee(SGF, e, constant, selfValue,
- substFnType, subs);
+ subs);
AssumedPlusZeroSelf = selfValue.isRValue()
&& selfValue.forceAndPeekRValue(SGF).peekIsPlusZeroRValueOrTrivial();
@@ -1048,7 +902,7 @@
// If there are substitutions, add them now.
if (!subs.empty())
- ApplyCallee->setSubstitutions(SGF, e, subs);
+ ApplyCallee->setSubstitutions(subs);
return;
}
@@ -1127,13 +981,11 @@
SILDeclRef::ConstructAtNaturalUncurryLevel,
requiresForeignEntryPoint(afd));
- setCallee(Callee::forClassMethod(SGF, selfValue,
- constant, getSubstFnType(), e));
+ setCallee(Callee::forClassMethod(SGF, selfValue, constant, e));
// If there are substitutions, add them.
if (e->getDeclRef().isSpecialized()) {
- ApplyCallee->setSubstitutions(SGF, e,
- e->getDeclRef().getSubstitutions());
+ ApplyCallee->setSubstitutions(e->getDeclRef().getSubstitutions());
}
return;
@@ -1154,29 +1006,18 @@
&& requiresForeignEntryPoint(e->getDecl()));
// Otherwise, we have a statically-dispatched call.
- CanFunctionType substFnType = getSubstFnType();
-
- auto afd = dyn_cast<AbstractFunctionDecl>(e->getDecl());
- if (afd) {
- // If there are captures, put the placeholder curry level in the formal
- // type.
- // TODO: Eliminate the need for this.
- if (SGF.SGM.M.Types.hasLoweredLocalCaptures(afd))
- substFnType = CanFunctionType::get(
- SGF.getASTContext().TheEmptyTupleType, substFnType);
- }
-
SubstitutionList subs;
if (e->getDeclRef().isSpecialized())
subs = e->getDeclRef().getSubstitutions();
// Enum case constructor references are open-coded.
if (isa<EnumElementDecl>(e->getDecl()))
- setCallee(Callee::forEnumElement(SGF, constant, substFnType, e));
+ setCallee(Callee::forEnumElement(SGF, constant, e));
else
- setCallee(Callee::forDirect(SGF, constant, substFnType, e));
+ setCallee(Callee::forDirect(SGF, constant, e));
// If the decl ref requires captures, emit the capture params.
+ auto afd = dyn_cast<AbstractFunctionDecl>(e->getDecl());
if (afd) {
// FIXME: We should be checking hasLocalCaptures() on the lowered
// captures in the constant info too, to generate more efficient
@@ -1195,7 +1036,7 @@
(!afd ||
!afd->getDeclContext()->isLocalContext() ||
afd->getCaptureInfo().hasGenericParamCaptures()))
- ApplyCallee->setSubstitutions(SGF, e, subs);
+ ApplyCallee->setSubstitutions(subs);
}
void visitAbstractClosureExpr(AbstractClosureExpr *e) {
@@ -1217,24 +1058,10 @@
if (e->getCaptureInfo().hasGenericParamCaptures())
subs = SGF.getForwardingSubstitutions();
- CanFunctionType substFnType = getSubstFnType();
-
- // FIXME: We should be checking hasLocalCaptures() on the lowered
- // captures in the constant info above, to generate more efficient
- // code for mutually recursive local functions which otherwise
- // capture no state.
-
- // If there are captures, put the placeholder curry level in the formal
- // type.
- // TODO: Eliminate the need for this.
- bool hasCaptures = SGF.SGM.M.Types.hasLoweredLocalCaptures(e);
- if (hasCaptures)
- substFnType = CanFunctionType::get(
- SGF.getASTContext().TheEmptyTupleType, substFnType);
-
- setCallee(Callee::forDirect(SGF, constant, substFnType, e));
+ setCallee(Callee::forDirect(SGF, constant, e));
// If the closure requires captures, emit them.
+ bool hasCaptures = SGF.SGM.M.Types.hasLoweredLocalCaptures(e);
if (hasCaptures) {
SmallVector<ManagedValue, 4> captures;
SGF.emitCaptures(e, e, CaptureEmission::ImmediateApplication,
@@ -1243,7 +1070,7 @@
}
// If there are substitutions, add them.
if (!subs.empty())
- ApplyCallee->setSubstitutions(SGF, e, subs);
+ ApplyCallee->setSubstitutions(subs);
}
void visitOtherConstructorDeclRefExpr(OtherConstructorDeclRefExpr *e) {
@@ -1251,12 +1078,11 @@
// constructors imported from Clang (which won't have a direct entry point)
// or to delegate to a designated initializer.
setCallee(Callee::forDirect(SGF,
- SILDeclRef(e->getDecl(), SILDeclRef::Kind::Initializer),
- getSubstFnType(), e));
+ SILDeclRef(e->getDecl(), SILDeclRef::Kind::Initializer), e));
// If there are substitutions, add them.
if (e->getDeclRef().isSpecialized())
- ApplyCallee->setSubstitutions(SGF, e, e->getDeclRef().getSubstitutions());
+ ApplyCallee->setSubstitutions(e->getDeclRef().getSubstitutions());
}
void visitDotSyntaxBaseIgnoredExpr(DotSyntaxBaseIgnoredExpr *e) {
setSideEffect(e->getLHS());
@@ -1338,16 +1164,15 @@
if (!canUseStaticDispatch(SGF, constant)) {
// ObjC super calls require dynamic dispatch.
- setCallee(Callee::forSuperMethod(SGF, super.getValue(), constant,
- getSubstFnType(), fn));
+ setCallee(Callee::forSuperMethod(SGF, super.getValue(), constant, fn));
} else {
// Native Swift super calls to final methods are direct.
- setCallee(Callee::forDirect(SGF, constant, getSubstFnType(), fn));
+ setCallee(Callee::forDirect(SGF, constant, fn));
}
// If there are any substitutions for the callee, apply them now.
if (!substitutions.empty())
- ApplyCallee->setSubstitutions(SGF, fn, substitutions);
+ ApplyCallee->setSubstitutions(substitutions);
}
/// Walk the given \c selfArg expression that produces the appropriate
@@ -1508,9 +1333,7 @@
SILDeclRef::ConstructAtNaturalUncurryLevel,
requiresForeignEntryPoint(ctorRef->getDecl()));
setCallee(Callee::forArchetype(SGF, SILValue(),
- self.getType().getSwiftRValueType(), constant,
- cast<FunctionType>(expr->getType()->getCanonicalType()),
- expr));
+ self.getType().getSwiftRValueType(), constant, expr));
} else if (getMethodDispatch(ctorRef->getDecl())
== MethodDispatch::Class) {
// Dynamic dispatch to the initializer.
@@ -1524,7 +1347,7 @@
SILDeclRef::ConstructAtBestResilienceExpansion,
SILDeclRef::ConstructAtNaturalUncurryLevel,
requiresForeignEntryPoint(ctorRef->getDecl())),
- getSubstFnType(), fn));
+ fn));
} else {
// Directly call the peer constructor.
setCallee(
@@ -1537,13 +1360,12 @@
SILDeclRef::ConstructAtBestResilienceExpansion,
SILDeclRef::ConstructAtNaturalUncurryLevel,
requiresForeignEntryPoint(ctorRef->getDecl())),
- getSubstFnType(useAllocatingCtor), fn));
+ fn));
}
// Set up the substitutions, if we have any.
if (ctorRef->getDeclRef().isSpecialized())
- ApplyCallee->setSubstitutions(SGF, fn,
- ctorRef->getDeclRef().getSubstitutions());
+ ApplyCallee->setSubstitutions(ctorRef->getDeclRef().getSubstitutions());
return true;
}
@@ -1634,8 +1456,10 @@
SILDeclRef::ConstructAtNaturalUncurryLevel,
/*isObjC=*/true);
+ auto substFormalType = dynamicMemberRef->getType()
+ ->getAnyOptionalObjectType();
setCallee(Callee::forDynamic(SGF, base.getValue(), member,
- getSubstFnType(), e));
+ substFormalType, e));
};
// When we have an open existential, open it and then emit the
@@ -4712,19 +4536,12 @@
SubstitutionList subs,
ArrayRef<ManagedValue> args,
SGFContext ctx) {
+ auto callee = Callee::forDirect(*this, SILDeclRef(fn), loc);
+ callee.setSubstitutions(subs);
+
auto origFormalType =
cast<AnyFunctionType>(fn->getInterfaceType()->getCanonicalType());
- CanFunctionType substFormalType;
- if (!subs.empty()) {
- auto genericFnType = cast<GenericFunctionType>(origFormalType);
- auto applied = genericFnType->substGenericArgs(subs);
- substFormalType = cast<FunctionType>(applied->getCanonicalType());
- } else {
- substFormalType = cast<FunctionType>(origFormalType);
- }
-
- auto callee = Callee::forDirect(*this, SILDeclRef(fn), substFormalType, loc);
- callee.setSubstitutions(*this, loc, subs);
+ auto substFormalType = callee.getSubstFormalType();
ManagedValue mv;
CanSILFunctionType substFnType;
@@ -4771,37 +4588,12 @@
SILDeclRef::ConstructAtBestResilienceExpansion,
SILDeclRef::ConstructAtNaturalUncurryLevel,
requiresForeignEntryPoint(ctor));
- SILConstantInfo initConstant = SGF.getConstantInfo(initRef);
+ auto initConstant = SGF.getConstantInfo(initRef);
+ auto subs = init.getSubstitutions();
// Scope any further writeback just within this operation.
FormalEvaluationScope writebackScope(SGF);
- // Determine the formal and substituted types.
- CanFunctionType substFormalType;
- auto subs = init.getSubstitutions();
- if (!subs.empty()) {
- auto genericFnType = cast<GenericFunctionType>(
- initConstant.FormalInterfaceType);
- auto applied = genericFnType->substGenericArgs(subs);
- substFormalType = cast<FunctionType>(applied->getCanonicalType());
- } else {
- substFormalType = cast<FunctionType>(initConstant.FormalInterfaceType);
- }
-
- // For an inheritable initializer, determine whether we'll need to adjust the
- // result type.
- bool requiresDowncast = false;
- if (ctor->isInheritable() && overriddenSelfType) {
- CanType substResultType = substFormalType;
- for (unsigned i : range(ctor->getNumParameterLists())) {
- (void)i;
- substResultType = cast<FunctionType>(substResultType).getResult();
- }
-
- if (!substResultType->isEqual(overriddenSelfType))
- requiresDowncast = true;
- }
-
// Form the metatype argument.
ManagedValue selfMetaVal;
SILType selfMetaTy;
@@ -4841,13 +4633,28 @@
RValue(SGF, loc,
selfMetaVal.getType().getSwiftRValueType(),
selfMetaVal));
- callee.emplace(prepareArchetypeCallee(SGF, loc, initRef, selfSource,
- substFormalType, subs));
+ callee.emplace(prepareArchetypeCallee(SGF, loc, initRef, selfSource, subs));
} else {
- callee.emplace(Callee::forDirect(SGF, initRef, substFormalType, loc));
+ callee.emplace(Callee::forDirect(SGF, initRef, loc));
}
if (!subs.empty())
- callee->setSubstitutions(SGF, loc, subs);
+ callee->setSubstitutions(subs);
+
+ auto substFormalType = callee->getSubstFormalType();
+
+ // For an inheritable initializer, determine whether we'll need to adjust the
+ // result type.
+ bool requiresDowncast = false;
+ if (ctor->isInheritable() && overriddenSelfType) {
+ CanType substResultType = substFormalType;
+ for (unsigned i : range(ctor->getNumParameterLists())) {
+ (void)i;
+ substResultType = cast<FunctionType>(substResultType).getResult();
+ }
+
+ if (!substResultType->isEqual(overriddenSelfType))
+ requiresDowncast = true;
+ }
// Form the call emission.
CallEmission emission(SGF, std::move(*callee), std::move(writebackScope));
@@ -5045,7 +4852,6 @@
ArgumentSource &selfValue,
bool isSuper,
bool isDirectUse,
- CanFunctionType substAccessorType,
SubstitutionList &substitutions){
auto *decl = cast<AbstractFunctionDecl>(constant.getDecl());
@@ -5055,7 +4861,7 @@
assert(!isSuper && "super call to protocol method?");
return prepareArchetypeCallee(gen, loc, constant, selfValue,
- substAccessorType, substitutions);
+ substitutions);
}
bool isClassDispatch = false;
@@ -5072,20 +4878,20 @@
// Dispatch in a struct/enum or to a final method is always direct.
if (!isClassDispatch || decl->isFinal())
- return Callee::forDirect(gen, constant, substAccessorType, loc);
+ return Callee::forDirect(gen, constant, loc);
// Otherwise, if we have a non-final class dispatch to a normal method,
// perform a dynamic dispatch.
auto self = selfValue.forceAndPeekRValue(gen).peekScalarValue();
if (!isSuper)
- return Callee::forClassMethod(gen, self, constant, substAccessorType, loc);
+ return Callee::forClassMethod(gen, self, constant, loc);
// If this is a "super." dispatch, we do a dynamic dispatch for objc methods
// or non-final native Swift methods.
if (!canUseStaticDispatch(gen, constant))
- return Callee::forSuperMethod(gen, self, constant, substAccessorType, loc);
+ return Callee::forSuperMethod(gen, self, constant, loc);
- return Callee::forDirect(gen, constant, substAccessorType, loc);
+ return Callee::forDirect(gen, constant, loc);
}
static Callee
@@ -5097,23 +4903,11 @@
bool isSuper,
bool isDirectUse)
{
- SILConstantInfo constantInfo = gen.getConstantInfo(constant);
-
- // Apply substitutions to the callee type.
- CanFunctionType substAccessorType;
- if (!substitutions.empty()) {
- auto genericFn = cast<GenericFunctionType>(constantInfo.FormalInterfaceType);
- auto substFn = genericFn->substGenericArgs(substitutions);
- substAccessorType = cast<FunctionType>(substFn->getCanonicalType());
- } else {
- substAccessorType = cast<FunctionType>(constantInfo.FormalInterfaceType);
- }
-
// Get the accessor function. The type will be a polymorphic function if
// the Self type is generic.
Callee callee = getBaseAccessorFunctionRef(gen, loc, constant, selfValue,
isSuper, isDirectUse,
- substAccessorType, substitutions);
+ substitutions);
// Collect captures if the accessor has them.
auto accessorFn = cast<AbstractFunctionDecl>(constant.getDecl());
@@ -5126,10 +4920,8 @@
}
// If there are substitutions, specialize the generic accessor.
- // FIXME: Generic subscript operator could add another layer of
- // substitutions.
if (!substitutions.empty()) {
- callee.setSubstitutions(gen, loc, substitutions);
+ callee.setSubstitutions(substitutions);
}
return callee;
}