diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp index 30a22793f675a..65406a30d9b46 100644 --- a/lib/SIL/SILFunctionType.cpp +++ b/lib/SIL/SILFunctionType.cpp @@ -765,9 +765,14 @@ static CanSILFunctionType getSILFunctionType(SILModule &M, for (auto capture : loweredCaptures.getCaptures()) { if (capture.isDynamicSelfMetadata()) { ParameterConvention convention = ParameterConvention::Direct_Unowned; + auto dynamicSelfInterfaceType = GenericEnvironment::mapTypeOutOfContext( + function->getGenericEnvironment(), + loweredCaptures.getDynamicSelfType()); + auto selfMetatype = MetatypeType::get( - loweredCaptures.getDynamicSelfType(), + dynamicSelfInterfaceType, MetatypeRepresentation::Thick); + auto canSelfMetatype = getCanonicalType(selfMetatype); SILParameterInfo param(canSelfMetatype, convention); inputs.push_back(param); diff --git a/test/SILGen/dynamic_self.swift b/test/SILGen/dynamic_self.swift index 6d8574d450f8d..ddd4d184f270c 100644 --- a/test/SILGen/dynamic_self.swift +++ b/test/SILGen/dynamic_self.swift @@ -363,6 +363,28 @@ class Derived : Base { } } +class Generic { + // Examples where we have to add a special argument to capture Self's metadata + func t1() -> Self { + // CHECK-LABEL: sil private @_T012dynamic_self7GenericC2t1ACyxGXDyFAEXDSgycfU_ : $@convention(thin) (@owned <τ_0_0> { var @sil_weak Optional> } , @thick @dynamic_self Generic.Type) -> @owned Optional> + _ = {[weak self] in self } + return self + } + + func t2() -> Self { + // CHECK-LABEL: sil private @_T012dynamic_self7GenericC2t2ACyxGXDyFAEXD_AEXDtycfU_ : $@convention(thin) (@owned (Generic, Generic), @thick @dynamic_self Generic.Type) -> (@owned Generic, @owned Generic) + let selves = (self, self) + _ = { selves } + return self + } + + func t3() -> Self { + // CHECK-LABEL: sil private @_T012dynamic_self7GenericC2t3ACyxGXDyFAEXDycfU_ : $@convention(thin) (@owned @sil_unowned Generic, @thick @dynamic_self Generic.Type) -> @owned Generic + _ = {[unowned self] in self } + return self + } +} + // CHECK-LABEL: sil_witness_table hidden X: P module dynamic_self { // CHECK: method #P.f!1: {{.*}} : @_T012dynamic_self1XCAA1PA2aDP1f{{[_0-9a-zA-Z]*}}FTW