Skip to content

Commit 422ae0a

Browse files
committed
RequirementMachine: Implement GenericSignature::getConcreteType() query
1 parent 060f490 commit 422ae0a

File tree

3 files changed

+64
-4
lines changed

3 files changed

+64
-4
lines changed

include/swift/AST/RequirementMachine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class RequirementMachine final {
6262
GenericSignature::RequiredProtocols getRequiredProtocols(Type depType) const;
6363
Type getSuperclassBound(Type depType) const;
6464
bool isConcreteType(Type depType) const;
65+
Type getConcreteType(Type depType) const;
6566
bool areSameTypeParameterInContext(Type depType1, Type depType2) const;
6667
Type getCanonicalTypeInContext(Type type,
6768
TypeArrayView<GenericTypeParamType> genericParams) const;

lib/AST/GenericSignature.cpp

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -558,14 +558,56 @@ bool GenericSignatureImpl::isConcreteType(Type type) const {
558558
Type GenericSignatureImpl::getConcreteType(Type type) const {
559559
assert(type->isTypeParameter() && "Expected a type parameter");
560560

561-
auto &builder = *getGenericSignatureBuilder();
562-
auto equivClass =
561+
auto computeViaGSB = [&]() -> Type {
562+
auto &builder = *getGenericSignatureBuilder();
563+
auto equivClass =
563564
builder.resolveEquivalenceClass(
564565
type,
565566
ArchetypeResolutionKind::CompleteWellFormed);
566-
if (!equivClass) return Type();
567+
if (!equivClass) return nullptr;
568+
569+
return equivClass->concreteType;
570+
};
571+
572+
auto computeViaRQM = [&]() {
573+
auto *machine = getRequirementMachine();
574+
return machine->getConcreteType(type);
575+
};
567576

568-
return equivClass->concreteType;
577+
auto &ctx = getASTContext();
578+
if (ctx.LangOpts.EnableRequirementMachine) {
579+
auto rqmResult = computeViaRQM();
580+
581+
#ifndef NDEBUG
582+
auto gsbResult = computeViaGSB();
583+
584+
auto check = [&]() {
585+
if (!gsbResult || !rqmResult)
586+
return !gsbResult == !rqmResult;
587+
return gsbResult->isEqual(rqmResult);
588+
};
589+
590+
if (!check()) {
591+
llvm::errs() << "RequirementMachine::getConcreteType() is broken\n";
592+
llvm::errs() << "Generic signature: " << GenericSignature(this) << "\n";
593+
llvm::errs() << "Dependent type: "; type.dump(llvm::errs());
594+
llvm::errs() << "GenericSignatureBuilder says: " << gsbResult << "\n";
595+
if (gsbResult)
596+
gsbResult.dump(llvm::errs());
597+
llvm::errs() << "\n";
598+
llvm::errs() << "RequirementMachine says: " << rqmResult << "\n";
599+
if (rqmResult)
600+
rqmResult.dump(llvm::errs());
601+
llvm::errs() << "\n";
602+
getRequirementMachine()->dump(llvm::errs());
603+
abort();
604+
}
605+
#endif
606+
607+
return rqmResult;
608+
} else {
609+
return computeViaGSB();
610+
}
569611
}
570612

571613
LayoutConstraint GenericSignatureImpl::getLayoutConstraint(Type type) const {

lib/AST/RequirementMachine/RequirementMachine.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,23 @@ bool RequirementMachine::isConcreteType(Type depType) const {
538538
return equivClass->isConcreteType();
539539
}
540540

541+
Type RequirementMachine::getConcreteType(Type depType) const {
542+
auto term = Impl->Context.getMutableTermForType(depType->getCanonicalType(),
543+
/*proto=*/nullptr);
544+
Impl->System.simplify(term);
545+
Impl->verify(term);
546+
547+
auto *equivClass = Impl->Map.lookUpEquivalenceClass(term);
548+
if (!equivClass)
549+
return Type();
550+
551+
if (!equivClass->isConcreteType())
552+
return Type();
553+
554+
auto &protos = Impl->System.getProtocols();
555+
return equivClass->getConcreteType({ }, protos, Impl->Context);
556+
}
557+
541558
bool RequirementMachine::areSameTypeParameterInContext(Type depType1,
542559
Type depType2) const {
543560
auto term1 = Impl->Context.getMutableTermForType(depType1->getCanonicalType(),

0 commit comments

Comments
 (0)