Files
swift-mirror/test/SILOptimizer/devirt_class_witness_method_generic.swift
Slava Pestov ed4e8d65f0 SILOptimizer: Fix invariant violation in getWitnessMethodSubstitutions() with class witness methods
Witness thunks where the conforming type is a class and the witness is in a
protocol extension have an extra generic parameter constrained to the class
type that is passed as the 'Self' parameter for the protocol extension
method.

This means the substitution map for the devirtualized call must be
assembled from three sources:

- The 'Self' substitution
- The generic parameters of the concrete conforming type, if any
- The generic parameters of the protocol requirement, if any

This was previously done by making two calls to combineSubstitutionMaps(),
the first call combined the first two maps and the second call combined the
result of the first call with the third map.

Unfortunately, both calls were made with the generic signature of the
witness thunk, and the result of combining the first two substitution maps
does not provide sufficient replacements for all generic parameters and
conformance requirements in the witness thunk's signature.

This was apparently fine with the GenericSignatureBuilder, but the
Requirement Machine flags the missing generic parameters in assert builds.

Fixes https://github.com/apple/swift/issues/59193.
2022-06-14 13:57:20 -04:00

24 lines
1015 B
Swift

// RUN: %target-swift-frontend -emit-sil -O %s | %FileCheck %s
public protocol P {}
public protocol Q {
func foo<T: P>(t: T)
func bar<T: P>(t: T)
}
extension Q {
@inline(__always)
public func foo<T: P>(t: T) {
bar(t: t)
}
@_optimize(none)
public func bar<T: P>(t: T) {}
}
public class C<T>: Q {}
// CHECK-LABEL: sil shared [transparent] [thunk] @$s35devirt_class_witness_method_generic1CCyqd__GAA1QA2aEP3bar1tyqd___tAA1PRd__lFTW : $@convention(witness_method: Q) <τ_0_0><τ_1_0 where τ_0_0 : C<τ_1_0>><τ_2_0 where τ_2_0 : P> (@in_guaranteed τ_2_0, @in_guaranteed τ_0_0) -> () {
// CHECK: [[FN:%.*]] = function_ref @$s35devirt_class_witness_method_generic1QPAAE3bar1tyqd___tAA1PRd__lF : $@convention(method) <τ_0_0 where τ_0_0 : Q><τ_1_0 where τ_1_0 : P> (@in_guaranteed τ_1_0, @in_guaranteed τ_0_0) -> ()
// CHECK: apply [[FN]]<τ_0_0, τ_2_0>(%0, %1) : $@convention(method) <τ_0_0 where τ_0_0 : Q><τ_1_0 where τ_1_0 : P> (@in_guaranteed τ_1_0, @in_guaranteed τ_0_0) -> ()