Skip to content

Commit dfbb580

Browse files
committed
AST: Store the GenericSignature in the AbstractFunctionDecl, NFC
For better or worse, the type of a function can end up as ErrorType, and the generic signature was not stored anywhere else, causing crashes from orphaned generic type parameters. This patch is the first in a series to make this more robust by storing the generic signature before the interface type is computed.
1 parent d56cbfa commit dfbb580

File tree

4 files changed

+55
-32
lines changed

4 files changed

+55
-32
lines changed

include/swift/AST/Decl.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4371,6 +4371,7 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext {
43714371
};
43724372

43734373
GenericParamList *GenericParams;
4374+
GenericSignature *GenericSig;
43744375

43754376
CaptureInfo Captures;
43764377

@@ -4379,7 +4380,7 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext {
43794380
GenericParamList *GenericParams)
43804381
: ValueDecl(Kind, Parent, Name, NameLoc),
43814382
DeclContext(DeclContextKind::AbstractFunctionDecl, Parent),
4382-
Body(nullptr), GenericParams(nullptr) {
4383+
Body(nullptr), GenericParams(nullptr), GenericSig(nullptr) {
43834384
setBodyKind(BodyKind::None);
43844385
setGenericParams(GenericParams);
43854386
AbstractFunctionDeclBits.NumParamPatterns = NumParamPatterns;
@@ -4396,6 +4397,17 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext {
43964397
}
43974398

43984399
void setGenericParams(GenericParamList *GenericParams);
4400+
4401+
public:
4402+
void setGenericSignature(GenericSignature *GenericSig) {
4403+
assert(!this->GenericSig && "already have signature?");
4404+
this->GenericSig = GenericSig;
4405+
}
4406+
4407+
GenericSignature *getGenericSignature() const {
4408+
return GenericSig;
4409+
}
4410+
43994411
public:
44004412
// FIXME: Hack that provides names with keyword arguments for accessors.
44014413
DeclName getEffectiveFullName() const;

lib/AST/DeclContext.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,8 @@ GenericSignature *DeclContext::getGenericSignatureOfContext() const {
250250

251251
case DeclContextKind::AbstractFunctionDecl: {
252252
auto *AFD = cast<AbstractFunctionDecl>(this);
253-
if (auto GFT = AFD->getInterfaceType()->getAs<GenericFunctionType>())
254-
return GFT->getGenericSignature();
253+
if (auto genericSig = AFD->getGenericSignature())
254+
return genericSig;
255255

256256
// If we're within a type context, pick up the generic signature
257257
// of that context.

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -653,16 +653,16 @@ static Type getResultType(TypeChecker &TC, FuncDecl *fn, Type resultType) {
653653
}
654654

655655
bool TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) {
656+
bool invalid = false;
657+
656658
// Create the archetype builder.
657659
ArchetypeBuilder builder = createArchetypeBuilder(func->getParentModule());
658660

659661
// Type check the function declaration, treating all generic type
660662
// parameters as dependent, unresolved.
661663
DependentGenericTypeResolver dependentResolver(builder);
662-
if (checkGenericFuncSignature(*this, &builder, func, dependentResolver)) {
663-
func->overwriteType(ErrorType::get(Context));
664-
return true;
665-
}
664+
if (checkGenericFuncSignature(*this, &builder, func, dependentResolver))
665+
invalid = true;
666666

667667
// If this triggered a recursive validation, back out: we're done.
668668
// FIXME: This is an awful hack.
@@ -677,10 +677,8 @@ bool TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) {
677677
// function signature and type-check it again, completely.
678678
revertGenericFuncSignature(func);
679679
CompleteGenericTypeResolver completeResolver(*this, builder);
680-
if (checkGenericFuncSignature(*this, nullptr, func, completeResolver)) {
681-
func->overwriteType(ErrorType::get(Context));
682-
return true;
683-
}
680+
if (checkGenericFuncSignature(*this, nullptr, func, completeResolver))
681+
invalid = true;
684682

685683
// The generic function signature is complete and well-formed. Determine
686684
// the type of the generic function.
@@ -694,6 +692,32 @@ bool TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) {
694692
// Collect the requirements placed on the generic parameter types.
695693
SmallVector<Requirement, 4> requirements;
696694
collectRequirements(builder, allGenericParams, requirements);
695+
696+
auto sig = GenericSignature::get(allGenericParams, requirements);
697+
698+
// Debugging of the archetype builder and generic signature generation.
699+
if (sig && Context.LangOpts.DebugGenericSignatures) {
700+
func->dumpRef(llvm::errs());
701+
llvm::errs() << "\n";
702+
builder.dump(llvm::errs());
703+
llvm::errs() << "Generic signature: ";
704+
sig->print(llvm::errs());
705+
llvm::errs() << "\n";
706+
llvm::errs() << "Canonical generic signature: ";
707+
sig->getCanonicalSignature()->print(llvm::errs());
708+
llvm::errs() << "\n";
709+
llvm::errs() << "Canonical generic signature for mangling: ";
710+
sig->getCanonicalManglingSignature(*func->getParentModule())
711+
->print(llvm::errs());
712+
llvm::errs() << "\n";
713+
}
714+
715+
func->setGenericSignature(sig);
716+
717+
if (invalid) {
718+
func->overwriteType(ErrorType::get(Context));
719+
return true;
720+
}
697721

698722
// Compute the function type.
699723
Type funcTy;
@@ -742,25 +766,6 @@ bool TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) {
742766
patterns = storedPatterns;
743767
}
744768

745-
auto sig = GenericSignature::get(allGenericParams, requirements);
746-
747-
// Debugging of the archetype builder and generic signature generation.
748-
if (Context.LangOpts.DebugGenericSignatures) {
749-
func->dumpRef(llvm::errs());
750-
llvm::errs() << "\n";
751-
builder.dump(llvm::errs());
752-
llvm::errs() << "Generic signature: ";
753-
sig->print(llvm::errs());
754-
llvm::errs() << "\n";
755-
llvm::errs() << "Canonical generic signature: ";
756-
sig->getCanonicalSignature()->print(llvm::errs());
757-
llvm::errs() << "\n";
758-
llvm::errs() << "Canonical generic signature for mangling: ";
759-
sig->getCanonicalManglingSignature(*func->getParentModule())
760-
->print(llvm::errs());
761-
llvm::errs() << "\n";
762-
}
763-
764769
bool hasSelf = func->getDeclContext()->isTypeContext();
765770
for (unsigned i = 0, e = patterns.size(); i != e; ++i) {
766771
Type argTy;

lib/Serialization/Deserialization.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2238,8 +2238,11 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
22382238
// A polymorphic constructor type needs to refer to the constructor to get
22392239
// its generic parameters.
22402240
ctor->setType(getType(signatureID));
2241-
if (auto interfaceType = getType(interfaceID))
2241+
if (auto interfaceType = getType(interfaceID)) {
2242+
if (auto genericFnType = interfaceType->getAs<GenericFunctionType>())
2243+
ctor->setGenericSignature(genericFnType->getGenericSignature());
22422244
ctor->setInterfaceType(interfaceType);
2245+
}
22432246

22442247
// Set the initializer type of the constructor.
22452248
auto allocType = ctor->getType();
@@ -2480,8 +2483,11 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
24802483
fn->setType(signature);
24812484

24822485
// Set the interface type.
2483-
if (auto interfaceType = getType(interfaceTypeID))
2486+
if (auto interfaceType = getType(interfaceTypeID)) {
2487+
if (auto genericFnType = interfaceType->getAs<GenericFunctionType>())
2488+
fn->setGenericSignature(genericFnType->getGenericSignature());
24842489
fn->setInterfaceType(interfaceType);
2490+
}
24852491

24862492
SmallVector<Pattern *, 16> patternBuf;
24872493
while (Pattern *pattern = maybeReadPattern())

0 commit comments

Comments
 (0)