Skip to content

Commit 5d91b59

Browse files
committed
RequirementMachine: Implement GenericSignature::isConcreteType() query
1 parent 62e0ad0 commit 5d91b59

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

include/swift/AST/RequirementMachine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class RequirementMachine final {
5757
bool requiresClass(Type depType) const;
5858
LayoutConstraint getLayoutConstraint(Type depType) const;
5959
bool requiresProtocol(Type depType, const ProtocolDecl *proto) const;
60+
bool isConcreteType(Type depType) const;
6061

6162
void dump(llvm::raw_ostream &out) const;
6263
};

lib/AST/GenericSignature.cpp

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,47 @@ bool GenericSignatureImpl::requiresProtocol(Type type,
431431

432432
/// Determine whether the given dependent type is equal to a concrete type.
433433
bool GenericSignatureImpl::isConcreteType(Type type) const {
434-
return bool(getConcreteType(type));
434+
assert(type->isTypeParameter() && "Expected a type parameter");
435+
436+
auto computeViaGSB = [&]() {
437+
auto &builder = *getGenericSignatureBuilder();
438+
auto equivClass =
439+
builder.resolveEquivalenceClass(
440+
type,
441+
ArchetypeResolutionKind::CompleteWellFormed);
442+
if (!equivClass) return false;
443+
444+
return bool(equivClass->concreteType);
445+
};
446+
447+
auto computeViaRQM = [&]() {
448+
auto *machine = getRequirementMachine();
449+
return machine->isConcreteType(type);
450+
};
451+
452+
auto &ctx = getASTContext();
453+
if (ctx.LangOpts.EnableRequirementMachine) {
454+
bool rqmResult = computeViaRQM();
455+
456+
#ifndef NDEBUG
457+
bool gsbResult = computeViaGSB();
458+
459+
if (gsbResult != rqmResult) {
460+
llvm::errs() << "RequirementMachine::isConcreteType() is broken\n";
461+
llvm::errs() << "Generic signature: " << GenericSignature(this) << "\n";
462+
llvm::errs() << "Dependent type: "; type.dump(llvm::errs());
463+
llvm::errs() << "\n";
464+
llvm::errs() << "GenericSignatureBuilder says: " << gsbResult << "\n";
465+
llvm::errs() << "RequirementMachine says: " << rqmResult << "\n";
466+
getRequirementMachine()->dump(llvm::errs());
467+
abort();
468+
}
469+
#endif
470+
471+
return rqmResult;
472+
} else {
473+
return computeViaGSB();
474+
}
435475
}
436476

437477
/// Return the concrete type that the given type parameter is constrained to,

lib/AST/RequirementMachine/RequirementMachine.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,4 +388,16 @@ bool RequirementMachine::requiresProtocol(Type depType,
388388
}
389389

390390
return false;
391+
}
392+
393+
bool RequirementMachine::isConcreteType(Type depType) const {
394+
auto term = Impl->Context.getMutableTermForType(depType->getCanonicalType(),
395+
/*proto=*/nullptr);
396+
Impl->System.simplify(term);
397+
398+
auto *equivClass = Impl->Map.lookUpEquivalenceClass(term);
399+
if (!equivClass)
400+
return false;
401+
402+
return equivClass->isConcreteType();
391403
}

0 commit comments

Comments
 (0)