Skip to content

Commit 75181f9

Browse files
authored
Merge pull request #81182 from slavapestov/fix-issue-79763-6.2
[6.2] AST: Fix existential erasure of long member types
2 parents ec7ed9a + 9bb6673 commit 75181f9

File tree

5 files changed

+54
-24
lines changed

5 files changed

+54
-24
lines changed

include/swift/AST/SubstitutionMap.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,6 @@ struct OuterSubstitutions {
340340
SubstitutionMap subs;
341341
unsigned depth;
342342

343-
bool isUnsubstitutedTypeParameter(Type type) const;
344343
Type operator()(SubstitutableType *type) const;
345344
ProtocolConformanceRef operator()(CanType dependentType,
346345
Type conformingReplacementType,

lib/AST/GenericEnvironment.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -317,9 +317,13 @@ GenericEnvironment::maybeApplyOuterContextSubstitutions(Type type) const {
317317
case Kind::OpenedExistential:
318318
case Kind::OpenedElement:
319319
case Kind::Opaque: {
320-
OuterSubstitutions replacer{
321-
getOuterSubstitutions(), getGenericSignature()->getMaxDepth()};
322-
return type.subst(replacer, replacer);
320+
if (auto subs = getOuterSubstitutions()) {
321+
OuterSubstitutions replacer{subs,
322+
getGenericSignature()->getMaxDepth()};
323+
return type.subst(replacer, replacer);
324+
}
325+
326+
return type;
323327
}
324328
}
325329
}

lib/AST/SubstitutionMap.cpp

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -669,21 +669,8 @@ SubstitutionMap SubstitutionMap::mapIntoTypeExpansionContext(
669669
SubstFlags::PreservePackExpansionLevel);
670670
}
671671

672-
bool OuterSubstitutions::isUnsubstitutedTypeParameter(Type type) const {
673-
if (!type->isTypeParameter())
674-
return false;
675-
676-
if (auto depMemTy = type->getAs<DependentMemberType>())
677-
return isUnsubstitutedTypeParameter(depMemTy->getBase());
678-
679-
if (auto genericParam = type->getAs<GenericTypeParamType>())
680-
return genericParam->getDepth() >= depth;
681-
682-
return false;
683-
}
684-
685672
Type OuterSubstitutions::operator()(SubstitutableType *type) const {
686-
if (isUnsubstitutedTypeParameter(type))
673+
if (cast<GenericTypeParamType>(type)->getDepth() >= depth)
687674
return Type(type);
688675

689676
return QuerySubstitutionMap{subs}(type);
@@ -693,9 +680,23 @@ ProtocolConformanceRef OuterSubstitutions::operator()(
693680
CanType dependentType,
694681
Type conformingReplacementType,
695682
ProtocolDecl *conformedProtocol) const {
696-
if (isUnsubstitutedTypeParameter(dependentType))
697-
return ProtocolConformanceRef::forAbstract(
683+
auto sig = subs.getGenericSignature();
684+
if (!sig->isValidTypeParameter(dependentType) ||
685+
!sig->requiresProtocol(dependentType, conformedProtocol)) {
686+
// FIXME: We need the isValidTypeParameter() check instead of just looking
687+
// at the root generic parameter because in the case of an existential
688+
// environment, the reduced type of a member type of Self might be an outer
689+
// type parameter that is not formed from the outer generic signature's
690+
// conformance requirements. Ideally, we'd either add these supplementary
691+
// conformance requirements to the generalization signature, or we would
692+
// store the supplementary conformances directly in the generic environment
693+
// somehow.
694+
//
695+
// Once we check for that and handle it properly, the lookupConformance()
696+
// can become a forAbstract().
697+
return swift::lookupConformance(
698698
conformingReplacementType, conformedProtocol);
699+
}
699700

700701
return LookUpConformanceInSubstitutionMap(subs)(
701702
dependentType, conformingReplacementType, conformedProtocol);

lib/Sema/OpenedExistentials.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -823,10 +823,11 @@ Type swift::typeEraseOpenedExistentialReference(
823823

824824
auto applyOuterSubstitutions = [&](Type t) -> Type {
825825
if (t->hasTypeParameter()) {
826-
auto outerSubs = existentialSig.Generalization;
827-
unsigned depth = existentialSig.OpenedSig->getMaxDepth();
828-
OuterSubstitutions replacer{outerSubs, depth};
829-
return t.subst(replacer, replacer);
826+
if (auto outerSubs = existentialSig.Generalization) {
827+
unsigned depth = existentialSig.OpenedSig->getMaxDepth();
828+
OuterSubstitutions replacer{outerSubs, depth};
829+
return t.subst(replacer, replacer);
830+
}
830831
}
831832

832833
return t;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %target-swift-emit-silgen %s
2+
3+
protocol N {
4+
associatedtype A: N
5+
}
6+
7+
protocol P<A> {
8+
associatedtype A: N
9+
associatedtype B
10+
11+
func f0(_: A) -> B
12+
func f1(_: A.A) -> B
13+
func f2(_: A.A.A) -> B
14+
}
15+
16+
struct G<T>: N {
17+
typealias A = G<G<T>>
18+
}
19+
20+
func call(x: any P<G<Int>>) -> (Any, Any, Any) {
21+
let y0 = x.f0(G<Int>())
22+
let y1 = x.f1(G<G<Int>>())
23+
let y2 = x.f2(G<G<G<Int>>>())
24+
return (y0, y1, y2)
25+
}

0 commit comments

Comments
 (0)