Skip to content

Commit c91c760

Browse files
committed
RequirementMachine: Correctly handle importing of protocols in inferConditionalRequirements()
This fixes a regression from the rule sharing implementation; I forgot to handle the imported rules in builder.ImportedRules here. This makes the usage of RuleBuilder in conditional requirement inference look like the other usages of RuleBuilder, except that the results are passed to RewriteSystem::addRules() instead of RewriteSystem::initialize().
1 parent 652de97 commit c91c760

File tree

2 files changed

+25
-45
lines changed

2 files changed

+25
-45
lines changed

lib/AST/RequirementMachine/ConcreteTypeWitness.cpp

Lines changed: 12 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -531,8 +531,8 @@ void PropertyMap::inferConditionalRequirements(
531531
return;
532532

533533
SmallVector<Requirement, 2> desugaredRequirements;
534-
// FIXME: Store errors in the rewrite system to be diagnosed
535-
// from the top-level generic signature requests.
534+
535+
// FIXME: Do we need to diagnose these errors?
536536
SmallVector<RequirementError, 2> errors;
537537

538538
// First, desugar all conditional requirements.
@@ -547,47 +547,17 @@ void PropertyMap::inferConditionalRequirements(
547547
}
548548

549549
// Now, convert desugared conditional requirements to rules.
550-
for (auto req : desugaredRequirements) {
551-
if (Debug.contains(DebugFlags::ConditionalRequirements)) {
552-
llvm::dbgs() << "@@@ Desugared requirement: ";
553-
req.dump(llvm::dbgs());
554-
llvm::dbgs() << "\n";
555-
}
556550

557-
if (req.getKind() == RequirementKind::Conformance) {
558-
auto *proto = req.getProtocolDecl();
551+
// This will update System.getReferencedProtocols() with any new
552+
// protocols that were imported.
553+
RuleBuilder builder(Context, System.getReferencedProtocols());
554+
builder.initWithConditionalRequirements(desugaredRequirements,
555+
substitutions);
559556

560-
// If we haven't seen this protocol before, add rules for its
561-
// requirements.
562-
if (!System.isKnownProtocol(proto)) {
563-
if (Debug.contains(DebugFlags::ConditionalRequirements)) {
564-
llvm::dbgs() << "@@@ Unknown protocol: "<< proto->getName() << "\n";
565-
}
566-
567-
RuleBuilder builder(Context, System.getReferencedProtocols());
568-
builder.addReferencedProtocol(proto);
569-
builder.collectRulesFromReferencedProtocols();
557+
assert(builder.PermanentRules.empty());
558+
assert(builder.WrittenRequirements.empty());
570559

571-
for (const auto &rule : builder.PermanentRules)
572-
System.addPermanentRule(rule.first, rule.second);
573-
574-
for (const auto &rule : builder.RequirementRules) {
575-
auto lhs = std::get<0>(rule);
576-
auto rhs = std::get<1>(rule);
577-
System.addExplicitRule(lhs, rhs, /*requirementID=*/None);
578-
}
579-
}
580-
}
581-
582-
auto pair = getRuleForRequirement(req.getCanonical(), /*proto=*/nullptr,
583-
substitutions, Context);
584-
585-
if (Debug.contains(DebugFlags::ConditionalRequirements)) {
586-
llvm::dbgs() << "@@@ Induced rule from conditional requirement: "
587-
<< pair.first << " => " << pair.second << "\n";
588-
}
589-
590-
// FIXME: Do we need a rewrite path here?
591-
(void) System.addRule(pair.first, pair.second);
592-
}
560+
System.addRules(std::move(builder.ImportedRules),
561+
std::move(builder.PermanentRules),
562+
std::move(builder.RequirementRules));
593563
}

test/Generics/conditional_requirement_inference.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,21 @@ struct EquatableBox<T : Equatable> {
1616
// A conditional requirement with a protocol we haven't seen before.
1717
protocol First {}
1818

19-
protocol Second {}
19+
protocol Second {
20+
associatedtype X
21+
associatedtype Y where X == Y
22+
}
2023

2124
extension Array : First where Element : Second {}
2225

26+
func sameType<T>(_: T.Type, _: T.Type) {}
27+
2328
struct SillyBox<T : First> {
24-
// CHECK: Generic signature: <T, U where T == Array<U>, U : Second>
25-
func withArray<U>(_: U) where T == Array<U> {}
29+
// Make sure we pick up the same-type requirement from 'Second' -- U.Y should
30+
// minimize down to U.X.
31+
32+
// CHECK: Generic signature: <T, U, V where T == Array<U>, U : Second, V == U.[Second]X>
33+
func withArray<U, V>(_: U) where T == Array<U>, V == U.Y {
34+
sameType(U.X.self, U.Y.self)
35+
}
2636
}

0 commit comments

Comments
 (0)