Skip to content

Commit 6991a8c

Browse files
committed
[GSB] Basic infrastructure to allow type resolution to fail.
When we resolve() a type that is being used in a constraint, allow that resolution to fail. If it does fail, then record the constraint we were trying to address (via a stub that, currently, just drops it) and continue on. NFC for now; this is intended to allow us to limit the explosion of types in recursive systems.
1 parent 25f3b3d commit 6991a8c

File tree

2 files changed

+62
-10
lines changed

2 files changed

+62
-10
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,16 @@ class GenericSignatureBuilder {
191191
GenericSignatureBuilder(const GenericSignatureBuilder &) = delete;
192192
GenericSignatureBuilder &operator=(const GenericSignatureBuilder &) = delete;
193193

194+
/// When a particular requirement cannot be resolved due to, e.g., a
195+
/// currently-unresolvable or nested type, this routine should be
196+
/// called to record the unresolved requirement to be reconsidered later.
197+
///
198+
/// \returns false, which is used elsewhere to indicate "no failure".
199+
bool recordUnresolvedRequirement(RequirementKind kind,
200+
UnresolvedType lhs,
201+
RequirementRHS rhs,
202+
FloatingRequirementSource source);
203+
194204
/// Retrieve the constraint source conformance for the superclass constraint
195205
/// of the given potential archetype (if present) to the given protocol.
196206
///
@@ -547,9 +557,12 @@ class GenericSignatureBuilder {
547557

548558
/// \brief Resolve the given type as far as this Builder knows how.
549559
///
550-
/// This returns either a non-typealias potential archetype or a Type, if \c
551-
/// type is concrete.
552-
ResolvedType resolve(UnresolvedType type);
560+
/// If successful, this returns either a non-typealias potential archetype
561+
/// or a Type, if \c type is concrete.
562+
/// If the type cannot be resolved, e.g., because it is "too" recursive
563+
/// given the source, returns \c None.
564+
Optional<ResolvedType> resolve(UnresolvedType type,
565+
FloatingRequirementSource source);
553566

554567
/// \brief Dump all of the requirements, both specified and inferred.
555568
LLVM_ATTRIBUTE_DEPRECATED(

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,15 @@ bool EquivalenceClass::isConformanceSatisfiedBySuperclass(
959959
return false;
960960
}
961961

962+
bool GenericSignatureBuilder::recordUnresolvedRequirement(
963+
RequirementKind kind,
964+
UnresolvedType lhs,
965+
RequirementRHS rhs,
966+
FloatingRequirementSource source) {
967+
// FIXME: Drop the requirement for now. Nothing depends on this.
968+
return false;
969+
}
970+
962971
const RequirementSource *GenericSignatureBuilder::resolveSuperConformance(
963972
GenericSignatureBuilder::PotentialArchetype *pa,
964973
ProtocolDecl *proto) {
@@ -1613,9 +1622,9 @@ PotentialArchetype *PotentialArchetype::updateNestedTypeForConformance(
16131622
type = type.subst(subMap, SubstFlags::UseErrorType);
16141623

16151624
builder.addSameTypeRequirement(
1616-
ResolvedType::forNewTypeAlias(resultPA),
1617-
builder.resolve(type),
1618-
RequirementSource::forNestedTypeNameMatch(resultPA));
1625+
UnresolvedType(resultPA),
1626+
UnresolvedType(type),
1627+
RequirementSource::forNestedTypeNameMatch(resultPA));
16191628
}
16201629
}
16211630

@@ -2019,10 +2028,12 @@ auto GenericSignatureBuilder::resolveArchetype(Type type) -> PotentialArchetype
20192028
return nullptr;
20202029
}
20212030

2022-
auto GenericSignatureBuilder::resolve(UnresolvedType paOrT)
2023-
-> ResolvedType {
2031+
auto GenericSignatureBuilder::resolve(UnresolvedType paOrT,
2032+
FloatingRequirementSource source)
2033+
-> Optional<ResolvedType> {
20242034
auto pa = paOrT.dyn_cast<PotentialArchetype *>();
20252035
if (auto type = paOrT.dyn_cast<Type>()) {
2036+
// FIXME: Limit the resolution of the archetype based on the source.
20262037
pa = resolveArchetype(type);
20272038
if (!pa) {
20282039
return ResolvedType::forConcreteType(type);
@@ -2547,19 +2558,47 @@ bool GenericSignatureBuilder::addSameTypeRequirementBetweenConcrete(
25472558
return !matcher.match(type1, type2);
25482559
}
25492560

2561+
/// Map an unresolved type to a requirement right-hand-side.
2562+
static GenericSignatureBuilder::RequirementRHS
2563+
toRequirementRHS(GenericSignatureBuilder::UnresolvedType unresolved) {
2564+
if (auto pa = unresolved.dyn_cast<PotentialArchetype *>())
2565+
return pa;
2566+
2567+
return unresolved.dyn_cast<Type>();
2568+
}
2569+
25502570
bool GenericSignatureBuilder::addSameTypeRequirement(
25512571
UnresolvedType paOrT1,
25522572
UnresolvedType paOrT2,
25532573
FloatingRequirementSource source) {
2554-
return addSameTypeRequirement(resolve(paOrT1), resolve(paOrT2), source);
2574+
return addSameTypeRequirement(paOrT1, paOrT2, source,
2575+
[&](Type type1, Type type2) {
2576+
Diags.diagnose(source.getLoc(), diag::requires_same_concrete_type,
2577+
type1, type2);
2578+
});
25552579
}
2580+
25562581
bool GenericSignatureBuilder::addSameTypeRequirement(
25572582
UnresolvedType paOrT1, UnresolvedType paOrT2,
25582583
FloatingRequirementSource source,
25592584
llvm::function_ref<void(Type, Type)> diagnoseMismatch) {
2560-
return addSameTypeRequirement(resolve(paOrT1), resolve(paOrT2), source,
2585+
2586+
auto resolved1 = resolve(paOrT1, source);
2587+
if (!resolved1) {
2588+
return recordUnresolvedRequirement(RequirementKind::SameType, paOrT1,
2589+
toRequirementRHS(paOrT2), source);
2590+
}
2591+
2592+
auto resolved2 = resolve(paOrT2, source);
2593+
if (!resolved2) {
2594+
return recordUnresolvedRequirement(RequirementKind::SameType, paOrT1,
2595+
toRequirementRHS(paOrT2), source);
2596+
}
2597+
2598+
return addSameTypeRequirement(*resolved1, *resolved2, source,
25612599
diagnoseMismatch);
25622600
}
2601+
25632602
bool GenericSignatureBuilder::addSameTypeRequirement(ResolvedType paOrT1,
25642603
ResolvedType paOrT2,
25652604
FloatingRequirementSource source) {

0 commit comments

Comments
 (0)