@@ -60,7 +60,8 @@ namespace {
60
60
typedef GenericSignatureBuilder::EquivalenceClass EquivalenceClass;
61
61
typedef EquivalenceClass::DerivedSameTypeComponent DerivedSameTypeComponent;
62
62
typedef GenericSignatureBuilder::DelayedRequirement DelayedRequirement;
63
-
63
+ typedef GenericSignatureBuilder::ResolvedType ResolvedType;
64
+ typedef GenericSignatureBuilder::ResolveResult ResolveResult;
64
65
} // end anonymous namespace
65
66
66
67
namespace llvm {
@@ -1341,7 +1342,7 @@ const RequirementSource *FloatingRequirementSource::getSource(
1341
1342
PotentialArchetype *pa) const {
1342
1343
switch (kind) {
1343
1344
case Resolved:
1344
- return storage.get <const RequirementSource *>();
1345
+ return storage.get <const RequirementSource *>();
1345
1346
1346
1347
case Explicit:
1347
1348
if (auto requirementRepr = storage.dyn_cast <const RequirementRepr *>())
@@ -2205,36 +2206,39 @@ struct GenericSignatureBuilder::ResolvedType {
2205
2206
};
2206
2207
2207
2208
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;
2214
2211
2215
2212
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 ()) { }
2220
2216
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" );
2224
2222
}
2225
2223
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
+
2226
2229
// / Determine whether this result was resolved.
2227
- explicit operator bool () const { return resolved ; }
2230
+ explicit operator bool () const { return !type. isNull () ; }
2228
2231
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;
2234
2239
2235
- const ResolvedType *operator ->() const {
2236
- assert (*this );
2237
- return &type;
2240
+ // Create the equivalence class now.
2241
+ return type.get <PotentialArchetype *>()->getOrCreateEquivalenceClass ();
2238
2242
}
2239
2243
2240
2244
// / Retrieve the unresolved result.
@@ -2244,6 +2248,29 @@ class GenericSignatureBuilder::ResolveResult {
2244
2248
}
2245
2249
};
2246
2250
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
+
2247
2274
// / If there is a same-type requirement to be added for the given nested type
2248
2275
// / due to a superclass constraint on the parent type, add it now.
2249
2276
static void maybeAddSameTypeRequirementForNestedType (
@@ -3112,7 +3139,7 @@ auto GenericSignatureBuilder::resolve(UnresolvedType paOrT,
3112
3139
type = resolved;
3113
3140
}
3114
3141
3115
- return ResolvedType::forConcreteType (type);
3142
+ return ResolveResult (type, nullptr );
3116
3143
}
3117
3144
3118
3145
// Attempt to resolve the type parameter to a potential archetype. If this
@@ -3122,7 +3149,7 @@ auto GenericSignatureBuilder::resolve(UnresolvedType paOrT,
3122
3149
if (!pa) return resolved.get <EquivalenceClass *>();
3123
3150
}
3124
3151
3125
- return ResolvedType::forPotentialArchetype (pa);
3152
+ return ResolveResult (pa);
3126
3153
}
3127
3154
3128
3155
void GenericSignatureBuilder::addGenericParameter (GenericTypeParamDecl *GenericParam) {
@@ -3541,25 +3568,28 @@ ConstraintResult GenericSignatureBuilder::addLayoutRequirement(
3541
3568
FloatingRequirementSource source,
3542
3569
UnresolvedHandlingKind unresolvedHandling) {
3543
3570
// Resolve the subject.
3544
- auto resolvedSubject = resolve (subject, source);
3545
- if (!resolvedSubject ) {
3571
+ auto maybeResolvedSubject = resolve (subject, source);
3572
+ if (!maybeResolvedSubject ) {
3546
3573
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);
3551
3578
}
3552
3579
3580
+ // / Resolve the subject fully.
3581
+ ResolvedType resolvedSubject = maybeResolvedSubject.getResolvedType (*this );
3582
+
3553
3583
// If this layout constraint applies to a concrete type, we can fully
3554
3584
// resolve it now.
3555
- if (resolvedSubject-> isType ()) {
3585
+ if (resolvedSubject. isType ()) {
3556
3586
// If a layout requirement was explicitly written on a concrete type,
3557
3587
// complain.
3558
3588
if (source.isExplicit () && source.getLoc ().isValid ()) {
3559
3589
Impl->HadAnyError = true ;
3560
3590
3561
3591
Diags.diagnose (source.getLoc (), diag::requires_not_suitable_archetype,
3562
- TypeLoc::withoutLoc (resolvedSubject-> getType ()));
3592
+ TypeLoc::withoutLoc (resolvedSubject. getType ()));
3563
3593
return ConstraintResult::Concrete;
3564
3594
}
3565
3595
@@ -3569,7 +3599,7 @@ ConstraintResult GenericSignatureBuilder::addLayoutRequirement(
3569
3599
return ConstraintResult::Resolved;
3570
3600
}
3571
3601
3572
- auto pa = resolvedSubject-> getPotentialArchetype ();
3602
+ auto pa = resolvedSubject. getPotentialArchetype ();
3573
3603
return addLayoutRequirementDirect (pa, layout, source.getSource (pa));
3574
3604
}
3575
3605
@@ -3673,21 +3703,23 @@ ConstraintResult GenericSignatureBuilder::addTypeRequirement(
3673
3703
FloatingRequirementSource source, UnresolvedHandlingKind unresolvedHandling,
3674
3704
ModuleDecl *inferForModule) {
3675
3705
// Resolve the constraint.
3676
- auto resolvedConstraint = resolve (constraint, source);
3677
- if (!resolvedConstraint ) {
3706
+ auto maybeResolvedConstraint = resolve (constraint, source);
3707
+ if (!maybeResolvedConstraint ) {
3678
3708
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);
3683
3713
}
3684
3714
3685
3715
// The right-hand side needs to be concrete.
3716
+ ResolvedType resolvedConstraint =
3717
+ maybeResolvedConstraint.getResolvedType (*this );
3686
3718
Type constraintType;
3687
- if (auto constraintPA = resolvedConstraint-> getPotentialArchetype ()) {
3719
+ if (auto constraintPA = resolvedConstraint. getPotentialArchetype ()) {
3688
3720
constraintType = constraintPA->getDependentType (Impl->GenericParams );
3689
3721
} else {
3690
- constraintType = resolvedConstraint-> getType ();
3722
+ constraintType = resolvedConstraint. getType ();
3691
3723
}
3692
3724
3693
3725
// Check whether we have a reasonable constraint type at all.
@@ -3709,24 +3741,25 @@ ConstraintResult GenericSignatureBuilder::addTypeRequirement(
3709
3741
}
3710
3742
3711
3743
// 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 ) {
3714
3746
auto recordedKind =
3715
3747
constraintType->isExistentialType ()
3716
3748
? RequirementKind::Conformance
3717
3749
: RequirementKind::Superclass;
3718
3750
return handleUnresolvedRequirement (
3719
- recordedKind, subject, constraintType,
3720
- source,
3721
- resolvedSubject .getUnresolvedEquivClass (),
3722
- unresolvedHandling);
3751
+ recordedKind, subject, constraintType,
3752
+ source,
3753
+ maybeResolvedSubject .getUnresolvedEquivClass (),
3754
+ unresolvedHandling);
3723
3755
}
3724
3756
3725
3757
// If the resolved subject is a type, there may be things we can infer (if it
3726
3758
// conditionally conforms to the protocol), and we can probably perform
3727
3759
// 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 ();
3730
3763
3731
3764
if (constraintType->isExistentialType ()) {
3732
3765
auto layout = constraintType->getExistentialLayout ();
@@ -3762,7 +3795,7 @@ ConstraintResult GenericSignatureBuilder::addTypeRequirement(
3762
3795
return ConstraintResult::Resolved;
3763
3796
}
3764
3797
3765
- auto subjectPA = resolvedSubject-> getPotentialArchetype ();
3798
+ auto subjectPA = resolvedSubject. getPotentialArchetype ();
3766
3799
assert (subjectPA && " No potential archetype?" );
3767
3800
3768
3801
auto resolvedSource = source.getSource (subjectPA);
@@ -4127,8 +4160,9 @@ ConstraintResult GenericSignatureBuilder::addSameTypeRequirement(
4127
4160
unresolvedHandling);
4128
4161
}
4129
4162
4130
- return addSameTypeRequirementDirect (*resolved1, *resolved2, source,
4131
- diagnoseMismatch);
4163
+ return addSameTypeRequirementDirect (resolved1.getResolvedType (*this ),
4164
+ resolved2.getResolvedType (*this ),
4165
+ source, diagnoseMismatch);
4132
4166
}
4133
4167
4134
4168
ConstraintResult GenericSignatureBuilder::addSameTypeRequirementDirect (
0 commit comments