Skip to content

Commit ce550f2

Browse files
committed
AST: Try harder to preserve type sugar in AbstractGenericSignatureRequest
AbstractGenericSignatureRequest tries to minimize the number of GSBs that we spin up by only creating a GSB if the generic parameter and requirement types are canonical. If they're not canonical, it first canonicalizes them, then kicks off a request to compute the canonical signature, and finally, re-applies type sugar. We would do this by building a mapping for re-sugaring generic parameters, however this mapping was only populated for the newly-added generic parameters. If some of the newly-added generic requirements mention the base signature's generic parameters, they would remain canonicalized. Fixes <rdar://problem/67579220>.
1 parent a350fb7 commit ce550f2

File tree

3 files changed

+9
-11
lines changed

3 files changed

+9
-11
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7430,13 +7430,11 @@ AbstractGenericSignatureRequest::evaluate(
74307430
if (baseSignature)
74317431
canBaseSignature = baseSignature->getCanonicalSignature();
74327432

7433-
llvm::SmallDenseMap<GenericTypeParamType *, Type> mappedTypeParameters;
74347433
SmallVector<GenericTypeParamType *, 2> canAddedParameters;
74357434
canAddedParameters.reserve(addedParameters.size());
74367435
for (auto gp : addedParameters) {
74377436
auto canGP = gp->getCanonicalType()->castTo<GenericTypeParamType>();
74387437
canAddedParameters.push_back(canGP);
7439-
mappedTypeParameters[canGP] = Type(gp);
74407438
}
74417439

74427440
SmallVector<Requirement, 2> canAddedRequirements;
@@ -7453,10 +7451,8 @@ AbstractGenericSignatureRequest::evaluate(
74537451
if (!canSignatureResult || !*canSignatureResult)
74547452
return GenericSignature();
74557453

7456-
// Substitute in the original generic parameters to form a more-sugared
7457-
// result closer to what the original request wanted. Note that this
7458-
// loses sugar on concrete types, but for abstract signatures that
7459-
// shouldn't matter.
7454+
// Substitute in the original generic parameters to form the sugared
7455+
// result the original request wanted.
74607456
auto canSignature = *canSignatureResult;
74617457
SmallVector<GenericTypeParamType *, 2> resugaredParameters;
74627458
resugaredParameters.reserve(canSignature->getGenericParams().size());
@@ -7474,9 +7470,8 @@ AbstractGenericSignatureRequest::evaluate(
74747470
auto resugaredReq = req.subst(
74757471
[&](SubstitutableType *type) {
74767472
if (auto gp = dyn_cast<GenericTypeParamType>(type)) {
7477-
auto knownGP = mappedTypeParameters.find(gp);
7478-
if (knownGP != mappedTypeParameters.end())
7479-
return knownGP->second;
7473+
unsigned ordinal = canSignature->getGenericParamOrdinal(gp);
7474+
return Type(resugaredParameters[ordinal]);
74807475
}
74817476
return Type(type);
74827477
},

test/ModuleInterface/inherited-generic-parameters.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ public class Base<In, Out> {
1919
// CHECK-NEXT: public init<A>(_: A, _: A)
2020
public init<A>(_: A, _: A) {}
2121

22+
// CHECK-NEXT: public init<C>(_: C) where C : main.Base<In, Out>
23+
public init<C>(_: C) where C : Base<In, Out> {}
2224
// CHECK: }
2325
}
2426

@@ -27,6 +29,7 @@ public class Derived<T> : Base<T, T> {
2729
// CHECK-NEXT: {{(@objc )?}}deinit
2830
// CHECK-NEXT: override public init(x: @escaping (T) -> T)
2931
// CHECK-NEXT: override public init<A>(_ argument: A, _ argument: A)
32+
// CHECK-NEXT: override public init<C>(_ argument: C) where C : main.Base<T, T>
3033
// CHECK-NEXT: }
3134
}
3235

test/attr/attr_override.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ class SR_4206_Base_7<T> {
590590
}
591591

592592
class SR_4206_Derived_7<T>: SR_4206_Base_7<T> {
593-
override func foo1() where T: SR_4206_Protocol_2 {} // expected-error {{overridden method 'foo1' has generic signature <T where T : SR_4206_Protocol_2> which is incompatible with base method's generic signature <T where T : SR_4206_Protocol_1>; expected generic signature to be <T where τ_0_0 : SR_4206_Protocol_1>}}
593+
override func foo1() where T: SR_4206_Protocol_2 {} // expected-error {{overridden method 'foo1' has generic signature <T where T : SR_4206_Protocol_2> which is incompatible with base method's generic signature <T where T : SR_4206_Protocol_1>; expected generic signature to be <T where T : SR_4206_Protocol_1>}}
594594

595595
override func foo2() {} // OK
596596
}
@@ -627,7 +627,7 @@ class SR_4206_Base_10<T> {
627627
func foo() where T: SR_4206_Protocol_1 {} // expected-note {{overridden declaration is here}}
628628
}
629629
class SR_4206_Derived_10<T, U>: SR_4206_Base_10<T> {
630-
override func foo() where U: SR_4206_Protocol_1 {} // expected-error {{overridden method 'foo' has generic signature <T, U where U : SR_4206_Protocol_1> which is incompatible with base method's generic signature <T where T : SR_4206_Protocol_1>; expected generic signature to be <T, U where τ_0_0 : SR_4206_Protocol_1>}}
630+
override func foo() where U: SR_4206_Protocol_1 {} // expected-error {{overridden method 'foo' has generic signature <T, U where U : SR_4206_Protocol_1> which is incompatible with base method's generic signature <T where T : SR_4206_Protocol_1>; expected generic signature to be <T, U where T : SR_4206_Protocol_1>}}
631631
}
632632

633633
// Override with return type specialization

0 commit comments

Comments
 (0)