Skip to content

Commit af9ea67

Browse files
committed
RequirementMachine: Implement InferredGenericSignatureRequest
1 parent 42c0a28 commit af9ea67

File tree

5 files changed

+168
-1
lines changed

5 files changed

+168
-1
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1553,7 +1553,50 @@ class InferredGenericSignatureRequest :
15531553
SourceLoc getNearestLoc() const {
15541554
return SourceLoc();
15551555
}
1556-
1556+
1557+
// Cycle handling.
1558+
void noteCycleStep(DiagnosticEngine &diags) const;
1559+
};
1560+
1561+
/// Build a generic signature using the RequirementMachine. This is temporary;
1562+
/// once the GenericSignatureBuilder goes away this will be folded into
1563+
/// InferredGenericSignatureRequest.
1564+
class InferredGenericSignatureRequestRQM :
1565+
public SimpleRequest<InferredGenericSignatureRequestRQM,
1566+
GenericSignatureWithError (ModuleDecl *,
1567+
const GenericSignatureImpl *,
1568+
GenericParamList *,
1569+
WhereClauseOwner,
1570+
SmallVector<Requirement, 2>,
1571+
SmallVector<TypeLoc, 2>,
1572+
bool),
1573+
RequestFlags::Cached> {
1574+
public:
1575+
using SimpleRequest::SimpleRequest;
1576+
1577+
private:
1578+
friend SimpleRequest;
1579+
1580+
// Evaluation.
1581+
GenericSignatureWithError
1582+
evaluate(Evaluator &evaluator,
1583+
ModuleDecl *parentModule,
1584+
const GenericSignatureImpl *baseSignature,
1585+
GenericParamList *genericParams,
1586+
WhereClauseOwner whereClause,
1587+
SmallVector<Requirement, 2> addedRequirements,
1588+
SmallVector<TypeLoc, 2> inferenceSources,
1589+
bool allowConcreteGenericParams) const;
1590+
1591+
public:
1592+
// Separate caching.
1593+
bool isCached() const { return true; }
1594+
1595+
/// Inferred generic signature requests don't have source-location info.
1596+
SourceLoc getNearestLoc() const {
1597+
return SourceLoc();
1598+
}
1599+
15571600
// Cycle handling.
15581601
void noteCycleStep(DiagnosticEngine &diags) const;
15591602
};

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,14 @@ SWIFT_REQUEST(TypeChecker, InferredGenericSignatureRequest,
143143
SmallVector<Requirement, 2>,
144144
SmallVector<TypeLoc, 2>, bool),
145145
Cached, NoLocationInfo)
146+
SWIFT_REQUEST(TypeChecker, InferredGenericSignatureRequestRQM,
147+
GenericSignatureWithError (ModuleDecl *,
148+
const GenericSignatureImpl *,
149+
GenericParamList *,
150+
WhereClauseOwner,
151+
SmallVector<Requirement, 2>,
152+
SmallVector<TypeLoc, 2>, bool),
153+
Cached, NoLocationInfo)
146154
SWIFT_REQUEST(TypeChecker, DistributedModuleIsAvailableRequest,
147155
bool(ModuleDecl *), Cached, NoLocationInfo)
148156
SWIFT_REQUEST(TypeChecker, InheritedTypeRequest,

lib/AST/RequirementMachine/RequirementMachine.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class ASTContext;
3232
class AssociatedTypeDecl;
3333
class CanType;
3434
class GenericTypeParamType;
35+
class InferredGenericSignatureRequestRQM;
3536
class LayoutConstraint;
3637
class ProtocolDecl;
3738
class Requirement;
@@ -47,6 +48,7 @@ class RequirementMachine final {
4748
friend class swift::ASTContext;
4849
friend class swift::rewriting::RewriteContext;
4950
friend class swift::AbstractGenericSignatureRequestRQM;
51+
friend class swift::InferredGenericSignatureRequestRQM;
5052

5153
CanGenericSignature Sig;
5254
SmallVector<Type, 2> Params;

lib/AST/RequirementMachine/RequirementMachineRequests.cpp

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "swift/AST/LazyResolver.h"
2626
#include "swift/AST/Requirement.h"
2727
#include "swift/AST/TypeCheckRequests.h"
28+
#include "swift/AST/TypeRepr.h"
2829
#include "swift/Basic/Statistic.h"
2930
#include "RequirementLowering.h"
3031
#include <memory>
@@ -357,5 +358,110 @@ AbstractGenericSignatureRequestRQM::evaluate(
357358
bool hadError = false;
358359

359360
auto result = GenericSignature::get(genericParams, minimalRequirements);
361+
return GenericSignatureWithError(result, hadError);
362+
}
363+
364+
GenericSignatureWithError
365+
InferredGenericSignatureRequestRQM::evaluate(
366+
Evaluator &evaluator,
367+
ModuleDecl *parentModule,
368+
const GenericSignatureImpl *parentSigImpl,
369+
GenericParamList *genericParamList,
370+
WhereClauseOwner whereClause,
371+
SmallVector<Requirement, 2> addedRequirements,
372+
SmallVector<TypeLoc, 2> inferenceSources,
373+
bool allowConcreteGenericParams) const {
374+
GenericSignature parentSig(parentSigImpl);
375+
376+
SmallVector<GenericTypeParamType *, 4> genericParams(
377+
parentSig.getGenericParams().begin(),
378+
parentSig.getGenericParams().end());
379+
380+
SmallVector<StructuralRequirement, 4> requirements;
381+
for (const auto &req : parentSig.getRequirements())
382+
requirements.push_back({req, SourceLoc(), /*wasInferred=*/false});
383+
384+
const auto visitRequirement = [&](const Requirement &req,
385+
RequirementRepr *reqRepr) {
386+
realizeRequirement(req, reqRepr, /*infer=*/true, requirements);
387+
return false;
388+
};
389+
390+
if (genericParamList) {
391+
// Extensions never have a parent signature.
392+
assert(genericParamList->getOuterParameters() == nullptr || !parentSig);
393+
394+
// Collect all outer generic parameter lists.
395+
SmallVector<GenericParamList *, 2> gpLists;
396+
for (auto *outerParamList = genericParamList;
397+
outerParamList != nullptr;
398+
outerParamList = outerParamList->getOuterParameters()) {
399+
gpLists.push_back(outerParamList);
400+
}
401+
402+
// The generic parameter lists must appear from innermost to outermost.
403+
// We walk them backwards to order outer parameters before inner
404+
// parameters.
405+
for (auto *gpList : llvm::reverse(gpLists)) {
406+
assert(gpList->size() > 0 &&
407+
"Parsed an empty generic parameter list?");
408+
409+
for (auto *gpDecl : *gpList) {
410+
auto *gpType = gpDecl->getDeclaredInterfaceType()
411+
->castTo<GenericTypeParamType>();
412+
genericParams.push_back(gpType);
413+
414+
realizeInheritedRequirements(gpDecl, gpType, /*infer=*/true,
415+
requirements);
416+
}
417+
418+
// Add the generic parameter list's 'where' clause to the builder.
419+
//
420+
// The only time generic parameter lists have a 'where' clause is
421+
// in SIL mode; all other generic declarations have a free-standing
422+
// 'where' clause, which will be visited below.
423+
WhereClauseOwner(parentModule, gpList)
424+
.visitRequirements(TypeResolutionStage::Structural,
425+
visitRequirement);
426+
}
427+
}
428+
429+
if (whereClause) {
430+
std::move(whereClause).visitRequirements(
431+
TypeResolutionStage::Structural,
432+
visitRequirement);
433+
}
434+
435+
// Perform requirement inference from function parameter and result
436+
// types and such.
437+
for (auto sourcePair : inferenceSources) {
438+
auto *typeRepr = sourcePair.getTypeRepr();
439+
auto loc = typeRepr ? typeRepr->getStartLoc() : SourceLoc();
440+
441+
inferRequirements(sourcePair.getType(), loc, requirements);
442+
}
443+
444+
// Finish by adding any remaining requirements. This is used to introduce
445+
// inferred same-type requirements when building the generic signature of
446+
// an extension whose extended type is a generic typealias.
447+
for (const auto &req : addedRequirements)
448+
requirements.push_back({req, SourceLoc(), /*wasInferred=*/true});
449+
450+
// Heap-allocate the requirement machine to save stack space.
451+
std::unique_ptr<RequirementMachine> machine(new RequirementMachine(
452+
parentModule->getASTContext().getRewriteContext()));
453+
454+
machine->initWithWrittenRequirements(genericParams, requirements);
455+
456+
auto minimalRequirements =
457+
machine->computeMinimalGenericSignatureRequirements();
458+
459+
// FIXME: Implement this
460+
bool hadError = false;
461+
462+
auto result = GenericSignature::get(genericParams, minimalRequirements);
463+
464+
// FIXME: Handle allowConcreteGenericParams
465+
360466
return GenericSignatureWithError(result, hadError);
361467
}

lib/AST/TypeCheckRequests.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,14 @@ void InferredGenericSignatureRequest::noteCycleStep(DiagnosticEngine &d) const {
766766
// into this request. See rdar://55263708
767767
}
768768

769+
void InferredGenericSignatureRequestRQM::noteCycleStep(DiagnosticEngine &d) const {
770+
// For now, the GSB does a better job of describing the exact structure of
771+
// the cycle.
772+
//
773+
// FIXME: We should consider merging the circularity handling the GSB does
774+
// into this request. See rdar://55263708
775+
}
776+
769777
//----------------------------------------------------------------------------//
770778
// UnderlyingTypeRequest computation.
771779
//----------------------------------------------------------------------------//

0 commit comments

Comments
 (0)