Skip to content

Commit d07812e

Browse files
committed
RequirementMachine: Factor out PropertyMap::concretizeTypeWitnessInConformance()
1 parent 7a56ab8 commit d07812e

File tree

2 files changed

+97
-53
lines changed

2 files changed

+97
-53
lines changed

lib/AST/RequirementMachine/PropertyMap.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,13 @@ class PropertyMap {
216216
llvm::TinyPtrVector<ProtocolConformance *> &conformances,
217217
SmallVectorImpl<InducedRule> &inducedRules) const;
218218

219+
void concretizeTypeWitnessInConformance(
220+
Term key, RequirementKind requirementKind,
221+
CanType concreteType, ArrayRef<Term> substitutions,
222+
const ProtocolDecl *proto, ProtocolConformance *concrete,
223+
AssociatedTypeDecl *assocType,
224+
SmallVectorImpl<InducedRule> &inducedRules) const;
225+
219226
MutableTerm computeConstraintTermForTypeWitness(
220227
Term key, CanType concreteType, CanType typeWitness,
221228
const MutableTerm &subjectType, ArrayRef<Term> substitutions) const;

lib/AST/RequirementMachine/PropertyUnification.cpp

Lines changed: 90 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ void PropertyMap::concretizeNestedTypesFromConcreteParents(
428428
RequirementKind::SameType,
429429
props->ConcreteType->getConcreteType(),
430430
props->ConcreteType->getSubstitutions(),
431-
props->getConformsTo(),
431+
props->ConformsTo,
432432
props->ConcreteConformances,
433433
inducedRules);
434434
}
@@ -523,70 +523,83 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
523523
continue;
524524

525525
for (auto *assocType : assocTypes) {
526-
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
527-
llvm::dbgs() << "^^ " << "Looking up type witness for "
528-
<< proto->getName() << ":" << assocType->getName()
529-
<< " on " << concreteType << "\n";
530-
}
526+
concretizeTypeWitnessInConformance(key, requirementKind,
527+
concreteType, substitutions,
528+
proto, concrete, assocType,
529+
inducedRules);
530+
}
531+
}
532+
}
531533

532-
auto t = concrete->getTypeWitness(assocType);
533-
if (!t) {
534-
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
535-
llvm::dbgs() << "^^ " << "Type witness for " << assocType->getName()
536-
<< " of " << concreteType << " could not be inferred\n";
537-
}
534+
void PropertyMap::concretizeTypeWitnessInConformance(
535+
Term key, RequirementKind requirementKind,
536+
CanType concreteType, ArrayRef<Term> substitutions,
537+
const ProtocolDecl *proto, ProtocolConformance *concrete,
538+
AssociatedTypeDecl *assocType,
539+
SmallVectorImpl<InducedRule> &inducedRules) const {
538540

539-
t = ErrorType::get(concreteType);
540-
}
541+
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
542+
llvm::dbgs() << "^^ " << "Looking up type witness for "
543+
<< proto->getName() << ":" << assocType->getName()
544+
<< " on " << concreteType << "\n";
545+
}
541546

542-
auto typeWitness = t->getCanonicalType();
547+
auto t = concrete->getTypeWitness(assocType);
548+
if (!t) {
549+
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
550+
llvm::dbgs() << "^^ " << "Type witness for " << assocType->getName()
551+
<< " of " << concreteType << " could not be inferred\n";
552+
}
543553

544-
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
545-
llvm::dbgs() << "^^ " << "Type witness for " << assocType->getName()
546-
<< " of " << concreteType << " is " << typeWitness << "\n";
547-
}
554+
t = ErrorType::get(concreteType);
555+
}
548556

549-
MutableTerm subjectType(key);
550-
subjectType.add(Symbol::forAssociatedType(proto, assocType->getName(),
551-
Context));
557+
auto typeWitness = t->getCanonicalType();
552558

553-
MutableTerm constraintType;
559+
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
560+
llvm::dbgs() << "^^ " << "Type witness for " << assocType->getName()
561+
<< " of " << concreteType << " is " << typeWitness << "\n";
562+
}
554563

555-
auto simplify = [&](CanType t) -> CanType {
556-
return CanType(t.transformRec([&](Type t) -> Optional<Type> {
557-
if (!t->isTypeParameter())
558-
return None;
564+
MutableTerm subjectType(key);
565+
subjectType.add(Symbol::forAssociatedType(proto, assocType->getName(),
566+
Context));
559567

560-
auto term = Context.getRelativeTermForType(t->getCanonicalType(),
561-
substitutions);
562-
System.simplify(term);
563-
return Context.getTypeForTerm(term, { });
564-
}));
565-
};
568+
MutableTerm constraintType;
566569

567-
if (simplify(concreteType) == simplify(typeWitness) &&
568-
requirementKind == RequirementKind::SameType) {
569-
// FIXME: ConcreteTypeInDomainMap should support substitutions so
570-
// that we can remove this.
570+
auto simplify = [&](CanType t) -> CanType {
571+
return CanType(t.transformRec([&](Type t) -> Optional<Type> {
572+
if (!t->isTypeParameter())
573+
return None;
571574

572-
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
573-
llvm::dbgs() << "^^ Type witness is the same as the concrete type\n";
574-
}
575+
auto term = Context.getRelativeTermForType(t->getCanonicalType(),
576+
substitutions);
577+
System.simplify(term);
578+
return Context.getTypeForTerm(term, { });
579+
}));
580+
};
575581

576-
// Add a rule T.[P:A] => T.
577-
constraintType = MutableTerm(key);
578-
} else {
579-
constraintType = computeConstraintTermForTypeWitness(
580-
key, concreteType, typeWitness, subjectType,
581-
substitutions);
582-
}
582+
if (simplify(concreteType) == simplify(typeWitness) &&
583+
requirementKind == RequirementKind::SameType) {
584+
// FIXME: ConcreteTypeInDomainMap should support substitutions so
585+
// that we can remove this.
583586

584-
inducedRules.emplace_back(subjectType, constraintType);
585-
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
586-
llvm::dbgs() << "^^ Induced rule " << constraintType
587-
<< " => " << subjectType << "\n";
588-
}
587+
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
588+
llvm::dbgs() << "^^ Type witness is the same as the concrete type\n";
589589
}
590+
591+
// Add a rule T.[P:A] => T.
592+
constraintType = MutableTerm(key);
593+
} else {
594+
constraintType = computeConstraintTermForTypeWitness(
595+
key, concreteType, typeWitness, subjectType,
596+
substitutions);
597+
}
598+
599+
inducedRules.emplace_back(subjectType, constraintType);
600+
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
601+
llvm::dbgs() << "^^ Induced rule " << constraintType
602+
<< " => " << subjectType << "\n";
590603
}
591604
}
592605

@@ -677,12 +690,36 @@ void PropertyMap::recordConcreteConformanceRules(
677690
// minimizes as
678691
//
679692
// <T where T == Int>.
693+
//
694+
// We model this by marking unsatisfied conformance rules as conflicts.
695+
696+
// The conformances in ConcreteConformances should appear in the same
697+
// order as the protocols in ConformsTo.
698+
auto conformanceIter = props->ConcreteConformances.begin();
699+
680700
for (unsigned i : indices(props->ConformsTo)) {
681-
auto *proto = props->ConformsTo[i];
682701
auto conformanceRuleID = props->ConformsToRules[i];
702+
if (conformanceIter == props->ConcreteConformances.end()) {
703+
// FIXME: We should mark the more specific rule of the conformance and
704+
// concrete type rules as conflicting.
705+
System.getRule(conformanceRuleID).markConflicting();
706+
continue;
707+
}
708+
709+
auto *proto = props->ConformsTo[i];
710+
if (proto != (*conformanceIter)->getProtocol()) {
711+
// FIXME: We should mark the more specific rule of the conformance and
712+
// concrete type rules as conflicting.
713+
System.getRule(conformanceRuleID).markConflicting();
714+
continue;
715+
}
716+
683717
recordConcreteConformanceRule(concreteRuleID, conformanceRuleID, proto,
684718
inducedRules);
719+
++conformanceIter;
685720
}
721+
722+
assert(conformanceIter == props->ConcreteConformances.end());
686723
}
687724

688725
if (props->Superclass) {

0 commit comments

Comments
 (0)