Skip to content

Commit 39c1a23

Browse files
committed
---
yaml --- r: 348570 b: refs/heads/master c: 5ea6845 h: refs/heads/master
1 parent 450a2a9 commit 39c1a23

18 files changed

+439
-398
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 089c3adf332ef1ff829dcb70db06f7d0edce17e8
2+
refs/heads/master: 5ea68459528321747370ab866f853bde20225a58
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/include/swift/AST/Decl.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,12 +1505,13 @@ class alignas(8) _GenericContext {
15051505
TrailingWhereClause *TrailingWhere = nullptr;
15061506

15071507
/// The generic signature of this declaration.
1508-
GenericSignature *GenericSig = nullptr;
1508+
llvm::PointerIntPair<GenericSignature *, 1, bool> GenericSigAndBit;
15091509
};
15101510

15111511
class GenericContext : private _GenericContext, public DeclContext {
15121512
friend class GenericParamListRequest;
1513-
1513+
friend class GenericSignatureRequest;
1514+
15141515
protected:
15151516
GenericContext(DeclContextKind Kind, DeclContext *Parent,
15161517
GenericParamList *Params);
@@ -1534,7 +1535,8 @@ class GenericContext : private _GenericContext, public DeclContext {
15341535
/// }
15351536
/// \endcode
15361537
bool isGeneric() const { return getGenericParams() != nullptr; }
1537-
1538+
bool hasComputedGenericSignature() const;
1539+
15381540
/// Retrieve the trailing where clause for this extension, if any.
15391541
TrailingWhereClause *getTrailingWhereClause() const {
15401542
return TrailingWhere;

trunk/include/swift/AST/TypeCheckRequests.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,6 +1160,27 @@ class FunctionOperatorRequest :
11601160
bool isCached() const { return true; }
11611161
};
11621162

1163+
class GenericSignatureRequest :
1164+
public SimpleRequest<GenericSignatureRequest,
1165+
GenericSignature *(GenericContext *),
1166+
CacheKind::SeparatelyCached> {
1167+
public:
1168+
using SimpleRequest::SimpleRequest;
1169+
1170+
private:
1171+
friend SimpleRequest;
1172+
1173+
// Evaluation.
1174+
llvm::Expected<GenericSignature *>
1175+
evaluate(Evaluator &evaluator, GenericContext *value) const;
1176+
1177+
public:
1178+
// Separate caching.
1179+
bool isCached() const { return true; }
1180+
Optional<GenericSignature *> getCachedResult() const;
1181+
void cacheResult(GenericSignature *value) const;
1182+
};
1183+
11631184
// Allow AnyValue to compare two Type values, even though Type doesn't
11641185
// support ==.
11651186
template<>

trunk/include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ SWIFT_REQUEST(TypeChecker, FunctionBuilderTypeRequest, Type(ValueDecl *),
4949
Cached, NoLocationInfo)
5050
SWIFT_REQUEST(TypeChecker, FunctionOperatorRequest, OperatorDecl *(FuncDecl *),
5151
Cached, NoLocationInfo)
52+
SWIFT_REQUEST(NameLookup, GenericSignatureRequest,
53+
GenericSignature *(GenericContext *),
54+
SeparatelyCached, NoLocationInfo)
5255
SWIFT_REQUEST(TypeChecker, InferredGenericSignatureRequest,
5356
GenericSignature *(ModuleDecl *, GenericSignature *,
5457
SmallVector<GenericParamList *, 2>,

trunk/lib/AST/ASTVerifier.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,32 @@ std::pair<bool, Expr *> dispatchVisitPreExprHelper(
167167
}
168168

169169
namespace {
170-
/// Retrieve the "overridden" declaration of this declaration, but only if
171-
// it's already been computed.
172-
template<typename T>
173-
T *getOverriddenDeclIfAvailable(T *decl) {
174-
if (!decl->overriddenDeclsComputed()) return nullptr;
170+
// Retrieve the "overridden" declaration of this declaration, but only if
171+
// it's already been computed.
172+
template <typename T> T *getOverriddenDeclIfAvailable(T *decl) {
173+
if (!decl->overriddenDeclsComputed())
174+
return nullptr;
175175

176-
return cast_or_null<T>(decl->getOverriddenDecl());
177-
}
176+
return cast_or_null<T>(decl->getOverriddenDecl());
178177
}
178+
179+
// Retrieve the generic signature of the innermost context that has been forced
180+
// so far.
181+
//
182+
// This avoids kicking off the request for a generic signature in the verifier.
183+
static GenericSignature *
184+
getNearestForcedGenericSignatureOfContext(DeclContext *dc) {
185+
do {
186+
if (auto decl = dc->getAsDecl())
187+
if (auto GC = decl->getAsGenericContext())
188+
if (GC->hasComputedGenericSignature())
189+
return GC->getGenericSignature();
190+
} while ((dc = dc->getParent()));
191+
192+
return nullptr;
193+
}
194+
} // namespace
195+
179196
class Verifier : public ASTWalker {
180197
PointerUnion<ModuleDecl *, SourceFile *> M;
181198
ASTContext &Ctx;
@@ -686,14 +703,14 @@ class Verifier : public ASTWalker {
686703

687704
void pushScope(DeclContext *scope) {
688705
Scopes.push_back(scope);
689-
GenericSig.push_back(scope->getGenericSignatureOfContext());
706+
GenericSig.push_back(::getNearestForcedGenericSignatureOfContext(scope));
690707
}
691708
void pushScope(BraceStmt *scope) {
692709
Scopes.push_back(scope);
693710
}
694711
void popScope(DeclContext *scope) {
695712
assert(Scopes.back().get<DeclContext*>() == scope);
696-
assert(GenericSig.back() == scope->getGenericSignatureOfContext());
713+
assert(GenericSig.back() == ::getNearestForcedGenericSignatureOfContext(scope));
697714
Scopes.pop_back();
698715
GenericSig.pop_back();
699716
}

trunk/lib/AST/Decl.cpp

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -855,22 +855,14 @@ GenericParamList *GenericContext::getGenericParams() const {
855855
const_cast<GenericContext *>(this)}, nullptr);
856856
}
857857

858-
GenericSignature *GenericContext::getGenericSignature() const {
859-
if (GenericSig)
860-
return GenericSig;
861-
862-
// The signature of a Protocol is trivial (Self: TheProtocol) so let's compute
863-
// it.
864-
if (auto PD = dyn_cast<ProtocolDecl>(this)) {
865-
auto self = PD->getSelfInterfaceType()->castTo<GenericTypeParamType>();
866-
auto req =
867-
Requirement(RequirementKind::Conformance, self, PD->getDeclaredType());
868-
const_cast<GenericContext *>(this)->GenericSig
869-
= GenericSignature::get({self}, {req});
870-
return GenericSig;
871-
}
858+
bool GenericContext::hasComputedGenericSignature() const {
859+
return GenericSigAndBit.getInt();
860+
}
872861

873-
return nullptr;
862+
GenericSignature *GenericContext::getGenericSignature() const {
863+
return evaluateOrDefault(
864+
getASTContext().evaluator,
865+
GenericSignatureRequest{const_cast<GenericContext *>(this)}, nullptr);
874866
}
875867

876868
GenericEnvironment *GenericContext::getGenericEnvironment() const {
@@ -881,8 +873,9 @@ GenericEnvironment *GenericContext::getGenericEnvironment() const {
881873
}
882874

883875
void GenericContext::setGenericSignature(GenericSignature *genericSig) {
884-
assert(GenericSig == nullptr && "Generic signature cannot be changed");
885-
this->GenericSig = genericSig;
876+
assert(!GenericSigAndBit.getPointer() && "Generic signature cannot be changed");
877+
getASTContext().evaluator.cacheOutput(GenericSignatureRequest{this},
878+
std::move(genericSig));
886879
}
887880

888881
SourceRange GenericContext::getGenericTrailingWhereClauseSourceRange() const {
@@ -6159,6 +6152,10 @@ void SubscriptDecl::computeType() {
61596152

61606153
// Record the interface type.
61616154
setInterfaceType(funcTy);
6155+
6156+
// Make sure that there are no unresolved dependent types in the
6157+
// generic signature.
6158+
assert(!funcTy->findUnresolvedDependentMemberType());
61626159
}
61636160

61646161
ObjCSubscriptKind SubscriptDecl::getObjCSubscriptKind() const {
@@ -6753,6 +6750,10 @@ void AbstractFunctionDecl::computeType(AnyFunctionType::ExtInfo info) {
67536750
// Compute the type of the 'self' parameter if we're created one already.
67546751
if (hasSelf)
67556752
computeSelfDeclType();
6753+
6754+
// Make sure that there are no unresolved dependent types in the
6755+
// generic signature.
6756+
assert(!funcTy->findUnresolvedDependentMemberType());
67566757
}
67576758

67586759
bool AbstractFunctionDecl::hasInlinableBodyText() const {

trunk/lib/AST/GenericSignatureBuilder.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5296,6 +5296,12 @@ class GenericSignatureBuilder::InferRequirementsWalker : public TypeWalker {
52965296
auto decl = ty->getAnyNominal();
52975297
if (!decl) return Action::Continue;
52985298

5299+
// FIXME: The GSB and the request evaluator both detect a cycle here if we
5300+
// force a recursive generic signature. We should look into moving cycle
5301+
// detection into the generic signature request(s) - see rdar://55263708
5302+
if (!decl->hasComputedGenericSignature())
5303+
return Action::Continue;
5304+
52995305
auto genericSig = decl->getGenericSignature();
53005306
if (!genericSig)
53015307
return Action::Continue;

trunk/lib/AST/ProtocolConformance.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -547,17 +547,9 @@ void NormalProtocolConformance::differenceAndStoreConditionalRequirements()
547547
return;
548548
}
549549

550-
auto extensionSig = ext->getGenericSignature();
551-
if (!extensionSig) {
552-
if (auto lazyResolver = ctxt.getLazyResolver()) {
553-
lazyResolver->resolveExtension(ext);
554-
extensionSig = ext->getGenericSignature();
555-
}
556-
}
557-
558550
// The type is generic, but the extension doesn't have a signature yet, so
559551
// we might be in a recursive validation situation.
560-
if (!extensionSig) {
552+
if (!ext->hasComputedGenericSignature()) {
561553
// If the extension is invalid, it won't ever get a signature, so we
562554
// "succeed" with an empty result instead.
563555
if (ext->isInvalid()) {
@@ -569,6 +561,15 @@ void NormalProtocolConformance::differenceAndStoreConditionalRequirements()
569561
failure();
570562
return;
571563
}
564+
565+
// FIXME: All of this will be removed when validateExtension goes away.
566+
auto extensionSig = ext->getGenericSignature();
567+
if (!extensionSig) {
568+
if (auto lazyResolver = ctxt.getLazyResolver()) {
569+
lazyResolver->resolveExtension(ext);
570+
extensionSig = ext->getGenericSignature();
571+
}
572+
}
572573

573574
auto canExtensionSig = extensionSig->getCanonicalSignature();
574575
auto canTypeSig = typeSig->getCanonicalSignature();

trunk/lib/AST/TypeCheckRequests.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,3 +805,20 @@ void IsImplicitlyUnwrappedOptionalRequest::cacheResult(bool value) const {
805805
auto *decl = std::get<0>(getStorage());
806806
decl->setImplicitlyUnwrappedOptional(value);
807807
}
808+
809+
//----------------------------------------------------------------------------//
810+
// GenericSignatureRequest computation.
811+
//----------------------------------------------------------------------------//
812+
813+
Optional<GenericSignature *> GenericSignatureRequest::getCachedResult() const {
814+
auto *GC = std::get<0>(getStorage());
815+
if (GC->GenericSigAndBit.getInt()) {
816+
return GC->GenericSigAndBit.getPointer();
817+
}
818+
return None;
819+
}
820+
821+
void GenericSignatureRequest::cacheResult(GenericSignature *value) const {
822+
auto *GC = std::get<0>(getStorage());
823+
GC->GenericSigAndBit.setPointerAndInt(value, true);
824+
}

trunk/lib/Sema/ConstraintSystem.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,9 @@ Type ConstraintSystem::openUnboundGenericType(UnboundGenericType *unbound,
501501

502502
// If the unbound decl hasn't been validated yet, we have a circular
503503
// dependency that isn't being diagnosed properly.
504-
if (!unboundDecl->getGenericSignature()) {
504+
//
505+
// FIXME: Delete this condition. He's dead Jim.
506+
if (!unboundDecl->hasComputedGenericSignature()) {
505507
TC.diagnose(unboundDecl, diag::circular_reference);
506508
return Type();
507509
}

trunk/lib/Sema/MiscDiagnostics.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,9 +1478,13 @@ bool TypeChecker::getDefaultGenericArgumentsString(
14781478
genericParamText << contextTy;
14791479
};
14801480

1481-
interleave(typeDecl->getInnermostGenericParamTypes(),
1482-
printGenericParamSummary, [&]{ genericParamText << ", "; });
1483-
1481+
// FIXME: We can potentially be in the middle of creating a generic signature
1482+
// if we get here. Break this cycle.
1483+
if (typeDecl->hasComputedGenericSignature()) {
1484+
interleave(typeDecl->getInnermostGenericParamTypes(),
1485+
printGenericParamSummary, [&]{ genericParamText << ", "; });
1486+
}
1487+
14841488
genericParamText << ">";
14851489
return true;
14861490
}

0 commit comments

Comments
 (0)