Skip to content

Commit 574a450

Browse files
committed
Extensions Do Not Have Parent Signatures
Remove the parent signature from consideration when computing the generic signature for an extension. This cuts off a series of crashers that involved nested extensions with trailing where clauses a la extension Foo { extension Foo where Self.Undefined == Bar { } } The inner (invalid) extension technically has a parent signature from Foo itself. Adding that signature to the GSB means when we go to register the inner extension's generic parameters we crash. Since extensions have to occur at the top level, just remove the parent signature from consideration. Fixes rdar://55502661
1 parent 49179e4 commit 574a450

File tree

6 files changed

+30
-24
lines changed

6 files changed

+30
-24
lines changed

Diff for: include/swift/AST/TypeCheckRequests.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -1094,7 +1094,7 @@ class InferredGenericSignatureRequest :
10941094
public SimpleRequest<InferredGenericSignatureRequest,
10951095
GenericSignature *(ModuleDecl *,
10961096
GenericSignature *,
1097-
SmallVector<GenericParamList *, 2>,
1097+
GenericParamList *,
10981098
SmallVector<Requirement, 2>,
10991099
SmallVector<TypeLoc, 2>,
11001100
bool),
@@ -1110,7 +1110,7 @@ class InferredGenericSignatureRequest :
11101110
evaluate(Evaluator &evaluator,
11111111
ModuleDecl *module,
11121112
GenericSignature *baseSignature,
1113-
SmallVector<GenericParamList *, 2> addedParameters,
1113+
GenericParamList *gpl,
11141114
SmallVector<Requirement, 2> addedRequirements,
11151115
SmallVector<TypeLoc, 2> inferenceSources,
11161116
bool allowConcreteGenericParams) const;

Diff for: include/swift/AST/TypeCheckerTypeIDZone.def

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ SWIFT_REQUEST(NameLookup, GenericSignatureRequest,
5454
SeparatelyCached, NoLocationInfo)
5555
SWIFT_REQUEST(TypeChecker, InferredGenericSignatureRequest,
5656
GenericSignature *(ModuleDecl *, GenericSignature *,
57-
SmallVector<GenericParamList *, 2>,
57+
GenericParamList *,
5858
SmallVector<Requirement, 2>,
5959
SmallVector<TypeLoc, 2>, bool),
6060
Cached, NoLocationInfo)

Diff for: lib/AST/GenericSignatureBuilder.cpp

+14-1
Original file line numberDiff line numberDiff line change
@@ -7690,7 +7690,7 @@ llvm::Expected<GenericSignature *>
76907690
InferredGenericSignatureRequest::evaluate(
76917691
Evaluator &evaluator, ModuleDecl *parentModule,
76927692
GenericSignature *parentSig,
7693-
SmallVector<GenericParamList *, 2> gpLists,
7693+
GenericParamList *gpl,
76947694
SmallVector<Requirement, 2> addedRequirements,
76957695
SmallVector<TypeLoc, 2> inferenceSources,
76967696
bool allowConcreteGenericParams) const {
@@ -7701,6 +7701,19 @@ InferredGenericSignatureRequest::evaluate(
77017701
// from that context.
77027702
builder.addGenericSignature(parentSig);
77037703

7704+
// Type check the generic parameters, treating all generic type
7705+
// parameters as dependent, unresolved.
7706+
SmallVector<GenericParamList *, 2> gpLists;
7707+
if (gpl->getOuterParameters() && !parentSig) {
7708+
for (auto *outerParams = gpl;
7709+
outerParams != nullptr;
7710+
outerParams = outerParams->getOuterParameters()) {
7711+
gpLists.push_back(outerParams);
7712+
}
7713+
} else {
7714+
gpLists.push_back(gpl);
7715+
}
7716+
77047717
// The generic parameter lists MUST appear from innermost to outermost.
77057718
// We walk them backwards to order outer requirements before
77067719
// inner requirements.

Diff for: lib/Sema/TypeCheckDecl.cpp

+2-6
Original file line numberDiff line numberDiff line change
@@ -3086,10 +3086,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
30863086

30873087
// Validate the nominal type declaration being extended.
30883088
(void)nominal->getInterfaceType();
3089-
// Don't bother computing the generic signature if the extended nominal
3090-
// type didn't pass validation so we don't crash.
3091-
if (!nominal->isInvalid())
3092-
(void)ED->getGenericSignature();
3089+
(void)ED->getGenericSignature();
30933090
ED->setValidationToChecked();
30943091

30953092
if (extType && !extType->hasError()) {
@@ -3770,8 +3767,7 @@ void TypeChecker::validateDecl(ValueDecl *D) {
37703767
(void)nominal->getInterfaceType();
37713768

37723769
// Eagerly validate the generic signature of the extension.
3773-
if (!nominal->isInvalid())
3774-
(void)ext->getGenericSignature();
3770+
(void)ext->getGenericSignature();
37753771
}
37763772
}
37773773
if (ext->getValidationState() == Decl::ValidationState::Checking)

Diff for: lib/Sema/TypeCheckGeneric.cpp

+7-14
Original file line numberDiff line numberDiff line change
@@ -448,26 +448,16 @@ void TypeChecker::checkReferencedGenericParams(GenericContext *dc) {
448448
///
449449

450450
GenericSignature *TypeChecker::checkGenericSignature(
451-
GenericParamList *genericParams,
451+
GenericParamList *genericParamList,
452452
DeclContext *dc,
453453
GenericSignature *parentSig,
454454
bool allowConcreteGenericParams,
455455
SmallVector<Requirement, 2> additionalRequirements,
456456
SmallVector<TypeLoc, 2> inferenceSources) {
457-
assert(genericParams && "Missing generic parameters?");
458-
459-
// Type check the generic parameters, treating all generic type
460-
// parameters as dependent, unresolved.
461-
SmallVector<GenericParamList *, 2> gpLists;
462-
for (auto *outerParams = genericParams;
463-
outerParams != nullptr;
464-
outerParams = outerParams->getOuterParameters()) {
465-
gpLists.push_back(outerParams);
466-
}
457+
assert(genericParamList && "Missing generic parameters?");
467458

468459
auto request = InferredGenericSignatureRequest{
469-
dc->getParentModule(), parentSig,
470-
gpLists,
460+
dc->getParentModule(), parentSig, genericParamList,
471461
additionalRequirements, inferenceSources,
472462
allowConcreteGenericParams};
473463
auto *sig = evaluateOrDefault(dc->getASTContext().evaluator,
@@ -636,6 +626,7 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
636626
return cast<SubscriptDecl>(accessor->getStorage())->getGenericSignature();
637627
}
638628

629+
auto *parentSig = GC->getParent()->getGenericSignatureOfContext();
639630
bool allowConcreteGenericParams = false;
640631
SmallVector<TypeLoc, 2> inferenceSources;
641632
SmallVector<Requirement, 2> sameTypeReqs;
@@ -716,13 +707,15 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
716707

717708
// Allow parameters to be equated with concrete types.
718709
allowConcreteGenericParams = true;
710+
// Extensions must occur at the top level, they have no
711+
// (valid) parent signature.
712+
parentSig = nullptr;
719713
inferenceSources.emplace_back(nullptr, extInterfaceType);
720714
}
721715

722716
// EGREGIOUS HACK: The GSB cannot handle the addition of parent signatures
723717
// from malformed decls in many cases. Check the invalid bit and null out the
724718
// parent signature.
725-
auto *parentSig = GC->getParent()->getGenericSignatureOfContext();
726719
if (auto *DD = GC->getParent()->getAsDecl()) {
727720
parentSig = DD->isInvalid() ? nullptr : parentSig;
728721
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// RUN: not %target-swift-frontend %s -typecheck -o /dev/null
2+
3+
extension Result {
4+
extension Result where Result.Undefined == Int {

0 commit comments

Comments
 (0)