Skip to content

DynamicSelfType fixes [5.1] #24062

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions docs/ABI/Mangling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,9 @@ types where the metadata itself has unknown layout.)
global ::= global specialization // function specialization
global ::= global 'Tm' // merged function
global ::= entity // some identifiable thing
global ::= type type generic-signature? 'T' REABSTRACT-THUNK-TYPE // reabstraction thunk helper function
global ::= from-type to-type generic-signature? 'TR' // reabstraction thunk
global ::= from-type to-type self-type generic-signature? 'Ty' // reabstraction thunk with dynamic 'Self' capture
global ::= from-type to-type generic-signature? 'Tr' // obsolete mangling for reabstraction thunk
global ::= entity generic-signature? type type* 'TK' // key path getter
global ::= entity generic-signature? type type* 'Tk' // key path setter
global ::= type generic-signature 'TH' // key path equality
Expand All @@ -204,11 +206,11 @@ types where the metadata itself has unknown layout.)
global ::= type assoc-type-list protocol 'TN' // default associated conformance witness accessor
global ::= type protocol 'Tb' // base conformance descriptor

REABSTRACT-THUNK-TYPE ::= 'R' // reabstraction thunk helper function
REABSTRACT-THUNK-TYPE ::= 'r' // reabstraction thunk
REABSTRACT-THUNK-TYPE ::= 'R' // reabstraction thunk
REABSTRACT-THUNK-TYPE ::= 'r' // reabstraction thunk (obsolete)

The types in a reabstraction thunk helper function are always non-polymorphic
``<impl-function-type>`` types.
The `from-type` and `to-type` in a reabstraction thunk helper function
are always non-polymorphic ``<impl-function-type>`` types.

::

Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/ASTMangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ class ASTMangler : public Mangler {

std::string mangleReabstractionThunkHelper(CanSILFunctionType ThunkType,
Type FromType, Type ToType,
Type SelfType,
ModuleDecl *Module);

std::string mangleKeyPathGetterThunkHelper(const AbstractStorageDecl *property,
Expand Down
1 change: 1 addition & 0 deletions include/swift/Demangling/DemangleNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ NODE(ProtocolWitnessTableAccessor)
NODE(ProtocolWitnessTablePattern)
NODE(ReabstractionThunk)
NODE(ReabstractionThunkHelper)
NODE(ReabstractionThunkHelperWithSelf)
CONTEXT_NODE(ReadAccessor)
NODE(RelatedEntityDeclName)
NODE(RetroactiveConformance)
Expand Down
12 changes: 10 additions & 2 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ std::string ASTMangler::mangleReabstractionThunkHelper(
CanSILFunctionType ThunkType,
Type FromType,
Type ToType,
Type SelfType,
ModuleDecl *Module) {
Mod = Module;
GenericSignature *GenSig = ThunkType->getGenericSignature();
Expand All @@ -353,10 +354,17 @@ std::string ASTMangler::mangleReabstractionThunkHelper(
beginMangling();
appendType(FromType);
appendType(ToType);
if (SelfType)
appendType(SelfType);

if (GenSig)
appendGenericSignature(GenSig);
// TODO: mangle ThunkType->isPseudogeneric()
appendOperator("TR");

if (SelfType)
appendOperator("Ty");
else
appendOperator("TR");

return finalize();
}

Expand Down
19 changes: 12 additions & 7 deletions lib/Demangling/Demangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2057,15 +2057,20 @@ NodePointer Demangler::demangleThunkOrSpecialization() {
return createWithChild(Node::Kind::ProtocolSelfConformanceWitness,
popNode(isEntity));
case 'R':
case 'r': {
NodePointer Thunk = createNode(c == 'R' ?
Node::Kind::ReabstractionThunkHelper :
Node::Kind::ReabstractionThunk);
case 'r':
case 'y': {
Node::Kind kind;
if (c == 'R') kind = Node::Kind::ReabstractionThunkHelper;
else if (c == 'y') kind = Node::Kind::ReabstractionThunkHelperWithSelf;
else kind = Node::Kind::ReabstractionThunk;
NodePointer Thunk = createNode(kind);
if (NodePointer GenSig = popNode(Node::Kind::DependentGenericSignature))
addChild(Thunk, GenSig);
NodePointer Ty2 = popNode(Node::Kind::Type);
Thunk = addChild(Thunk, popNode(Node::Kind::Type));
return addChild(Thunk, Ty2);
if (kind == Node::Kind::ReabstractionThunkHelperWithSelf)
addChild(Thunk, popNode(Node::Kind::Type));
addChild(Thunk, popNode(Node::Kind::Type));
addChild(Thunk, popNode(Node::Kind::Type));
return Thunk;
}
case 'g':
return demangleGenericSpecialization(Node::Kind::GenericSpecialization);
Expand Down
31 changes: 25 additions & 6 deletions lib/Demangling/NodePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ class NodePrinter {
case Node::Kind::ProtocolWitnessTablePattern:
case Node::Kind::ReabstractionThunk:
case Node::Kind::ReabstractionThunkHelper:
case Node::Kind::ReabstractionThunkHelperWithSelf:
case Node::Kind::ReadAccessor:
case Node::Kind::RelatedEntityDeclName:
case Node::Kind::RetroactiveConformance:
Expand Down Expand Up @@ -1536,22 +1537,40 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
case Node::Kind::ReabstractionThunkHelper: {
if (Options.ShortenThunk) {
Printer << "thunk for ";
print(Node->getChild(Node->getNumChildren() - 2));
print(Node->getChild(Node->getNumChildren() - 1));
return nullptr;
}
Printer << "reabstraction thunk ";
if (Node->getKind() == Node::Kind::ReabstractionThunkHelper)
Printer << "helper ";
auto generics = getFirstChildOfKind(Node, Node::Kind::DependentGenericSignature);
assert(Node->getNumChildren() == 2 + unsigned(generics != nullptr));
if (generics) {
unsigned idx = 0;
if (Node->getNumChildren() == 3) {
auto generics = Node->getChild(0);
idx = 1;
print(generics);
Printer << " ";
}
Printer << "from ";
print(Node->getChild(idx + 1));
Printer << " to ";
print(Node->getChild(idx));
return nullptr;
}
case Node::Kind::ReabstractionThunkHelperWithSelf: {
Printer << "reabstraction thunk ";
unsigned idx = 0;
if (Node->getNumChildren() == 4) {
auto generics = Node->getChild(0);
idx = 1;
print(generics);
Printer << " ";
}
Printer << "from ";
print(Node->getChild(Node->getNumChildren() - 2));
print(Node->getChild(idx + 2));
Printer << " to ";
print(Node->getChild(Node->getNumChildren() - 1));
print(Node->getChild(idx + 1));
Printer << " self ";
print(Node->getChild(idx));
return nullptr;
}
case Node::Kind::MergedFunction:
Expand Down
12 changes: 6 additions & 6 deletions lib/Demangling/OldRemangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -715,15 +715,15 @@ void Remangler::mangleBaseWitnessTableAccessor(Node *node) {
}

void Remangler::mangleReabstractionThunkHelper(Node *node) {
Buffer << "TR";
if (node->getNumChildren() == 3) Buffer << 'G';
mangleChildNodes(node); // generic signature?, type, type
Buffer << "<reabstraction-thunk-helper>";
}

void Remangler::mangleReabstractionThunkHelperWithSelf(Node *node) {
Buffer << "<reabstraction-thunk-helper-with-self>";
}

void Remangler::mangleReabstractionThunk(Node *node) {
Buffer << "Tr";
if (node->getNumChildren() == 3) Buffer << 'G';
mangleChildNodes(node); // generic signature?, type, type
Buffer << "<reabstraction-thunk>";
}

void Remangler::mangleProtocolSelfConformanceWitness(Node *node) {
Expand Down
21 changes: 7 additions & 14 deletions lib/Demangling/Remangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1856,27 +1856,20 @@ void Remangler::mangleProtocolWitnessTableAccessor(Node *node) {
}

void Remangler::mangleReabstractionThunk(Node *node) {
if (node->getNumChildren() == 3) {
mangleChildNode(node, 1); // type 1
mangleChildNode(node, 2); // type 2
mangleChildNode(node, 0); // generic signature
} else {
mangleChildNodes(node);
}
mangleChildNodesReversed(node);
Buffer << "Tr";
}

void Remangler::mangleReabstractionThunkHelper(Node *node) {
if (node->getNumChildren() == 3) {
mangleChildNode(node, 1); // type 1
mangleChildNode(node, 2); // type 2
mangleChildNode(node, 0); // generic signature
} else {
mangleChildNodes(node);
}
mangleChildNodesReversed(node);
Buffer << "TR";
}

void Remangler::mangleReabstractionThunkHelperWithSelf(Node *node) {
mangleChildNodesReversed(node);
Buffer << "Ty";
}

void Remangler::mangleReadAccessor(Node *node) {
mangleAbstractStorage(node->getFirstChild(), "r");
}
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
CanSILFunctionType thunkType,
CanSILFunctionType fromType,
CanSILFunctionType toType,
IsSerialized_t Serialized);
CanType dynamicSelfType);

/// Determine whether the given class has any instance variables that
/// need to be destroyed.
Expand Down
4 changes: 2 additions & 2 deletions lib/SILGen/SILGenBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ ManagedValue SILGenFunction::emitFuncToBlock(SILLocation loc,
auto thunk = SGM.getOrCreateReabstractionThunk(invokeTy,
loweredFuncTy,
loweredBlockTy,
F.isSerialized());
/*dynamicSelfType=*/CanType());

// Build it if necessary.
if (thunk->empty()) {
Expand Down Expand Up @@ -937,7 +937,7 @@ SILGenFunction::emitBlockToFunc(SILLocation loc,
auto thunk = SGM.getOrCreateReabstractionThunk(thunkTy,
loweredBlockTy,
loweredFuncTyWithoutNoEscape,
F.isSerialized());
/*dynamicSelfType=*/CanType());

// Build it if necessary.
if (thunk->empty()) {
Expand Down
70 changes: 44 additions & 26 deletions lib/SILGen/SILGenPoly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3041,16 +3041,23 @@ CanSILFunctionType SILGenFunction::buildThunkType(
expectedType = cast<SILFunctionType>(
substIntoThunkContext(expectedType));

bool hasDynamicSelf = false;

if (inputSubstType) {
inputSubstType = cast<AnyFunctionType>(
substIntoThunkContext(inputSubstType));
hasDynamicSelf |= inputSubstType->hasDynamicSelfType();
}

if (outputSubstType) {
outputSubstType = cast<AnyFunctionType>(
substIntoThunkContext(outputSubstType));
hasDynamicSelf |= outputSubstType->hasDynamicSelfType();
}

hasDynamicSelf |= sourceType->hasDynamicSelfType();
hasDynamicSelf |= expectedType->hasDynamicSelfType();

// If our parent function was pseudogeneric, this thunk must also be
// pseudogeneric, since we have no way to pass generic parameters.
if (genericSig)
Expand All @@ -3072,8 +3079,7 @@ CanSILFunctionType SILGenFunction::buildThunkType(

// If this thunk involves DynamicSelfType in any way, add a capture for it
// in case we need to recover metadata.
if (sourceType->hasDynamicSelfType() ||
expectedType->hasDynamicSelfType()) {
if (hasDynamicSelf) {
dynamicSelfType = F.getSelfMetadataArgument()->getType().getASTType();
if (!isa<MetatypeType>(dynamicSelfType)) {
dynamicSelfType = CanMetatypeType::get(dynamicSelfType,
Expand Down Expand Up @@ -3127,6 +3133,36 @@ CanSILFunctionType SILGenFunction::buildThunkType(
getASTContext());
}

static ManagedValue createPartialApplyOfThunk(SILGenFunction &SGF,
SILLocation loc,
SILFunction *thunk,
SubstitutionMap interfaceSubs,
CanType dynamicSelfType,
CanSILFunctionType toType,
ManagedValue fn) {
CanSILFunctionType substFnType = thunk->getLoweredFunctionType();

if (substFnType->getGenericSignature()) {
substFnType = substFnType->substGenericArgs(SGF.F.getModule(),
interfaceSubs);
}

auto thunkValue = SGF.B.createFunctionRefFor(loc, thunk);
SmallVector<ManagedValue, 2> thunkArgs;
thunkArgs.push_back(fn);
if (dynamicSelfType) {
SILType dynamicSILType = SGF.getLoweredType(dynamicSelfType);
SILValue value = SGF.B.createMetatype(loc, dynamicSILType);
thunkArgs.push_back(ManagedValue::forUnmanaged(value));
}

return
SGF.B.createPartialApply(loc, thunkValue,
SILType::getPrimitiveObjectType(substFnType),
interfaceSubs, thunkArgs,
SILType::getPrimitiveObjectType(toType));
}

/// Create a reabstraction thunk.
static ManagedValue createThunk(SILGenFunction &SGF,
SILLocation loc,
Expand Down Expand Up @@ -3160,7 +3196,7 @@ static ManagedValue createThunk(SILGenFunction &SGF,
thunkType,
sourceType,
toType,
SGF.F.isSerialized());
dynamicSelfType);

// Build it if necessary.
if (thunk->empty()) {
Expand All @@ -3175,28 +3211,9 @@ static ManagedValue createThunk(SILGenFunction &SGF,
dynamicSelfType);
}

CanSILFunctionType substFnType = thunkType;

if (thunkType->getGenericSignature()) {
substFnType = thunkType->substGenericArgs(SGF.F.getModule(),
interfaceSubs);
}

// Create it in our current function.
auto thunkValue = SGF.B.createFunctionRefFor(loc, thunk);
SmallVector<ManagedValue, 2> thunkArgs;
thunkArgs.push_back(fn.ensurePlusOne(SGF, loc));
if (dynamicSelfType) {
SILType dynamicSILType = SGF.getLoweredType(dynamicSelfType);
SILValue value = SGF.B.createMetatype(loc, dynamicSILType);
thunkArgs.push_back(ManagedValue::forUnmanaged(value));
}

ManagedValue thunkedFn =
SGF.B.createPartialApply(loc, thunkValue,
SILType::getPrimitiveObjectType(substFnType),
interfaceSubs, thunkArgs,
SILType::getPrimitiveObjectType(toType));
auto thunkedFn =
createPartialApplyOfThunk(SGF, loc, thunk, interfaceSubs, dynamicSelfType,
toType, fn.ensurePlusOne(SGF, loc));

if (!expectedType->isNoEscape()) {
return thunkedFn;
Expand Down Expand Up @@ -3284,7 +3301,8 @@ SILGenFunction::createWithoutActuallyEscapingClosure(
*this, noEscapingFnTy, escapingFnTy, genericEnv, interfaceSubs);

auto *thunk = SGM.getOrCreateReabstractionThunk(
thunkType, noEscapingFnTy, escapingFnTy, F.isSerialized());
thunkType, noEscapingFnTy, escapingFnTy,
/*dynamicSelfType=*/CanType());

if (thunk->empty()) {
thunk->setWithoutActuallyEscapingThunk();
Expand Down
5 changes: 3 additions & 2 deletions lib/SILGen/SILGenThunk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ SILFunction *SILGenModule::
getOrCreateReabstractionThunk(CanSILFunctionType thunkType,
CanSILFunctionType fromType,
CanSILFunctionType toType,
IsSerialized_t Serialized) {
CanType dynamicSelfType) {
// The reference to the thunk is likely @noescape, but declarations are always
// escaping.
auto thunkDeclType =
Expand All @@ -315,7 +315,8 @@ getOrCreateReabstractionThunk(CanSILFunctionType thunkType,

Mangle::ASTMangler NewMangler;
std::string name = NewMangler.mangleReabstractionThunkHelper(thunkType,
fromInterfaceType, toInterfaceType, M.getSwiftModule());
fromInterfaceType, toInterfaceType, dynamicSelfType,
M.getSwiftModule());

auto loc = RegularLocation::getAutoGeneratedLocation();

Expand Down
3 changes: 2 additions & 1 deletion lib/Sema/ConstraintSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2197,7 +2197,8 @@ Type simplifyTypeImpl(ConstraintSystem &cs, Type type, Fn getFixedTypeFn) {
// through lvalue, inout and IUO types here
Type lookupBaseType = newBase->getWithoutSpecifierType();

if (lookupBaseType->mayHaveMembers()) {
if (lookupBaseType->mayHaveMembers() ||
lookupBaseType->is<DynamicSelfType>()) {
auto *proto = assocType->getProtocol();
auto conformance = cs.DC->getParentModule()->lookupConformance(
lookupBaseType, proto);
Expand Down
Loading