Skip to content

Commit 112511c

Browse files
committed
Remember to set AbstractFunctionDecl's generic signature in a few places
I originally added this so that we would keep the signature around even if type checking failed, and the function was given an ErrorType. Add a formal check to the AST verifier for this, and set the signature in a few places where it wasn't being set. Note that since we only serialize valid declarations, we don't have to serialize a reference to the generic signature separately, but we do have to remember to set it when deserializing, which wasn't being done for destructors.
1 parent 1a3fa4d commit 112511c

File tree

7 files changed

+37
-7
lines changed

7 files changed

+37
-7
lines changed

lib/AST/ASTVerifier.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,6 +2196,15 @@ struct ASTNodeBase {};
21962196
abort();
21972197
}
21982198

2199+
// If the function has a generic interface type, it should also have a
2200+
// generic signature.
2201+
if (AFD->getInterfaceType()->is<GenericFunctionType>() !=
2202+
(AFD->getGenericSignature() != nullptr)) {
2203+
Out << "Missing generic signature for generic function\n";
2204+
AFD->dump(Out);
2205+
abort();
2206+
}
2207+
21992208
// If there is an interface type, it shouldn't have any unresolved
22002209
// dependent member types.
22012210
// FIXME: This is a general property of the type system.

lib/ClangImporter/ImportDecl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2943,6 +2943,7 @@ namespace {
29432943
getProtocolMethodType(proto, fnType->castTo<AnyFunctionType>());
29442944
result->setType(fnType);
29452945
result->setInterfaceType(interfaceType);
2946+
result->setGenericSignature(proto->getGenericSignature());
29462947
} else {
29472948
result->setType(fnType);
29482949
}
@@ -3740,6 +3741,7 @@ namespace {
37403741
result->setBodyResultType(resultTy);
37413742
result->setType(type);
37423743
result->setInterfaceType(interfaceType);
3744+
result->setGenericSignature(dc->getGenericSignatureOfContext());
37433745

37443746
// Optional methods in protocols.
37453747
if (decl->getImplementationControl() == clang::ObjCMethodDecl::Optional &&
@@ -4215,6 +4217,7 @@ namespace {
42154217

42164218
result->setInitializerInterfaceType(interfaceInitType);
42174219
result->setInterfaceType(interfaceAllocType);
4220+
result->setGenericSignature(dc->getGenericSignatureOfContext());
42184221
} else if (dc->isGenericContext()) {
42194222
Type interfaceAllocType;
42204223
Type interfaceInitType;
@@ -4225,6 +4228,7 @@ namespace {
42254228

42264229
result->setInitializerInterfaceType(interfaceInitType);
42274230
result->setInterfaceType(interfaceAllocType);
4231+
result->setGenericSignature(dc->getGenericSignatureOfContext());
42284232
selfVar->overwriteType(initType->castTo<AnyFunctionType>()->getInput());
42294233
}
42304234

@@ -4407,6 +4411,7 @@ namespace {
44074411
getter->getClangNode());
44084412
thunk->setBodyResultType(elementTy);
44094413
thunk->setInterfaceType(interfaceType);
4414+
thunk->setGenericSignature(dc->getGenericSignatureOfContext());
44104415
thunk->setAccessibility(Accessibility::Public);
44114416

44124417
auto objcAttr = getter->getAttrs().getAttribute<ObjCAttr>();
@@ -4482,6 +4487,7 @@ namespace {
44824487
setter->getClangNode());
44834488
thunk->setBodyResultType(TupleType::getEmpty(C));
44844489
thunk->setInterfaceType(interfaceType);
4490+
thunk->setGenericSignature(dc->getGenericSignatureOfContext());
44854491
thunk->setAccessibility(Accessibility::Public);
44864492

44874493
auto objcAttr = setter->getAttrs().getAttribute<ObjCAttr>();

lib/Sema/CodeSynthesis.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,7 +1304,9 @@ void TypeChecker::completePropertyBehaviorParameter(VarDecl *VD,
13041304
auto ParameterTy = BehaviorParameter->getInterfaceType()
13051305
->castTo<AnyFunctionType>()
13061306
->getResult();
1307-
1307+
1308+
GenericSignature *genericSig = nullptr;
1309+
13081310
TypeSubstitutionMap interfaceMap = sig->getSubstitutionMap(SelfInterfaceSubs);
13091311
auto SubstInterfaceTy = ParameterTy.subst(VD->getModuleContext(),
13101312
interfaceMap, SubstOptions());
@@ -1321,7 +1323,7 @@ void TypeChecker::completePropertyBehaviorParameter(VarDecl *VD,
13211323
// Add the Self type back to the interface and context types.
13221324
if (DC->isTypeContext()) {
13231325
if (DC->isGenericContext()) {
1324-
auto genericSig = DC->getGenericSignatureOfContext();
1326+
genericSig = DC->getGenericSignatureOfContext();
13251327
SubstInterfaceTy = GenericFunctionType::get(genericSig,
13261328
DC->getSelfInterfaceType(),
13271329
SubstInterfaceTy,
@@ -1398,6 +1400,8 @@ void TypeChecker::completePropertyBehaviorParameter(VarDecl *VD,
13981400
TypeLoc::withoutLoc(SubstBodyResultTy), DC);
13991401

14001402
Parameter->setInterfaceType(SubstInterfaceTy);
1403+
Parameter->setGenericSignature(genericSig);
1404+
14011405
// Mark the method to be final, implicit, and private. In a class, this
14021406
// prevents it from being dynamically dispatched.
14031407
if (DC->getAsClassOrClassExtensionContext())

lib/Sema/DerivedConformanceEquatableHashable.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ deriveEquatable_enum_eq(TypeChecker &tc, Decl *parentDecl, EnumDecl *enumDecl) {
248248
// Compute the interface type.
249249
Type interfaceTy;
250250
if (auto genericSig = parentDC->getGenericSignatureOfContext()) {
251+
eqDecl->setGenericSignature(genericSig);
252+
251253
auto enumIfaceTy = parentDC->getDeclaredInterfaceType();
252254
TupleTypeElt ifaceParamElts[] = {
253255
enumIfaceTy, enumIfaceTy,
@@ -397,10 +399,11 @@ deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl,
397399
// Compute the interface type of hashValue().
398400
Type interfaceType;
399401
Type selfIfaceType = getterDecl->computeInterfaceSelfType(false);
400-
if (auto sig = parentDC->getGenericSignatureOfContext())
402+
if (auto sig = parentDC->getGenericSignatureOfContext()) {
403+
getterDecl->setGenericSignature(sig);
401404
interfaceType = GenericFunctionType::get(sig, selfIfaceType, methodType,
402405
AnyFunctionType::ExtInfo());
403-
else
406+
} else
404407
interfaceType = FunctionType::get(selfType, methodType);
405408

406409
getterDecl->setInterfaceType(interfaceType);

lib/Sema/DerivedConformanceRawRepresentable.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ static ConstructorDecl *deriveRawRepresentable_init(TypeChecker &tc,
326326
Type allocIfaceType;
327327
Type initIfaceType;
328328
if (auto sig = parentDC->getGenericSignatureOfContext()) {
329+
initDecl->setGenericSignature(sig);
330+
329331
allocIfaceType = GenericFunctionType::get(sig, selfInterfaceType,
330332
interfaceType,
331333
FunctionType::ExtInfo());

lib/Sema/DerivedConformances.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,12 @@ FuncDecl *DerivedConformance::declareDerivedPropertyGetter(TypeChecker &tc,
163163
Type interfaceType = FunctionType::get(TupleType::getEmpty(C),
164164
propertyInterfaceType);
165165
Type selfInterfaceType = getterDecl->computeInterfaceSelfType(false);
166-
if (auto sig = parentDC->getGenericSignatureOfContext())
166+
if (auto sig = parentDC->getGenericSignatureOfContext()) {
167+
getterDecl->setGenericSignature(sig);
167168
interfaceType = GenericFunctionType::get(sig, selfInterfaceType,
168169
interfaceType,
169170
FunctionType::ExtInfo());
170-
else
171+
} else
171172
interfaceType = type;
172173
getterDecl->setInterfaceType(interfaceType);
173174
getterDecl->setAccessibility(typeDecl->getFormalAccess());

lib/Serialization/Deserialization.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3226,7 +3226,12 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
32263226
dtor->setSelfDecl(selfParams->get(0));
32273227

32283228
dtor->setType(getType(signatureID));
3229-
dtor->setInterfaceType(getType(interfaceID));
3229+
3230+
auto interfaceType = getType(interfaceID);
3231+
if (auto genericFnType = interfaceType->getAs<GenericFunctionType>())
3232+
dtor->setGenericSignature(genericFnType->getGenericSignature());
3233+
dtor->setInterfaceType(interfaceType);
3234+
32303235
if (isImplicit)
32313236
dtor->setImplicit();
32323237

0 commit comments

Comments
 (0)