Skip to content

Commit 9a563ce

Browse files
committed
[GSB] Extend ResolveResult to describe resolved types that were not realized.
We want to be able to resolve a type to a particular known equivalence class without realizing the corresponding potential archetype. Represent this in ResolveResult, even though we're not using this state yet.
1 parent 8194587 commit 9a563ce

File tree

1 file changed

+88
-54
lines changed

1 file changed

+88
-54
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 88 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ namespace {
6060
typedef GenericSignatureBuilder::EquivalenceClass EquivalenceClass;
6161
typedef EquivalenceClass::DerivedSameTypeComponent DerivedSameTypeComponent;
6262
typedef GenericSignatureBuilder::DelayedRequirement DelayedRequirement;
63-
63+
typedef GenericSignatureBuilder::ResolvedType ResolvedType;
64+
typedef GenericSignatureBuilder::ResolveResult ResolveResult;
6465
} // end anonymous namespace
6566

6667
namespace llvm {
@@ -1341,7 +1342,7 @@ const RequirementSource *FloatingRequirementSource::getSource(
13411342
PotentialArchetype *pa) const {
13421343
switch (kind) {
13431344
case Resolved:
1344-
return storage.get<const RequirementSource *>();
1345+
return storage.get<const RequirementSource *>();
13451346

13461347
case Explicit:
13471348
if (auto requirementRepr = storage.dyn_cast<const RequirementRepr *>())
@@ -2205,36 +2206,39 @@ struct GenericSignatureBuilder::ResolvedType {
22052206
};
22062207

22072208
class GenericSignatureBuilder::ResolveResult {
2208-
union {
2209-
ResolvedType type;
2210-
EquivalenceClass *equivClass;
2211-
};
2212-
2213-
const bool resolved;
2209+
llvm::PointerUnion<Type, PotentialArchetype *> type;
2210+
EquivalenceClass *equivClass;
22142211

22152212
public:
2216-
/// Form a resolved result with the given type.
2217-
ResolveResult(ResolvedType type) : resolved(true) {
2218-
this->type = type;
2219-
}
2213+
/// A specific resolved potential archetype.
2214+
ResolveResult(PotentialArchetype *pa)
2215+
: type(pa), equivClass(pa->getEquivalenceClassIfPresent()) { }
22202216

2221-
/// Form an unresolved result dependent on the given equivalence class.
2222-
ResolveResult(EquivalenceClass *equivClass) : resolved(false) {
2223-
this->equivClass = equivClass;
2217+
/// A resolved type within the given equivalence class.
2218+
ResolveResult(Type type, EquivalenceClass *equivClass)
2219+
: type(type), equivClass(equivClass) {
2220+
assert(type->isTypeParameter() == static_cast<bool>(equivClass) &&
2221+
"type parameters must have equivalence classes");
22242222
}
22252223

2224+
/// For a type that could not be resolved further unless the given
2225+
/// equivalence class changes.
2226+
ResolveResult(EquivalenceClass *equivClass)
2227+
: type(), equivClass(equivClass) { }
2228+
22262229
/// Determine whether this result was resolved.
2227-
explicit operator bool() const { return resolved; }
2230+
explicit operator bool() const { return !type.isNull(); }
22282231

2229-
/// Retrieve the resolved result.
2230-
ResolvedType operator*() const {
2231-
assert(*this);
2232-
return type;
2233-
}
2232+
/// Retrieve the resolved type.
2233+
ResolvedType getResolvedType(GenericSignatureBuilder &builder) const;
2234+
2235+
/// Retrieve the equivalence class into which a resolved type refers.
2236+
EquivalenceClass *getEquivalenceClass() const {
2237+
assert(*this && "Only for resolved types");
2238+
if (equivClass) return equivClass;
22342239

2235-
const ResolvedType *operator->() const {
2236-
assert(*this);
2237-
return &type;
2240+
// Create the equivalence class now.
2241+
return type.get<PotentialArchetype *>()->getOrCreateEquivalenceClass();
22382242
}
22392243

22402244
/// Retrieve the unresolved result.
@@ -2244,6 +2248,29 @@ class GenericSignatureBuilder::ResolveResult {
22442248
}
22452249
};
22462250

2251+
ResolvedType ResolveResult::getResolvedType(
2252+
GenericSignatureBuilder &builder) const {
2253+
assert(*this && "Unresolved result");
2254+
2255+
// Already-resolved potential archetype.
2256+
if (auto pa = type.dyn_cast<PotentialArchetype *>())
2257+
return ResolvedType::forPotentialArchetype(pa);
2258+
2259+
Type type = this->type.get<Type>();
2260+
2261+
// Concrete type.
2262+
if (!type->isTypeParameter())
2263+
return ResolvedType::forConcreteType(type);
2264+
2265+
// Resolve the potential archetype now.
2266+
auto pa =
2267+
builder.resolvePotentialArchetype(type,
2268+
ArchetypeResolutionKind::WellFormed)
2269+
.get<PotentialArchetype *>();
2270+
assert(pa && "Not a resolvable type!");
2271+
return ResolvedType::forPotentialArchetype(pa);
2272+
}
2273+
22472274
/// If there is a same-type requirement to be added for the given nested type
22482275
/// due to a superclass constraint on the parent type, add it now.
22492276
static void maybeAddSameTypeRequirementForNestedType(
@@ -3112,7 +3139,7 @@ auto GenericSignatureBuilder::resolve(UnresolvedType paOrT,
31123139
type = resolved;
31133140
}
31143141

3115-
return ResolvedType::forConcreteType(type);
3142+
return ResolveResult(type, nullptr);
31163143
}
31173144

31183145
// Attempt to resolve the type parameter to a potential archetype. If this
@@ -3122,7 +3149,7 @@ auto GenericSignatureBuilder::resolve(UnresolvedType paOrT,
31223149
if (!pa) return resolved.get<EquivalenceClass *>();
31233150
}
31243151

3125-
return ResolvedType::forPotentialArchetype(pa);
3152+
return ResolveResult(pa);
31263153
}
31273154

31283155
void GenericSignatureBuilder::addGenericParameter(GenericTypeParamDecl *GenericParam) {
@@ -3541,25 +3568,28 @@ ConstraintResult GenericSignatureBuilder::addLayoutRequirement(
35413568
FloatingRequirementSource source,
35423569
UnresolvedHandlingKind unresolvedHandling) {
35433570
// Resolve the subject.
3544-
auto resolvedSubject = resolve(subject, source);
3545-
if (!resolvedSubject) {
3571+
auto maybeResolvedSubject = resolve(subject, source);
3572+
if (!maybeResolvedSubject) {
35463573
return handleUnresolvedRequirement(
3547-
RequirementKind::Layout, subject,
3548-
layout, source,
3549-
resolvedSubject.getUnresolvedEquivClass(),
3550-
unresolvedHandling);
3574+
RequirementKind::Layout, subject,
3575+
layout, source,
3576+
maybeResolvedSubject.getUnresolvedEquivClass(),
3577+
unresolvedHandling);
35513578
}
35523579

3580+
/// Resolve the subject fully.
3581+
ResolvedType resolvedSubject = maybeResolvedSubject.getResolvedType(*this);
3582+
35533583
// If this layout constraint applies to a concrete type, we can fully
35543584
// resolve it now.
3555-
if (resolvedSubject->isType()) {
3585+
if (resolvedSubject.isType()) {
35563586
// If a layout requirement was explicitly written on a concrete type,
35573587
// complain.
35583588
if (source.isExplicit() && source.getLoc().isValid()) {
35593589
Impl->HadAnyError = true;
35603590

35613591
Diags.diagnose(source.getLoc(), diag::requires_not_suitable_archetype,
3562-
TypeLoc::withoutLoc(resolvedSubject->getType()));
3592+
TypeLoc::withoutLoc(resolvedSubject.getType()));
35633593
return ConstraintResult::Concrete;
35643594
}
35653595

@@ -3569,7 +3599,7 @@ ConstraintResult GenericSignatureBuilder::addLayoutRequirement(
35693599
return ConstraintResult::Resolved;
35703600
}
35713601

3572-
auto pa = resolvedSubject->getPotentialArchetype();
3602+
auto pa = resolvedSubject.getPotentialArchetype();
35733603
return addLayoutRequirementDirect(pa, layout, source.getSource(pa));
35743604
}
35753605

@@ -3673,21 +3703,23 @@ ConstraintResult GenericSignatureBuilder::addTypeRequirement(
36733703
FloatingRequirementSource source, UnresolvedHandlingKind unresolvedHandling,
36743704
ModuleDecl *inferForModule) {
36753705
// Resolve the constraint.
3676-
auto resolvedConstraint = resolve(constraint, source);
3677-
if (!resolvedConstraint) {
3706+
auto maybeResolvedConstraint = resolve(constraint, source);
3707+
if (!maybeResolvedConstraint) {
36783708
return handleUnresolvedRequirement(
3679-
RequirementKind::Conformance, subject,
3680-
toRequirementRHS(constraint), source,
3681-
resolvedConstraint.getUnresolvedEquivClass(),
3682-
unresolvedHandling);
3709+
RequirementKind::Conformance, subject,
3710+
toRequirementRHS(constraint), source,
3711+
maybeResolvedConstraint.getUnresolvedEquivClass(),
3712+
unresolvedHandling);
36833713
}
36843714

36853715
// The right-hand side needs to be concrete.
3716+
ResolvedType resolvedConstraint =
3717+
maybeResolvedConstraint.getResolvedType(*this);
36863718
Type constraintType;
3687-
if (auto constraintPA = resolvedConstraint->getPotentialArchetype()) {
3719+
if (auto constraintPA = resolvedConstraint.getPotentialArchetype()) {
36883720
constraintType = constraintPA->getDependentType(Impl->GenericParams);
36893721
} else {
3690-
constraintType = resolvedConstraint->getType();
3722+
constraintType = resolvedConstraint.getType();
36913723
}
36923724

36933725
// Check whether we have a reasonable constraint type at all.
@@ -3709,24 +3741,25 @@ ConstraintResult GenericSignatureBuilder::addTypeRequirement(
37093741
}
37103742

37113743
// Resolve the subject. If we can't, delay the constraint.
3712-
auto resolvedSubject = resolve(subject, source);
3713-
if (!resolvedSubject) {
3744+
auto maybeResolvedSubject = resolve(subject, source);
3745+
if (!maybeResolvedSubject) {
37143746
auto recordedKind =
37153747
constraintType->isExistentialType()
37163748
? RequirementKind::Conformance
37173749
: RequirementKind::Superclass;
37183750
return handleUnresolvedRequirement(
3719-
recordedKind, subject, constraintType,
3720-
source,
3721-
resolvedSubject.getUnresolvedEquivClass(),
3722-
unresolvedHandling);
3751+
recordedKind, subject, constraintType,
3752+
source,
3753+
maybeResolvedSubject.getUnresolvedEquivClass(),
3754+
unresolvedHandling);
37233755
}
37243756

37253757
// If the resolved subject is a type, there may be things we can infer (if it
37263758
// conditionally conforms to the protocol), and we can probably perform
37273759
// diagnostics here.
3728-
if (resolvedSubject->isType()) {
3729-
auto subjectType = resolvedSubject->getType();
3760+
ResolvedType resolvedSubject = maybeResolvedSubject.getResolvedType(*this);
3761+
if (resolvedSubject.isType()) {
3762+
auto subjectType = resolvedSubject.getType();
37303763

37313764
if (constraintType->isExistentialType()) {
37323765
auto layout = constraintType->getExistentialLayout();
@@ -3762,7 +3795,7 @@ ConstraintResult GenericSignatureBuilder::addTypeRequirement(
37623795
return ConstraintResult::Resolved;
37633796
}
37643797

3765-
auto subjectPA = resolvedSubject->getPotentialArchetype();
3798+
auto subjectPA = resolvedSubject.getPotentialArchetype();
37663799
assert(subjectPA && "No potential archetype?");
37673800

37683801
auto resolvedSource = source.getSource(subjectPA);
@@ -4127,8 +4160,9 @@ ConstraintResult GenericSignatureBuilder::addSameTypeRequirement(
41274160
unresolvedHandling);
41284161
}
41294162

4130-
return addSameTypeRequirementDirect(*resolved1, *resolved2, source,
4131-
diagnoseMismatch);
4163+
return addSameTypeRequirementDirect(resolved1.getResolvedType(*this),
4164+
resolved2.getResolvedType(*this),
4165+
source, diagnoseMismatch);
41324166
}
41334167

41344168
ConstraintResult GenericSignatureBuilder::addSameTypeRequirementDirect(

0 commit comments

Comments
 (0)