@@ -2370,43 +2370,6 @@ Type ResolvedType::getDependentType(GenericSignatureBuilder &builder) const {
2370
2370
return result->isTypeParameter () ? result : Type ();
2371
2371
}
2372
2372
2373
- // / If there is a same-type requirement to be added for the given nested type
2374
- // / due to a superclass constraint on the parent type, add it now.
2375
- static void maybeAddSameTypeRequirementForNestedType (
2376
- ResolvedType nested,
2377
- const RequirementSource *superSource,
2378
- GenericSignatureBuilder &builder) {
2379
- // If there's no super conformance, we're done.
2380
- if (!superSource) return ;
2381
-
2382
- // If the nested type is already concrete, we're done.
2383
- if (nested.getAsConcreteType ()) return ;
2384
-
2385
- // Dig out the associated type.
2386
- AssociatedTypeDecl *assocType = nullptr ;
2387
- if (auto depMemTy =
2388
- nested.getDependentType (builder)->getAs <DependentMemberType>())
2389
- assocType = depMemTy->getAssocType ();
2390
- else
2391
- return ;
2392
-
2393
- // Dig out the type witness.
2394
- auto superConformance = superSource->getProtocolConformance ().getConcrete ();
2395
- auto concreteType = superConformance->getTypeWitness (assocType);
2396
- if (!concreteType) return ;
2397
-
2398
- // We should only have interface types here.
2399
- assert (!superConformance->getType ()->hasArchetype ());
2400
- assert (!concreteType->hasArchetype ());
2401
-
2402
- // Add the same-type constraint.
2403
- auto nestedSource = superSource->viaParent (builder, assocType);
2404
-
2405
- builder.addSameTypeRequirement (
2406
- nested.getUnresolvedType (), concreteType, nestedSource,
2407
- GenericSignatureBuilder::UnresolvedHandlingKind::GenerateConstraints);
2408
- }
2409
-
2410
2373
auto PotentialArchetype::getOrCreateEquivalenceClass (
2411
2374
GenericSignatureBuilder &builder) const
2412
2375
-> EquivalenceClass * {
@@ -2542,7 +2505,9 @@ static void concretizeNestedTypeFromConcreteParent(
2542
2505
// If we don't already have a conformance of the parent to this protocol,
2543
2506
// add it now; it was elided earlier.
2544
2507
if (parentEquiv->conformsTo .count (proto) == 0 ) {
2545
- auto source = parentEquiv->concreteTypeConstraints .front ().source ;
2508
+ auto source = (!isSuperclassConstrained
2509
+ ? parentEquiv->concreteTypeConstraints .front ().source
2510
+ : parentEquiv->superclassConstraints .front ().source );
2546
2511
parentEquiv->recordConformanceConstraint (builder, parent, proto, source);
2547
2512
}
2548
2513
@@ -2572,7 +2537,7 @@ static void concretizeNestedTypeFromConcreteParent(
2572
2537
if (conformance.isConcrete ()) {
2573
2538
witnessType =
2574
2539
conformance.getConcrete ()->getTypeWitness (assocType);
2575
- if (!witnessType || witnessType-> hasError () )
2540
+ if (!witnessType)
2576
2541
return ; // FIXME: should we delay here?
2577
2542
} else if (auto archetype = concreteParent->getAs <ArchetypeType>()) {
2578
2543
witnessType = archetype->getNestedType (assocType->getName ());
@@ -2637,20 +2602,11 @@ PotentialArchetype *PotentialArchetype::updateNestedTypeForConformance(
2637
2602
2638
2603
// If we have a potential archetype that requires more processing, do so now.
2639
2604
if (shouldUpdatePA) {
2640
- // If there's a superclass constraint that conforms to the protocol,
2641
- // add the appropriate same-type relationship.
2642
- const auto proto = assocType->getProtocol ();
2643
- if (proto) {
2644
- if (auto superSource = builder.resolveSuperConformance (this , proto)) {
2645
- maybeAddSameTypeRequirementForNestedType (resultPA, superSource,
2646
- builder);
2647
- }
2648
- }
2649
-
2650
2605
// We know something concrete about the parent PA, so we need to propagate
2651
2606
// that information to this new archetype.
2652
- if (isConcreteType ()) {
2653
- concretizeNestedTypeFromConcreteParent (this , resultPA, builder);
2607
+ if (auto equivClass = getEquivalenceClassIfPresent ()) {
2608
+ if (equivClass->concreteType || equivClass->superclass )
2609
+ concretizeNestedTypeFromConcreteParent (this , resultPA, builder);
2654
2610
}
2655
2611
}
2656
2612
@@ -3585,50 +3541,29 @@ static Type getStructuralType(TypeDecl *typeDecl, bool keepSugar) {
3585
3541
return typeDecl->getDeclaredInterfaceType ();
3586
3542
}
3587
3543
3588
- static Type substituteConcreteType (GenericSignatureBuilder &builder,
3589
- PotentialArchetype *basePA,
3544
+ static Type substituteConcreteType (Type parentType,
3590
3545
TypeDecl *concreteDecl) {
3546
+ if (parentType->is <ErrorType>())
3547
+ return parentType;
3548
+
3591
3549
assert (concreteDecl);
3592
3550
3593
3551
auto *dc = concreteDecl->getDeclContext ();
3594
- auto *proto = dc->getSelfProtocolDecl ();
3595
3552
3596
3553
// Form an unsubstituted type referring to the given type declaration,
3597
3554
// for use in an inferred same-type requirement.
3598
3555
auto type = getStructuralType (concreteDecl, /* keepSugar=*/ true );
3599
3556
3600
- SubstitutionMap subMap;
3601
- if (proto) {
3602
- // Substitute in the type of the current PotentialArchetype in
3603
- // place of 'Self' here.
3604
- auto parentType = basePA->getDependentType (builder.getGenericParams ());
3605
-
3606
- subMap = SubstitutionMap::getProtocolSubstitutions (
3607
- proto, parentType, ProtocolConformanceRef (proto));
3608
- } else {
3609
- // Substitute in the superclass type.
3610
- auto parentPA = basePA->getEquivalenceClassIfPresent ();
3611
- auto parentType =
3612
- parentPA->concreteType ? parentPA->concreteType : parentPA->superclass ;
3613
- auto parentDecl = parentType->getAnyNominal ();
3614
-
3615
- subMap = parentType->getContextSubstitutionMap (
3616
- parentDecl->getParentModule (), dc);
3617
- }
3557
+ auto subMap = parentType->getContextSubstitutionMap (
3558
+ dc->getParentModule (), dc);
3618
3559
3619
3560
return type.subst (subMap);
3620
- };
3561
+ }
3621
3562
3622
3563
ResolvedType GenericSignatureBuilder::maybeResolveEquivalenceClass (
3623
3564
Type type,
3624
3565
ArchetypeResolutionKind resolutionKind,
3625
3566
bool wantExactPotentialArchetype) {
3626
- // An error type is best modeled as an unresolved potential archetype, since
3627
- // there's no way to be sure what it is actually meant to be.
3628
- if (type->is <ErrorType>()) {
3629
- return ResolvedType::forUnresolved (nullptr );
3630
- }
3631
-
3632
3567
// The equivalence class of a generic type is known directly.
3633
3568
if (auto genericParam = type->getAs <GenericTypeParamType>()) {
3634
3569
unsigned index = GenericParamKey (genericParam).findIndexIn (
@@ -3650,8 +3585,11 @@ ResolvedType GenericSignatureBuilder::maybeResolveEquivalenceClass(
3650
3585
wantExactPotentialArchetype);
3651
3586
if (!resolvedBase) return resolvedBase;
3652
3587
// If the base is concrete, so is this member.
3653
- if (resolvedBase.getAsConcreteType ())
3654
- return ResolvedType::forConcrete (type);
3588
+ if (auto parentType = resolvedBase.getAsConcreteType ()) {
3589
+ auto concreteType = substituteConcreteType (parentType,
3590
+ depMemTy->getAssocType ());
3591
+ return ResolvedType::forConcrete (concreteType);
3592
+ }
3655
3593
3656
3594
// Find the nested type declaration for this.
3657
3595
auto baseEquivClass = resolvedBase.getEquivalenceClass (*this );
@@ -3668,59 +3606,84 @@ ResolvedType GenericSignatureBuilder::maybeResolveEquivalenceClass(
3668
3606
basePA = baseEquivClass->members .front ();
3669
3607
}
3670
3608
3671
- AssociatedTypeDecl *nestedTypeDecl = nullptr ;
3672
3609
if (auto assocType = depMemTy->getAssocType ()) {
3673
3610
// Check whether this associated type references a protocol to which
3674
- // the base conforms. If not, it's unresolved.
3675
- if (baseEquivClass->conformsTo .find (assocType->getProtocol ())
3611
+ // the base conforms. If not, it's either concrete or unresolved.
3612
+ auto *proto = assocType->getProtocol ();
3613
+ if (baseEquivClass->conformsTo .find (proto)
3676
3614
== baseEquivClass->conformsTo .end ()) {
3677
- if (!baseEquivClass->concreteType ||
3678
- !lookupConformance (type->getCanonicalType (),
3679
- baseEquivClass->concreteType ,
3680
- assocType->getProtocol ())) {
3615
+ if (baseEquivClass->concreteType &&
3616
+ lookupConformance (type->getCanonicalType (),
3617
+ baseEquivClass->concreteType ,
3618
+ proto)) {
3619
+ // Fall through
3620
+ } else if (baseEquivClass->superclass &&
3621
+ lookupConformance (type->getCanonicalType (),
3622
+ baseEquivClass->superclass ,
3623
+ proto)) {
3624
+ // Fall through
3625
+ } else {
3681
3626
return ResolvedType::forUnresolved (baseEquivClass);
3682
3627
}
3628
+
3629
+ // FIXME: Instead of falling through, we ought to return a concrete
3630
+ // type here, but then we fail to update a nested PotentialArchetype
3631
+ // if one happens to already exist. It would be cleaner if concrete
3632
+ // types never had nested PotentialArchetypes.
3683
3633
}
3684
3634
3685
- nestedTypeDecl = assocType;
3635
+ auto nestedPA =
3636
+ basePA->updateNestedTypeForConformance (*this , assocType,
3637
+ resolutionKind);
3638
+ if (!nestedPA)
3639
+ return ResolvedType::forUnresolved (baseEquivClass);
3640
+
3641
+ // If base resolved to the anchor, then the nested potential archetype
3642
+ // we found is the resolved potential archetype. Return it directly,
3643
+ // so it doesn't need to be resolved again.
3644
+ if (basePA == resolvedBase.getPotentialArchetypeIfKnown ())
3645
+ return ResolvedType (nestedPA);
3646
+
3647
+ // Compute the resolved dependent type to return.
3648
+ Type resolvedBaseType = resolvedBase.getDependentType (*this );
3649
+ Type resolvedMemberType =
3650
+ DependentMemberType::get (resolvedBaseType, assocType);
3651
+
3652
+ return ResolvedType (resolvedMemberType,
3653
+ nestedPA->getOrCreateEquivalenceClass (*this ));
3686
3654
} else {
3687
- auto *typeAlias =
3655
+ auto *concreteDecl =
3688
3656
baseEquivClass->lookupNestedType (*this , depMemTy->getName ());
3689
3657
3690
- if (!typeAlias )
3658
+ if (!concreteDecl )
3691
3659
return ResolvedType::forUnresolved (baseEquivClass);
3692
3660
3693
- auto type = substituteConcreteType (*this , basePA, typeAlias);
3694
- return maybeResolveEquivalenceClass (type, resolutionKind,
3695
- wantExactPotentialArchetype);
3696
- }
3661
+ Type parentType;
3662
+ auto *proto = concreteDecl->getDeclContext ()->getSelfProtocolDecl ();
3663
+ if (!proto) {
3664
+ parentType = (baseEquivClass->concreteType
3665
+ ? baseEquivClass->concreteType
3666
+ : baseEquivClass->superclass );
3667
+ } else {
3668
+ if (baseEquivClass->concreteType &&
3669
+ lookupConformance (type->getCanonicalType (),
3670
+ baseEquivClass->concreteType ,
3671
+ proto)) {
3672
+ parentType = baseEquivClass->concreteType ;
3673
+ } else if (baseEquivClass->superclass &&
3674
+ lookupConformance (type->getCanonicalType (),
3675
+ baseEquivClass->superclass ,
3676
+ proto)) {
3677
+ parentType = baseEquivClass->superclass ;
3678
+ } else {
3679
+ parentType = basePA->getDependentType (getGenericParams ());
3680
+ }
3681
+ }
3697
3682
3698
- auto nestedPA =
3699
- basePA->updateNestedTypeForConformance (*this , nestedTypeDecl,
3700
- resolutionKind);
3701
- if (!nestedPA)
3702
- return ResolvedType::forUnresolved (baseEquivClass);
3703
-
3704
- // If base resolved to the anchor, then the nested potential archetype
3705
- // we found is the resolved potential archetype. Return it directly,
3706
- // so it doesn't need to be resolved again.
3707
- if (basePA == resolvedBase.getPotentialArchetypeIfKnown ())
3708
- return ResolvedType (nestedPA);
3709
-
3710
- // Compute the resolved dependent type to return.
3711
- Type resolvedBaseType = resolvedBase.getDependentType (*this );
3712
- Type resolvedMemberType;
3713
- if (auto assocType = dyn_cast<AssociatedTypeDecl>(nestedTypeDecl)) {
3714
- resolvedMemberType =
3715
- DependentMemberType::get (resolvedBaseType, assocType);
3716
- } else {
3717
- // Note: strange case that might not even really be dependent.
3718
- resolvedMemberType =
3719
- DependentMemberType::get (resolvedBaseType, depMemTy->getName ());
3683
+ auto concreteType = substituteConcreteType (parentType, concreteDecl);
3684
+ return maybeResolveEquivalenceClass (concreteType, resolutionKind,
3685
+ wantExactPotentialArchetype);
3720
3686
}
3721
-
3722
- return ResolvedType (resolvedMemberType,
3723
- nestedPA->getOrCreateEquivalenceClass (*this ));
3724
3687
}
3725
3688
3726
3689
// If it's not a type parameter, it won't directly resolve to one.
@@ -5523,7 +5486,8 @@ GenericSignatureBuilder::finalize(SourceLoc loc,
5523
5486
// Don't allow a generic parameter to be equivalent to a concrete type,
5524
5487
// because then we don't actually have a parameter.
5525
5488
auto equivClass = rep->getOrCreateEquivalenceClass (*this );
5526
- if (equivClass->concreteType ) {
5489
+ if (equivClass->concreteType &&
5490
+ !equivClass->concreteType ->is <ErrorType>()) {
5527
5491
if (auto constraint = equivClass->findAnyConcreteConstraintAsWritten ()){
5528
5492
Impl->HadAnyError = true ;
5529
5493
0 commit comments