@@ -2390,43 +2390,6 @@ Type ResolvedType::getDependentType(GenericSignatureBuilder &builder) const {
2390
2390
return result->isTypeParameter () ? result : Type ();
2391
2391
}
2392
2392
2393
- // / If there is a same-type requirement to be added for the given nested type
2394
- // / due to a superclass constraint on the parent type, add it now.
2395
- static void maybeAddSameTypeRequirementForNestedType (
2396
- ResolvedType nested,
2397
- const RequirementSource *superSource,
2398
- GenericSignatureBuilder &builder) {
2399
- // If there's no super conformance, we're done.
2400
- if (!superSource) return ;
2401
-
2402
- // If the nested type is already concrete, we're done.
2403
- if (nested.getAsConcreteType ()) return ;
2404
-
2405
- // Dig out the associated type.
2406
- AssociatedTypeDecl *assocType = nullptr ;
2407
- if (auto depMemTy =
2408
- nested.getDependentType (builder)->getAs <DependentMemberType>())
2409
- assocType = depMemTy->getAssocType ();
2410
- else
2411
- return ;
2412
-
2413
- // Dig out the type witness.
2414
- auto superConformance = superSource->getProtocolConformance ().getConcrete ();
2415
- auto concreteType = superConformance->getTypeWitness (assocType);
2416
- if (!concreteType) return ;
2417
-
2418
- // We should only have interface types here.
2419
- assert (!superConformance->getType ()->hasArchetype ());
2420
- assert (!concreteType->hasArchetype ());
2421
-
2422
- // Add the same-type constraint.
2423
- auto nestedSource = superSource->viaParent (builder, assocType);
2424
-
2425
- builder.addSameTypeRequirement (
2426
- nested.getUnresolvedType (), concreteType, nestedSource,
2427
- GenericSignatureBuilder::UnresolvedHandlingKind::GenerateConstraints);
2428
- }
2429
-
2430
2393
auto PotentialArchetype::getOrCreateEquivalenceClass (
2431
2394
GenericSignatureBuilder &builder) const
2432
2395
-> EquivalenceClass * {
@@ -2562,7 +2525,9 @@ static void concretizeNestedTypeFromConcreteParent(
2562
2525
// If we don't already have a conformance of the parent to this protocol,
2563
2526
// add it now; it was elided earlier.
2564
2527
if (parentEquiv->conformsTo .count (proto) == 0 ) {
2565
- auto source = parentEquiv->concreteTypeConstraints .front ().source ;
2528
+ auto source = (!isSuperclassConstrained
2529
+ ? parentEquiv->concreteTypeConstraints .front ().source
2530
+ : parentEquiv->superclassConstraints .front ().source );
2566
2531
parentEquiv->recordConformanceConstraint (builder, parent, proto, source);
2567
2532
}
2568
2533
@@ -2592,7 +2557,7 @@ static void concretizeNestedTypeFromConcreteParent(
2592
2557
if (conformance.isConcrete ()) {
2593
2558
witnessType =
2594
2559
conformance.getConcrete ()->getTypeWitness (assocType);
2595
- if (!witnessType || witnessType-> hasError () )
2560
+ if (!witnessType)
2596
2561
return ; // FIXME: should we delay here?
2597
2562
} else if (auto archetype = concreteParent->getAs <ArchetypeType>()) {
2598
2563
witnessType = archetype->getNestedType (assocType->getName ());
@@ -2657,20 +2622,11 @@ PotentialArchetype *PotentialArchetype::updateNestedTypeForConformance(
2657
2622
2658
2623
// If we have a potential archetype that requires more processing, do so now.
2659
2624
if (shouldUpdatePA) {
2660
- // If there's a superclass constraint that conforms to the protocol,
2661
- // add the appropriate same-type relationship.
2662
- const auto proto = assocType->getProtocol ();
2663
- if (proto) {
2664
- if (auto superSource = builder.resolveSuperConformance (this , proto)) {
2665
- maybeAddSameTypeRequirementForNestedType (resultPA, superSource,
2666
- builder);
2667
- }
2668
- }
2669
-
2670
2625
// We know something concrete about the parent PA, so we need to propagate
2671
2626
// that information to this new archetype.
2672
- if (isConcreteType ()) {
2673
- concretizeNestedTypeFromConcreteParent (this , resultPA, builder);
2627
+ if (auto equivClass = getEquivalenceClassIfPresent ()) {
2628
+ if (equivClass->concreteType || equivClass->superclass )
2629
+ concretizeNestedTypeFromConcreteParent (this , resultPA, builder);
2674
2630
}
2675
2631
}
2676
2632
@@ -3618,50 +3574,29 @@ static Type getStructuralType(TypeDecl *typeDecl, bool keepSugar) {
3618
3574
return typeDecl->getDeclaredInterfaceType ();
3619
3575
}
3620
3576
3621
- static Type substituteConcreteType (GenericSignatureBuilder &builder,
3622
- PotentialArchetype *basePA,
3577
+ static Type substituteConcreteType (Type parentType,
3623
3578
TypeDecl *concreteDecl) {
3579
+ if (parentType->is <ErrorType>())
3580
+ return parentType;
3581
+
3624
3582
assert (concreteDecl);
3625
3583
3626
3584
auto *dc = concreteDecl->getDeclContext ();
3627
- auto *proto = dc->getSelfProtocolDecl ();
3628
3585
3629
3586
// Form an unsubstituted type referring to the given type declaration,
3630
3587
// for use in an inferred same-type requirement.
3631
3588
auto type = getStructuralType (concreteDecl, /* keepSugar=*/ true );
3632
3589
3633
- SubstitutionMap subMap;
3634
- if (proto) {
3635
- // Substitute in the type of the current PotentialArchetype in
3636
- // place of 'Self' here.
3637
- auto parentType = basePA->getDependentType (builder.getGenericParams ());
3638
-
3639
- subMap = SubstitutionMap::getProtocolSubstitutions (
3640
- proto, parentType, ProtocolConformanceRef (proto));
3641
- } else {
3642
- // Substitute in the superclass type.
3643
- auto parentPA = basePA->getEquivalenceClassIfPresent ();
3644
- auto parentType =
3645
- parentPA->concreteType ? parentPA->concreteType : parentPA->superclass ;
3646
- auto parentDecl = parentType->getAnyNominal ();
3647
-
3648
- subMap = parentType->getContextSubstitutionMap (
3649
- parentDecl->getParentModule (), dc);
3650
- }
3590
+ auto subMap = parentType->getContextSubstitutionMap (
3591
+ dc->getParentModule (), dc);
3651
3592
3652
3593
return type.subst (subMap);
3653
- };
3594
+ }
3654
3595
3655
3596
ResolvedType GenericSignatureBuilder::maybeResolveEquivalenceClass (
3656
3597
Type type,
3657
3598
ArchetypeResolutionKind resolutionKind,
3658
3599
bool wantExactPotentialArchetype) {
3659
- // An error type is best modeled as an unresolved potential archetype, since
3660
- // there's no way to be sure what it is actually meant to be.
3661
- if (type->is <ErrorType>()) {
3662
- return ResolvedType::forUnresolved (nullptr );
3663
- }
3664
-
3665
3600
// The equivalence class of a generic type is known directly.
3666
3601
if (auto genericParam = type->getAs <GenericTypeParamType>()) {
3667
3602
unsigned index = GenericParamKey (genericParam).findIndexIn (
@@ -3683,8 +3618,11 @@ ResolvedType GenericSignatureBuilder::maybeResolveEquivalenceClass(
3683
3618
wantExactPotentialArchetype);
3684
3619
if (!resolvedBase) return resolvedBase;
3685
3620
// If the base is concrete, so is this member.
3686
- if (resolvedBase.getAsConcreteType ())
3687
- return ResolvedType::forConcrete (type);
3621
+ if (auto parentType = resolvedBase.getAsConcreteType ()) {
3622
+ auto concreteType = substituteConcreteType (parentType,
3623
+ depMemTy->getAssocType ());
3624
+ return ResolvedType::forConcrete (concreteType);
3625
+ }
3688
3626
3689
3627
// Find the nested type declaration for this.
3690
3628
auto baseEquivClass = resolvedBase.getEquivalenceClass (*this );
@@ -3701,59 +3639,84 @@ ResolvedType GenericSignatureBuilder::maybeResolveEquivalenceClass(
3701
3639
basePA = baseEquivClass->members .front ();
3702
3640
}
3703
3641
3704
- AssociatedTypeDecl *nestedTypeDecl = nullptr ;
3705
3642
if (auto assocType = depMemTy->getAssocType ()) {
3706
3643
// Check whether this associated type references a protocol to which
3707
- // the base conforms. If not, it's unresolved.
3708
- if (baseEquivClass->conformsTo .find (assocType->getProtocol ())
3644
+ // the base conforms. If not, it's either concrete or unresolved.
3645
+ auto *proto = assocType->getProtocol ();
3646
+ if (baseEquivClass->conformsTo .find (proto)
3709
3647
== baseEquivClass->conformsTo .end ()) {
3710
- if (!baseEquivClass->concreteType ||
3711
- !lookupConformance (type->getCanonicalType (),
3712
- baseEquivClass->concreteType ,
3713
- assocType->getProtocol ())) {
3648
+ if (baseEquivClass->concreteType &&
3649
+ lookupConformance (type->getCanonicalType (),
3650
+ baseEquivClass->concreteType ,
3651
+ proto)) {
3652
+ // Fall through
3653
+ } else if (baseEquivClass->superclass &&
3654
+ lookupConformance (type->getCanonicalType (),
3655
+ baseEquivClass->superclass ,
3656
+ proto)) {
3657
+ // Fall through
3658
+ } else {
3714
3659
return ResolvedType::forUnresolved (baseEquivClass);
3715
3660
}
3661
+
3662
+ // FIXME: Instead of falling through, we ought to return a concrete
3663
+ // type here, but then we fail to update a nested PotentialArchetype
3664
+ // if one happens to already exist. It would be cleaner if concrete
3665
+ // types never had nested PotentialArchetypes.
3716
3666
}
3717
3667
3718
- nestedTypeDecl = assocType;
3668
+ auto nestedPA =
3669
+ basePA->updateNestedTypeForConformance (*this , assocType,
3670
+ resolutionKind);
3671
+ if (!nestedPA)
3672
+ return ResolvedType::forUnresolved (baseEquivClass);
3673
+
3674
+ // If base resolved to the anchor, then the nested potential archetype
3675
+ // we found is the resolved potential archetype. Return it directly,
3676
+ // so it doesn't need to be resolved again.
3677
+ if (basePA == resolvedBase.getPotentialArchetypeIfKnown ())
3678
+ return ResolvedType (nestedPA);
3679
+
3680
+ // Compute the resolved dependent type to return.
3681
+ Type resolvedBaseType = resolvedBase.getDependentType (*this );
3682
+ Type resolvedMemberType =
3683
+ DependentMemberType::get (resolvedBaseType, assocType);
3684
+
3685
+ return ResolvedType (resolvedMemberType,
3686
+ nestedPA->getOrCreateEquivalenceClass (*this ));
3719
3687
} else {
3720
- auto *typeAlias =
3688
+ auto *concreteDecl =
3721
3689
baseEquivClass->lookupNestedType (*this , depMemTy->getName ());
3722
3690
3723
- if (!typeAlias )
3691
+ if (!concreteDecl )
3724
3692
return ResolvedType::forUnresolved (baseEquivClass);
3725
3693
3726
- auto type = substituteConcreteType (*this , basePA, typeAlias);
3727
- return maybeResolveEquivalenceClass (type, resolutionKind,
3728
- wantExactPotentialArchetype);
3729
- }
3694
+ Type parentType;
3695
+ auto *proto = concreteDecl->getDeclContext ()->getSelfProtocolDecl ();
3696
+ if (!proto) {
3697
+ parentType = (baseEquivClass->concreteType
3698
+ ? baseEquivClass->concreteType
3699
+ : baseEquivClass->superclass );
3700
+ } else {
3701
+ if (baseEquivClass->concreteType &&
3702
+ lookupConformance (type->getCanonicalType (),
3703
+ baseEquivClass->concreteType ,
3704
+ proto)) {
3705
+ parentType = baseEquivClass->concreteType ;
3706
+ } else if (baseEquivClass->superclass &&
3707
+ lookupConformance (type->getCanonicalType (),
3708
+ baseEquivClass->superclass ,
3709
+ proto)) {
3710
+ parentType = baseEquivClass->superclass ;
3711
+ } else {
3712
+ parentType = basePA->getDependentType (getGenericParams ());
3713
+ }
3714
+ }
3730
3715
3731
- auto nestedPA =
3732
- basePA->updateNestedTypeForConformance (*this , nestedTypeDecl,
3733
- resolutionKind);
3734
- if (!nestedPA)
3735
- return ResolvedType::forUnresolved (baseEquivClass);
3736
-
3737
- // If base resolved to the anchor, then the nested potential archetype
3738
- // we found is the resolved potential archetype. Return it directly,
3739
- // so it doesn't need to be resolved again.
3740
- if (basePA == resolvedBase.getPotentialArchetypeIfKnown ())
3741
- return ResolvedType (nestedPA);
3742
-
3743
- // Compute the resolved dependent type to return.
3744
- Type resolvedBaseType = resolvedBase.getDependentType (*this );
3745
- Type resolvedMemberType;
3746
- if (auto assocType = dyn_cast<AssociatedTypeDecl>(nestedTypeDecl)) {
3747
- resolvedMemberType =
3748
- DependentMemberType::get (resolvedBaseType, assocType);
3749
- } else {
3750
- // Note: strange case that might not even really be dependent.
3751
- resolvedMemberType =
3752
- DependentMemberType::get (resolvedBaseType, depMemTy->getName ());
3716
+ auto concreteType = substituteConcreteType (parentType, concreteDecl);
3717
+ return maybeResolveEquivalenceClass (concreteType, resolutionKind,
3718
+ wantExactPotentialArchetype);
3753
3719
}
3754
-
3755
- return ResolvedType (resolvedMemberType,
3756
- nestedPA->getOrCreateEquivalenceClass (*this ));
3757
3720
}
3758
3721
3759
3722
// If it's not a type parameter, it won't directly resolve to one.
@@ -5556,7 +5519,8 @@ GenericSignatureBuilder::finalize(SourceLoc loc,
5556
5519
// Don't allow a generic parameter to be equivalent to a concrete type,
5557
5520
// because then we don't actually have a parameter.
5558
5521
auto equivClass = rep->getOrCreateEquivalenceClass (*this );
5559
- if (equivClass->concreteType ) {
5522
+ if (equivClass->concreteType &&
5523
+ !equivClass->concreteType ->is <ErrorType>()) {
5560
5524
if (auto constraint = equivClass->findAnyConcreteConstraintAsWritten ()){
5561
5525
Impl->HadAnyError = true ;
5562
5526
0 commit comments