Skip to content

[4.2] [SILGen] Ensure type params in witness method conformances match the witness method signatures. #16514

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions lib/SILGen/SILGenType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,20 @@ SILFunction *SILGenModule::emitProtocolWitness(
auto input = reqtOrigTy->getInput().subst(reqtSubMap)->getCanonicalType();
auto result = reqtOrigTy->getResult().subst(reqtSubMap)->getCanonicalType();

// If there's something to map to for the witness thunk, the conformance
// should be phrased in the same terms. This particularly applies to classes
// where a thunk for a method in a conformance like `extension Class: P where
// T: Q` will go from its native signature of `<τ_0_0 where τ_0_0: Q>` (with T
// canonicalised to τ_0_0), to `<τ_0_0, τ_1_0 where τ_0_0: Class<τ_1_0>,
// τ_1_0: Q>` (with T now represented by τ_1_0). Find the right conformance by
// looking for the conformance of 'Self'.
if (!reqtSubMap.empty()) {
auto requirement = conformance.getRequirement();
auto self = requirement->getProtocolSelfType()->getCanonicalType();

conformance = *reqtSubMap.lookupConformance(self, requirement);
}

CanAnyFunctionType reqtSubstTy;
if (genericEnv) {
auto *genericSig = genericEnv->getGenericSignature();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// RUN: %target-swift-frontend -emit-ir %s -module-name x | %FileCheck %s

// rdar://problem/40078863 - witness signatures get adjusted and the
// ProtocolConformances accompanying them did not, resulting in an extra witness
// table parameter.

protocol Foo {
func bar()
}
extension Foo {
func bar() {}
}
class Box<T> {}
extension Box: Foo where T: Foo {}
// CHECK-LABEL: define internal swiftcc void @"$S1x3BoxCyqd__GAA3FooA2aEP3baryyFTW"(%T1x3BoxC.0** noalias nocapture swiftself dereferenceable({{[48]}}), %swift.type* %Self, i8** %SelfWitnessTable)
4 changes: 2 additions & 2 deletions test/SILGen/witnesses_class.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class UsesDefaults<X : Barable> : HasDefaults {}

// Covariant Self:

// CHECK-LABEL: sil private [transparent] [thunk] @$S15witnesses_class12UsesDefaultsCyxGAA03HasD0A2aEP10hasDefaultyyFTW : $@convention(witness_method: HasDefaults) <τ_0_0><τ_1_0 where τ_0_0 : UsesDefaults<τ_1_0>, τ_1_0 : Barable> (@in_guaranteed τ_0_0) -> ()
// CHECK-LABEL: sil private [transparent] [thunk] @$S15witnesses_class12UsesDefaultsCyqd__GAA03HasD0A2aEP10hasDefaultyyFTW : $@convention(witness_method: HasDefaults) <τ_0_0><τ_1_0 where τ_0_0 : UsesDefaults<τ_1_0>, τ_1_0 : Barable> (@in_guaranteed τ_0_0) -> () {
// CHECK: [[FN:%.*]] = function_ref @$S15witnesses_class11HasDefaultsPAAE10hasDefaultyyF : $@convention(method) <τ_0_0 where τ_0_0 : HasDefaults> (@in_guaranteed τ_0_0) -> ()
// CHECK: apply [[FN]]<τ_0_0>(
// CHECK: return
Expand All @@ -91,7 +91,7 @@ class UsesDefaults<X : Barable> : HasDefaults {}

// Covariant Self:

// CHECK-LABEL: sil private [transparent] [thunk] @$S15witnesses_class12UsesDefaultsCyxGAA03HasD0A2aEP17hasDefaultGenericyyqd__AA7FooableRd__lFTW : $@convention(witness_method: HasDefaults) <τ_0_0><τ_1_0 where τ_0_0 : UsesDefaults<τ_1_0>, τ_1_0 : Barable><τ_2_0 where τ_2_0 : Fooable> (@guaranteed τ_2_0, @in_guaranteed τ_0_0) -> ()
// CHECK-LABEL: sil private [transparent] [thunk] @$S15witnesses_class12UsesDefaultsCyqd__GAA03HasD0A2aEP17hasDefaultGenericyyqd__AA7FooableRd__lFTW : $@convention(witness_method: HasDefaults) <τ_0_0><τ_1_0 where τ_0_0 : UsesDefaults<τ_1_0>, τ_1_0 : Barable><τ_2_0 where τ_2_0 : Fooable> (@guaranteed τ_2_0, @in_guaranteed τ_0_0) -> () {
// CHECK: [[FN:%.*]] = function_ref @$S15witnesses_class11HasDefaultsPAAE17hasDefaultGenericyyqd__AA7FooableRd__lF : $@convention(method) <τ_0_0 where τ_0_0 : HasDefaults><τ_1_0 where τ_1_0 : Fooable> (@guaranteed τ_1_0, @in_guaranteed τ_0_0) -> ()
// CHECK: apply [[FN]]<τ_0_0, τ_2_0>(
// CHECK: return
Expand Down