Skip to content

Commit 4b2bb8f

Browse files
committed
SIL: Simpler and more correct TypeLowering::getConstantOverrideInfo()
We can use the new adjustSuperclassMemberDeclType() method here to eliminate some code duplication and fix some corner cases with generic method overrides. Fixes <rdar://problem/18560464>, <https://bugs.swift.org/browse/SR-2427>, <https://bugs.swift.org/browse/SR-2721>.
1 parent dec05e1 commit 4b2bb8f

File tree

3 files changed

+59
-21
lines changed

3 files changed

+59
-21
lines changed

lib/SIL/SILFunctionType.cpp

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,10 +2041,14 @@ SILConstantInfo TypeConverter::getConstantOverrideInfo(SILDeclRef derived,
20412041
auto selfInterfaceTy = derivedInterfaceTy.getInput()->getRValueInstanceType();
20422042

20432043
auto overrideInterfaceTy =
2044-
selfInterfaceTy->getTypeOfMember(M.getSwiftModule(), baseInterfaceTy,
2045-
base.getDecl()->getDeclContext());
2046-
2047-
// Copy generic signature from derived to the override type
2044+
selfInterfaceTy->adjustSuperclassMemberDeclType(
2045+
derived.getDecl(), base.getDecl(), baseInterfaceTy,
2046+
/*resolver=*/nullptr);
2047+
2048+
// Copy generic signature from derived to the override type, to handle
2049+
// the case where the base member is not generic (because the base class
2050+
// is concrete) but the derived member is generic (because the derived
2051+
// class is generic).
20482052
if (auto derivedInterfaceFnTy = derivedInterfaceTy->getAs<GenericFunctionType>()) {
20492053
auto overrideInterfaceFnTy = overrideInterfaceTy->castTo<AnyFunctionType>();
20502054
overrideInterfaceTy =
@@ -2054,23 +2058,6 @@ SILConstantInfo TypeConverter::getConstantOverrideInfo(SILDeclRef derived,
20542058
overrideInterfaceFnTy->getExtInfo());
20552059
}
20562060

2057-
// Replace occurrences of 'Self' in the signature with the derived type.
2058-
// FIXME: these should all be modeled with a DynamicSelfType.
2059-
overrideInterfaceTy =
2060-
overrideInterfaceTy->replaceSelfParameterType(selfInterfaceTy);
2061-
2062-
bool hasDynamicSelf = false;
2063-
if (auto funcDecl = dyn_cast<FuncDecl>(derived.getDecl()))
2064-
hasDynamicSelf = funcDecl->hasDynamicSelf();
2065-
else if (isa<ConstructorDecl>(derived.getDecl()))
2066-
hasDynamicSelf = true;
2067-
2068-
if (hasDynamicSelf) {
2069-
overrideInterfaceTy =
2070-
overrideInterfaceTy->replaceCovariantResultType(selfInterfaceTy,
2071-
base.uncurryLevel + 1);
2072-
}
2073-
20742061
// Lower the formal AST type.
20752062
auto overrideLoweredInterfaceTy = getLoweredASTFunctionType(
20762063
cast<AnyFunctionType>(overrideInterfaceTy->getCanonicalType()),

test/SILGen/vtable_thunks_reabstraction.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,33 @@ class ConcreteOptional<X>: Opaque<S?> {
9292
override func variantOptionality(x: S??) -> S? { return x! }
9393
}
9494
*/
95+
96+
// Make sure we remap the method's innermost generic parameters
97+
// to the correct depth
98+
class GenericBase<T> {
99+
func doStuff<U>(t: T, u: U) {}
100+
init<U>(t: T, u: U) {}
101+
}
102+
103+
class ConcreteSub : GenericBase<Int> {
104+
override func doStuff<U>(t: Int, u: U) {
105+
super.doStuff(t: t, u: u)
106+
}
107+
override init<U>(t: Int, u: U) {
108+
super.init(t: t, u: u)
109+
}
110+
}
111+
112+
class ConcreteBase {
113+
init<U>(t: Int, u: U) {}
114+
func doStuff<U>(t: Int, u: U) {}
115+
}
116+
117+
class GenericSub<T> : ConcreteBase {
118+
override init<U>(t: Int, u: U) {
119+
super.init(t: t, u: u)
120+
}
121+
override func doStuff<U>(t: Int, u: U) {
122+
super.doStuff(t: t, u: u)
123+
}
124+
}

test/attr/attr_override.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,4 +380,25 @@ class MismatchOptional3 : MismatchOptionalBase {
380380
override func result() -> Optional<Int> { return nil } // expected-error {{cannot override instance method result type 'Int' with optional type 'Optional<Int>'}} {{none}}
381381
}
382382

383+
// Make sure we remap the method's innermost generic parameters
384+
// to the correct depth
385+
class GenericBase<T> {
386+
func doStuff<U>(t: T, u: U) {}
387+
init<U>(t: T, u: U) {}
388+
}
389+
390+
class ConcreteSub : GenericBase<Int> {
391+
override func doStuff<U>(t: Int, u: U) {}
392+
override init<U>(t: Int, u: U) {}
393+
}
394+
395+
class ConcreteBase {
396+
init<U>(t: Int, u: U) {}
397+
func doStuff<U>(t: Int, u: U) {}
383398

399+
}
400+
401+
class GenericSub<T> : ConcreteBase {
402+
override init<U>(t: Int, u: U) {}
403+
override func doStuff<U>(t: Int, u: U) {}
404+
}

0 commit comments

Comments
 (0)