Skip to content

Commit 2666449

Browse files
committed
RequirementMachine: Implement AbstractGenericSignatureRequestRQM
1 parent 24bdecd commit 2666449

File tree

4 files changed

+131
-0
lines changed

4 files changed

+131
-0
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,6 +1467,38 @@ class AbstractGenericSignatureRequest :
14671467
}
14681468
};
14691469

1470+
/// Build a generic signature using the RequirementMachine. This is temporary;
1471+
/// once the GenericSignatureBuilder goes away this will be folded into
1472+
/// AbstractGenericSignatureRequest.
1473+
class AbstractGenericSignatureRequestRQM :
1474+
public SimpleRequest<AbstractGenericSignatureRequestRQM,
1475+
GenericSignatureWithError (const GenericSignatureImpl *,
1476+
SmallVector<GenericTypeParamType *, 2>,
1477+
SmallVector<Requirement, 2>),
1478+
RequestFlags::Cached> {
1479+
public:
1480+
using SimpleRequest::SimpleRequest;
1481+
1482+
private:
1483+
friend SimpleRequest;
1484+
1485+
// Evaluation.
1486+
GenericSignatureWithError
1487+
evaluate(Evaluator &evaluator,
1488+
const GenericSignatureImpl *baseSignature,
1489+
SmallVector<GenericTypeParamType *, 2> addedParameters,
1490+
SmallVector<Requirement, 2> addedRequirements) const;
1491+
1492+
public:
1493+
// Separate caching.
1494+
bool isCached() const { return true; }
1495+
1496+
/// Abstract generic signature requests never have source-location info.
1497+
SourceLoc getNearestLoc() const {
1498+
return SourceLoc();
1499+
}
1500+
};
1501+
14701502
class InferredGenericSignatureRequest :
14711503
public SimpleRequest<InferredGenericSignatureRequest,
14721504
GenericSignatureWithError (ModuleDecl *,

lib/AST/RequirementMachine/RequirementMachine.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,45 @@ void RequirementMachine::initWithProtocols(ArrayRef<const ProtocolDecl *> protos
546546
}
547547
}
548548

549+
/// Build a requirement machine from a set of generic parameters and
550+
/// (possibly non-canonical or non-minimal) structural requirements.
551+
void RequirementMachine::initWithAbstractRequirements(
552+
ArrayRef<GenericTypeParamType *> genericParams,
553+
ArrayRef<Requirement> requirements) {
554+
Params.append(genericParams.begin(), genericParams.end());
555+
556+
auto &ctx = Context.getASTContext();
557+
auto *Stats = ctx.Stats;
558+
559+
if (Stats)
560+
++Stats->getFrontendCounters().NumRequirementMachines;
561+
562+
FrontendStatsTracer tracer(Stats, "build-rewrite-system");
563+
564+
if (Dump) {
565+
llvm::dbgs() << "Adding generic parameters:";
566+
for (auto *paramTy : genericParams)
567+
llvm::dbgs() << " " << Type(paramTy);
568+
llvm::dbgs() << "\n";
569+
}
570+
571+
// Collect the top-level requirements, and all transtively-referenced
572+
// protocol requirement signatures.
573+
RewriteSystemBuilder builder(Context, Dump);
574+
builder.addRequirements(requirements);
575+
576+
// Add the initial set of rewrite rules to the rewrite system.
577+
System.initialize(/*recordLoops=*/true,
578+
std::move(builder.PermanentRules),
579+
std::move(builder.RequirementRules));
580+
581+
computeCompletion(RewriteSystem::AllowInvalidRequirements);
582+
583+
if (Dump) {
584+
llvm::dbgs() << "}\n";
585+
}
586+
}
587+
549588
/// Attempt to obtain a confluent rewrite system using the completion
550589
/// procedure.
551590
void RequirementMachine::computeCompletion(RewriteSystem::ValidityPolicy policy) {

lib/AST/RequirementMachine/RequirementMachine.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class raw_ostream;
2727

2828
namespace swift {
2929

30+
class AbstractGenericSignatureRequestRQM;
3031
class ASTContext;
3132
class AssociatedTypeDecl;
3233
class CanType;
@@ -45,6 +46,7 @@ class RewriteContext;
4546
class RequirementMachine final {
4647
friend class swift::ASTContext;
4748
friend class swift::rewriting::RewriteContext;
49+
friend class swift::AbstractGenericSignatureRequestRQM;
4850

4951
CanGenericSignature Sig;
5052
SmallVector<Type, 2> Params;
@@ -81,6 +83,9 @@ class RequirementMachine final {
8183

8284
void initWithGenericSignature(CanGenericSignature sig);
8385
void initWithProtocols(ArrayRef<const ProtocolDecl *> protos);
86+
void initWithAbstractRequirements(
87+
ArrayRef<GenericTypeParamType *> genericParams,
88+
ArrayRef<Requirement> requirements);
8489

8590
bool isComplete() const;
8691

lib/AST/RequirementMachine/RequirementMachineRequests.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "swift/AST/Requirement.h"
2727
#include "swift/AST/TypeCheckRequests.h"
2828
#include "swift/Basic/Statistic.h"
29+
#include <memory>
2930
#include <vector>
3031

3132
using namespace swift;
@@ -292,4 +293,58 @@ RequirementMachine::computeMinimalGenericSignatureRequirements() {
292293

293294
auto rules = System.getMinimizedGenericSignatureRules();
294295
return buildRequirementsFromRules(rules, getGenericParams());
296+
}
297+
298+
GenericSignatureWithError
299+
AbstractGenericSignatureRequestRQM::evaluate(
300+
Evaluator &evaluator,
301+
const GenericSignatureImpl *baseSignatureImpl,
302+
SmallVector<GenericTypeParamType *, 2> addedParameters,
303+
SmallVector<Requirement, 2> addedRequirements) const {
304+
GenericSignature baseSignature = GenericSignature{baseSignatureImpl};
305+
// If nothing is added to the base signature, just return the base
306+
// signature.
307+
if (addedParameters.empty() && addedRequirements.empty())
308+
return GenericSignatureWithError(baseSignature, /*hadError=*/false);
309+
310+
ASTContext &ctx = addedParameters.empty()
311+
? addedRequirements.front().getFirstType()->getASTContext()
312+
: addedParameters.front()->getASTContext();
313+
314+
SmallVector<GenericTypeParamType *, 4> genericParams(
315+
baseSignature.getGenericParams().begin(),
316+
baseSignature.getGenericParams().end());
317+
genericParams.append(
318+
addedParameters.begin(),
319+
addedParameters.end());
320+
321+
// If there are no added requirements, we can form the signature directly
322+
// with the added parameters.
323+
if (addedRequirements.empty()) {
324+
auto result = GenericSignature::get(genericParams,
325+
baseSignature.getRequirements());
326+
return GenericSignatureWithError(result, /*hadError=*/false);
327+
}
328+
329+
SmallVector<Requirement, 4> requirements(
330+
baseSignature.getRequirements().begin(),
331+
baseSignature.getRequirements().end());
332+
requirements.append(
333+
addedRequirements.begin(),
334+
addedRequirements.end());
335+
336+
// Heap-allocate the requirement machine to save stack space.
337+
std::unique_ptr<RequirementMachine> machine(new RequirementMachine(
338+
ctx.getRewriteContext()));
339+
340+
machine->initWithAbstractRequirements(genericParams, requirements);
341+
342+
auto minimalRequirements =
343+
machine->computeMinimalGenericSignatureRequirements();
344+
345+
// FIXME: Implement this
346+
bool hadError = false;
347+
348+
auto result = GenericSignature::get(genericParams, minimalRequirements);
349+
return GenericSignatureWithError(result, hadError);
295350
}

0 commit comments

Comments
 (0)