Skip to content

Commit 12a5243

Browse files
authored
Merge pull request #31836 from slavapestov/gsb-superclass-nested-type-5.3
GSB: Concretize nested types when adding a superclass constraint [5.3]
2 parents 83697ed + d48e50f commit 12a5243

File tree

3 files changed

+53
-5
lines changed

3 files changed

+53
-5
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2522,7 +2522,13 @@ static void concretizeNestedTypeFromConcreteParent(
25222522
GenericSignatureBuilder &builder) {
25232523
auto parentEquiv = parent->getEquivalenceClassIfPresent();
25242524
assert(parentEquiv && "can't have a concrete type without an equiv class");
2525+
2526+
bool isSuperclassConstrained = false;
25252527
auto concreteParent = parentEquiv->concreteType;
2528+
if (!concreteParent) {
2529+
isSuperclassConstrained = true;
2530+
concreteParent = parentEquiv->superclass;
2531+
}
25262532
assert(concreteParent &&
25272533
"attempting to resolve concrete nested type of non-concrete PA");
25282534

@@ -2544,8 +2550,14 @@ static void concretizeNestedTypeFromConcreteParent(
25442550
"No conformance requirement");
25452551
const RequirementSource *parentConcreteSource = nullptr;
25462552
for (const auto &constraint : parentEquiv->conformsTo.find(proto)->second) {
2547-
if (constraint.source->kind == RequirementSource::Concrete) {
2548-
parentConcreteSource = constraint.source;
2553+
if (!isSuperclassConstrained) {
2554+
if (constraint.source->kind == RequirementSource::Concrete) {
2555+
parentConcreteSource = constraint.source;
2556+
}
2557+
} else {
2558+
if (constraint.source->kind == RequirementSource::Superclass) {
2559+
parentConcreteSource = constraint.source;
2560+
}
25492561
}
25502562
}
25512563

@@ -4264,6 +4276,15 @@ bool GenericSignatureBuilder::updateSuperclass(
42644276
for (const auto &conforms : equivClass->conformsTo) {
42654277
(void)resolveSuperConformance(type, conforms.first);
42664278
}
4279+
4280+
// Eagerly resolve any existing nested types to their concrete forms (others
4281+
// will be "concretized" as they are constructed, in getNestedType).
4282+
for (auto equivT : equivClass->members) {
4283+
for (auto nested : equivT->getNestedTypes()) {
4284+
concretizeNestedTypeFromConcreteParent(equivT, nested.second.front(),
4285+
*this);
4286+
}
4287+
}
42674288
};
42684289

42694290
// If we haven't yet recorded a superclass constraint for this equivalence
@@ -7156,6 +7177,12 @@ void GenericSignatureBuilder::dump(llvm::raw_ostream &out) {
71567177
pa->dump(out, &Context.SourceMgr, 2);
71577178
}
71587179
out << "\n";
7180+
7181+
out << "Equivalence classes:\n";
7182+
for (auto &equiv : Impl->EquivalenceClasses) {
7183+
equiv.dump(out, this);
7184+
}
7185+
out << "\n";
71597186
}
71607187

71617188
void GenericSignatureBuilder::addGenericSignature(GenericSignature sig) {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
// rdar://problem/39481178 - Introducing a superclass constraint does not add
4+
// same-type constraints on nested types
5+
6+
protocol P {
7+
associatedtype Q
8+
}
9+
10+
class C : P {
11+
typealias Q = Int
12+
}
13+
14+
// Use the "generic parameter cannot be concrete" check as a proxy for the
15+
// same-type constraint 'T == C.Q (aka Int)' having been inferred:
16+
17+
extension P {
18+
func f1<T>(_: T) where T == Q, Self : C {}
19+
// expected-error@-1 {{same-type requirement makes generic parameter 'T' non-generic}}
20+
21+
func f2<T>(_: T) where Self : C, T == Q {}
22+
// expected-error@-1 {{same-type requirement makes generic parameter 'T' non-generic}}
23+
}

validation-test/compiler_crashers_2/sr11232.swift renamed to validation-test/compiler_crashers_2_fixed/sr11232.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
// RUN: not --crash %target-swift-emit-silgen %s
2-
3-
// REQUIRES: asserts
1+
// RUN: not %target-swift-emit-silgen %s
42

53
protocol Pub {
64
associatedtype Other

0 commit comments

Comments
 (0)