"Properly" compute the depth of Self in ill-formed protocol declarations.

Rather than always using depth 0 for the Self generic type parameter
of a protocol, which is the correct value in well-formed code,
actually compute the depth based on the context. This maintains the
depth invariants of the AST in ill-formed code, resolving a large
number of crashers (169), including rdar://problem/21042357, and
regresses one crasher.

Swift SVN r28920
This commit is contained in:
Doug Gregor
2015-05-22 16:28:29 +00:00
parent db13a714ba
commit a6300dfdc5
172 changed files with 314 additions and 293 deletions

View File

@@ -2451,10 +2451,19 @@ GenericParamList *ProtocolDecl::createGenericParams(DeclContext *dc) {
else
loc = getLoc();
// Find the depth of the 'Self' parameter. This is zero in all valid
// code; however, we compute it nonetheless to maintain the AST
// invariants around generic parameter depths.
unsigned depth = 0;
GenericParamList *outerGenericParams
= dc->getParent()->getGenericParamsOfContext();
if (outerGenericParams)
depth = outerGenericParams->getDepth() + 1;
// The generic parameter 'Self'.
auto &ctx = getASTContext();
auto selfId = ctx.Id_Self;
auto selfDecl = new (ctx) GenericTypeParamDecl(dc, selfId, loc, 0, 0);
auto selfDecl = new (ctx) GenericTypeParamDecl(dc, selfId, loc, depth, 0);
auto protoRef = new (ctx) SimpleIdentTypeRepr(loc, getName());
protoRef->setValue(this);
TypeLoc selfInherited[1] = { TypeLoc(protoRef) };
@@ -2463,7 +2472,10 @@ GenericParamList *ProtocolDecl::createGenericParams(DeclContext *dc) {
selfDecl->setImplicit();
// The generic parameter list itself.
return GenericParamList::create(ctx, SourceLoc(), selfDecl, SourceLoc());
auto result = GenericParamList::create(ctx, SourceLoc(), selfDecl,
SourceLoc());
result->setOuterParameters(outerGenericParams);
return result;
}
/// \brief Return true if the 'getter' is mutating, i.e. that it requires an