Skip to content

Commit 3b03a5e

Browse files
committed
AST: Work around shortcoming in abstract conformance representation when computing override substitutions
Fixes rdar://problem/98404650.
1 parent e22fc3e commit 3b03a5e

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

lib/AST/SubstitutionMap.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -534,10 +534,25 @@ OverrideSubsInfo::OverrideSubsInfo(const NominalTypeDecl *baseNominal,
534534
if (auto baseNominalSig = baseNominal->getGenericSignature()) {
535535
BaseDepth = baseNominalSig.getGenericParams().back()->getDepth() + 1;
536536

537+
auto *genericEnv = derivedNominal->getGenericEnvironment();
537538
auto derivedNominalTy = derivedNominal->getDeclaredInterfaceType();
539+
540+
// FIXME: Map in and out of context to get more accurate
541+
// conformance information. If the base generic signature
542+
// is <T: P> and the derived generic signature is <T: C>
543+
// where C is a class that conforms to P, then we want the
544+
// substitution map to store the concrete conformance C: P
545+
// and not the abstract conformance T: P.
546+
if (genericEnv) {
547+
derivedNominalTy = genericEnv->mapTypeIntoContext(
548+
derivedNominalTy);
549+
}
550+
538551
BaseSubMap = derivedNominalTy->getContextSubstitutionMap(
539-
baseNominal->getParentModule(), baseNominal);
540-
assert(!BaseSubMap.hasArchetypes());
552+
baseNominal->getParentModule(), baseNominal,
553+
genericEnv);
554+
555+
BaseSubMap = BaseSubMap.mapReplacementTypesOutOfContext();
541556
}
542557

543558
if (auto derivedNominalSig = derivedNominal->getGenericSignature())
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
2+
3+
class Base<T: P> {
4+
init(x: Int = 0) {}
5+
}
6+
7+
class Derived<T: C> : Base<T> {}
8+
9+
protocol P {}
10+
class C: P {}
11+
12+
_ = Derived<C>()
13+
14+
// CHECK-LABEL: sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
15+
// CHECK: [[FN:%.*]] = function_ref @$s35default_arguments_inherited_generic4BaseC1xACyxGSi_tcfcfA_ : $@convention(thin) <τ_0_0 where τ_0_0 : P> () -> Int
16+
// CHECK: apply [[FN]]<C>() : $@convention(thin) <τ_0_0 where τ_0_0 : P> () -> Int

0 commit comments

Comments
 (0)