Skip to content

Commit f480eea

Browse files
committed
RequirementMachine: Factor out getRuleForRequirement() from RuleBuilder::addRequirement()
1 parent f3b8bed commit f480eea

File tree

4 files changed

+65
-53
lines changed

4 files changed

+65
-53
lines changed

lib/AST/RequirementMachine/InterfaceType.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,3 +493,32 @@ Type PropertyMap::getTypeFromSubstitutionSchema(
493493
return None;
494494
});
495495
}
496+
497+
/// Given a concrete type that may contain type parameters in structural positions,
498+
/// collect all the structural type parameter components, and replace them all with
499+
/// fresh generic parameters. The fresh generic parameters all have a depth of 0,
500+
/// and the index is an index into the 'result' array.
501+
///
502+
/// For example, given the concrete type Foo<X.Y, Array<Z>>, this produces the
503+
/// result type Foo<τ_0_0, Array<τ_0_1>>, with result array {X.Y, Z}.
504+
CanType
505+
RewriteContext::getSubstitutionSchemaFromType(CanType concreteType,
506+
const ProtocolDecl *proto,
507+
SmallVectorImpl<Term> &result) {
508+
assert(!concreteType->isTypeParameter() && "Must have a concrete type here");
509+
510+
if (!concreteType->hasTypeParameter())
511+
return concreteType;
512+
513+
return CanType(concreteType.transformRec([&](Type t) -> Optional<Type> {
514+
if (!t->isTypeParameter())
515+
return None;
516+
517+
unsigned index = result.size();
518+
result.push_back(getTermForType(CanType(t), proto));
519+
520+
return CanGenericTypeParamType::get(/*type sequence=*/ false,
521+
/*depth=*/0, index,
522+
Context);
523+
}));
524+
}

lib/AST/RequirementMachine/RequirementLowering.cpp

Lines changed: 27 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -774,35 +774,6 @@ ProtocolDependenciesRequest::evaluate(Evaluator &evaluator,
774774
// Building rewrite rules from desugared requirements.
775775
//
776776

777-
/// Given a concrete type that may contain type parameters in structural positions,
778-
/// collect all the structural type parameter components, and replace them all with
779-
/// fresh generic parameters. The fresh generic parameters all have a depth of 0,
780-
/// and the index is an index into the 'result' array.
781-
///
782-
/// For example, given the concrete type Foo<X.Y, Array<Z>>, this produces the
783-
/// result type Foo<τ_0_0, Array<τ_0_1>>, with result array {X.Y, Z}.
784-
CanType
785-
RuleBuilder::getConcreteSubstitutionSchema(CanType concreteType,
786-
const ProtocolDecl *proto,
787-
SmallVectorImpl<Term> &result) {
788-
assert(!concreteType->isTypeParameter() && "Must have a concrete type here");
789-
790-
if (!concreteType->hasTypeParameter())
791-
return concreteType;
792-
793-
return CanType(concreteType.transformRec([&](Type t) -> Optional<Type> {
794-
if (!t->isTypeParameter())
795-
return None;
796-
797-
unsigned index = result.size();
798-
result.push_back(Context.getTermForType(CanType(t), proto));
799-
800-
return CanGenericTypeParamType::get(/*type sequence=*/ false,
801-
/*depth=*/0, index,
802-
Context.getASTContext());
803-
}));
804-
}
805-
806777
void RuleBuilder::addRequirements(ArrayRef<Requirement> requirements) {
807778
// Collect all protocols transitively referenced from these requirements.
808779
for (auto req : requirements) {
@@ -861,7 +832,7 @@ void RuleBuilder::addAssociatedType(const AssociatedTypeDecl *type,
861832
PermanentRules.emplace_back(lhs, rhs);
862833
}
863834

864-
/// Lowers a generic requirement to a rewrite rule.
835+
/// Lowers a desugared generic requirement to a rewrite rule.
865836
///
866837
/// If \p proto is null, this is a generic requirement from the top-level
867838
/// generic signature. The added rewrite rule will be rooted in a generic
@@ -870,17 +841,13 @@ void RuleBuilder::addAssociatedType(const AssociatedTypeDecl *type,
870841
/// If \p proto is non-null, this is a generic requirement in the protocol's
871842
/// requirement signature. The added rewrite rule will be rooted in a
872843
/// protocol symbol.
873-
void RuleBuilder::addRequirement(const Requirement &req,
874-
const ProtocolDecl *proto) {
875-
if (Dump) {
876-
llvm::dbgs() << "+ ";
877-
req.dump(llvm::dbgs());
878-
llvm::dbgs() << "\n";
879-
}
880-
844+
std::pair<MutableTerm, MutableTerm>
845+
swift::rewriting::getRuleForRequirement(const Requirement &req,
846+
const ProtocolDecl *proto,
847+
RewriteContext &ctx) {
881848
// Compute the left hand side.
882849
auto subjectType = CanType(req.getFirstType());
883-
auto subjectTerm = Context.getMutableTermForType(subjectType, proto);
850+
auto subjectTerm = ctx.getMutableTermForType(subjectType, proto);
884851

885852
// Compute the right hand side.
886853
MutableTerm constraintTerm;
@@ -895,7 +862,7 @@ void RuleBuilder::addRequirement(const Requirement &req,
895862
auto *proto = req.getProtocolDecl();
896863

897864
constraintTerm = subjectTerm;
898-
constraintTerm.add(Symbol::forProtocol(proto, Context));
865+
constraintTerm.add(Symbol::forProtocol(proto, ctx));
899866
break;
900867
}
901868

@@ -907,10 +874,10 @@ void RuleBuilder::addRequirement(const Requirement &req,
907874

908875
// Build the symbol [superclass: C<X, Y>].
909876
SmallVector<Term, 1> substitutions;
910-
otherType = getConcreteSubstitutionSchema(otherType, proto,
911-
substitutions);
877+
otherType = ctx.getSubstitutionSchemaFromType(otherType, proto,
878+
substitutions);
912879
auto superclassSymbol = Symbol::forSuperclass(otherType, substitutions,
913-
Context);
880+
ctx);
914881

915882
// Build the term T.[superclass: C<X, Y>].
916883
constraintTerm = subjectTerm;
@@ -924,7 +891,7 @@ void RuleBuilder::addRequirement(const Requirement &req,
924891
// T.[layout: L] == T
925892
constraintTerm = subjectTerm;
926893
constraintTerm.add(Symbol::forLayout(req.getLayoutConstraint(),
927-
Context));
894+
ctx));
928895
break;
929896
}
930897

@@ -937,21 +904,32 @@ void RuleBuilder::addRequirement(const Requirement &req,
937904
//
938905
// T.[concrete: C<X, Y>] => T
939906
SmallVector<Term, 1> substitutions;
940-
otherType = getConcreteSubstitutionSchema(otherType, proto,
941-
substitutions);
907+
otherType = ctx.getSubstitutionSchemaFromType(otherType, proto,
908+
substitutions);
942909

943910
constraintTerm = subjectTerm;
944911
constraintTerm.add(Symbol::forConcreteType(otherType, substitutions,
945-
Context));
912+
ctx));
946913
break;
947914
}
948915

949-
constraintTerm = Context.getMutableTermForType(otherType, proto);
916+
constraintTerm = ctx.getMutableTermForType(otherType, proto);
950917
break;
951918
}
952919
}
953920

954-
RequirementRules.emplace_back(subjectTerm, constraintTerm);
921+
return std::make_pair(subjectTerm, constraintTerm);
922+
}
923+
924+
void RuleBuilder::addRequirement(const Requirement &req,
925+
const ProtocolDecl *proto) {
926+
if (Dump) {
927+
llvm::dbgs() << "+ ";
928+
req.dump(llvm::dbgs());
929+
llvm::dbgs() << "\n";
930+
}
931+
932+
RequirementRules.push_back(getRuleForRequirement(req, proto, Context));
955933
}
956934

957935
void RuleBuilder::addRequirement(const StructuralRequirement &req,

lib/AST/RequirementMachine/RequirementLowering.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ void realizeInheritedRequirements(TypeDecl *decl, Type type,
5252
ModuleDecl *moduleForInference,
5353
SmallVectorImpl<StructuralRequirement> &result);
5454

55+
std::pair<MutableTerm, MutableTerm>
56+
getRuleForRequirement(const Requirement &req,
57+
const ProtocolDecl *proto,
58+
RewriteContext &ctx);
59+
5560
/// A utility class for bulding rewrite rules from the top-level requirements
5661
/// of a generic signature.
5762
///
@@ -89,10 +94,6 @@ struct RuleBuilder {
8994
/// eliminated by homotopy reduction.
9095
std::vector<std::pair<MutableTerm, MutableTerm>> RequirementRules;
9196

92-
CanType getConcreteSubstitutionSchema(CanType concreteType,
93-
const ProtocolDecl *proto,
94-
SmallVectorImpl<Term> &result);
95-
9697
RuleBuilder(RewriteContext &ctx, bool dump) : Context(ctx), Dump(dump) {}
9798
void addRequirements(ArrayRef<Requirement> requirements);
9899
void addRequirements(ArrayRef<StructuralRequirement> requirements);

lib/AST/RequirementMachine/RewriteContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ class RewriteContext final {
170170
MutableTerm getRelativeTermForType(CanType typeWitness,
171171
ArrayRef<Term> substitutions);
172172

173+
CanType getSubstitutionSchemaFromType(CanType concreteType,
174+
const ProtocolDecl *proto,
175+
SmallVectorImpl<Term> &result);
176+
173177
AssociatedTypeDecl *getAssociatedTypeForSymbol(Symbol symbol);
174178

175179
Symbol mergeAssociatedTypes(Symbol lhs, Symbol rhs);

0 commit comments

Comments
 (0)