Skip to content

Commit bd20e82

Browse files
authored
Merge pull request #3468 from swiftix/master
2 parents 5d9c10b + 8cc0f11 commit bd20e82

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

lib/IRGen/GenProto.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,13 @@ void EmitPolymorphicParameters::bindExtraSource(const MetadataSource &source,
511511
auto selfTy = FnType->getSelfInstanceType();
512512
CanType argTy = getTypeInContext(selfTy);
513513
setTypeMetadataName(IGF.IGM, metadata, argTy);
514-
IGF.bindLocalTypeDataFromTypeMetadata(argTy, IsExact, metadata);
514+
auto *CD = selfTy.getClassOrBoundGenericClass();
515+
// The self metadata here corresponds to the conforming type.
516+
// For an inheritable conformance, that may be a subclass of the static
517+
// type, and so the self metadata will be inexact. Currently, all
518+
// conformances are inheritable.
519+
IGF.bindLocalTypeDataFromTypeMetadata(
520+
argTy, (!CD || CD->isFinal()) ? IsExact : IsInexact, metadata);
515521
return;
516522
}
517523

test/IRGen/metadata_dominance.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %target-swift-frontend -emit-ir -primary-file %s | FileCheck %s
2+
// RUN: %target-swift-frontend -O -emit-ir -primary-file %s | FileCheck %s --check-prefix=CHECK-OPT
23

34
func use_metadata<F>(_ f: F) {}
45

@@ -49,3 +50,35 @@ func test2() {
4950
// CHECK: call void @_TF18metadata_dominance12use_metadataurFxT_(%swift.opaque* {{.*}}, %swift.type* [[T2]])
5051
use_metadata(voidToVoid)
5152
}
53+
54+
protocol P {
55+
func makeFoo() -> Foo
56+
}
57+
58+
class Foo: P {
59+
func makeFoo() -> Foo {
60+
fatalError()
61+
}
62+
}
63+
64+
class SubFoo: Foo {
65+
final override func makeFoo() -> Foo {
66+
// Check that it creates an instance of type Foo,
67+
// and not an instance of a Self type involved
68+
// in this protocol conformance.
69+
return Foo()
70+
}
71+
}
72+
73+
@inline(never)
74+
func testMakeFoo(_ p: P) -> Foo.Type {
75+
let foo = p.makeFoo()
76+
return foo.dynamicType
77+
}
78+
79+
// The protocol witness for metadata_dominance.P.makeFoo () -> metadata_dominance.Foo in
80+
// conformance metadata_dominance.Foo : metadata_dominance.P should not use the Self type
81+
// as the type of the object to be created. It should dynamically obtain the type.
82+
// CHECK-OPT-LABEL: define hidden %C18metadata_dominance3Foo* @_TTWC18metadata_dominance3FooS_1PS_FS1_7makeFoofT_S0_
83+
// CHECK-OPT-NOT: tail call noalias %swift.refcounted* @rt_swift_allocObject(%swift.type* %Self
84+

0 commit comments

Comments
 (0)