File tree Expand file tree Collapse file tree 2 files changed +41
-3
lines changed Expand file tree Collapse file tree 2 files changed +41
-3
lines changed Original file line number Diff line number Diff line change @@ -3345,11 +3345,20 @@ static WitnessDispatchKind getWitnessDispatchKind(SILDeclRef witness) {
3345
3345
// A natively ObjC method witness referenced this way will end up going
3346
3346
// through its native thunk, which will redispatch the method after doing
3347
3347
// bridging just like we want.
3348
- if (isFinal || isExtension || witness.isForeignToNativeThunk ()
3349
- // Hack--We emit a static thunk for ObjC allocating constructors.
3350
- || (decl->hasClangNode () && witness.kind == SILDeclRef::Kind::Allocator))
3348
+ if (isFinal || isExtension || witness.isForeignToNativeThunk ())
3351
3349
return WitnessDispatchKind::Static;
3352
3350
3351
+ if (witness.kind == SILDeclRef::Kind::Allocator) {
3352
+ // Non-required initializers can witness a protocol requirement if the class
3353
+ // is final, so we can statically dispatch to them.
3354
+ if (!cast<ConstructorDecl>(decl)->isRequired ())
3355
+ return WitnessDispatchKind::Static;
3356
+
3357
+ // We emit a static thunk for ObjC allocating constructors.
3358
+ if (decl->hasClangNode ())
3359
+ return WitnessDispatchKind::Static;
3360
+ }
3361
+
3353
3362
// Otherwise emit a class method.
3354
3363
return WitnessDispatchKind::Class;
3355
3364
}
Original file line number Diff line number Diff line change @@ -20,3 +20,32 @@ class Dog: Animal, BestFriend {}
20
20
// CHECK-LABEL: sil private [transparent] [thunk] @$S4main3DogCAA10BestFriendA2aDP6createxyFZTW
21
21
// CHECK: [[SELF:%.*]] = apply
22
22
// CHECK: unchecked_ref_cast [[SELF]] : $Animal to $Dog
23
+
24
+ class Base {
25
+ init ( ) { }
26
+
27
+ convenience init ( x: Int ) {
28
+ self . init ( )
29
+ }
30
+ }
31
+
32
+ protocol Initable {
33
+ init ( x: Int )
34
+ }
35
+
36
+ final class Derived : Base , Initable { }
37
+
38
+ // CHECK-LABEL: sil hidden @$S4main4BaseC1xACSi_tcfC : $@convention(method) (Int, @thick Base.Type) -> @owned Base
39
+ // CHECK: [[SELF:%.*]] = alloc_ref_dynamic %1 : $@thick Base.Type, $Base
40
+ // CHECK: [[METHOD:%.*]] = function_ref @$S4main4BaseC1xACSi_tcfc
41
+ // CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]](%0, [[SELF]])
42
+ // CHECK-NEXT: return [[RESULT]]
43
+
44
+ // CHECK-LABEL: sil private [transparent] [thunk] @$S4main7DerivedCAA8InitableA2aDP1xxSi_tcfCTW : $@convention(witness_method: Initable) (Int, @thick Derived.Type) -> @out Derived
45
+ // CHECK: [[SELF:%.*]] = upcast %2 : $@thick Derived.Type to $@thick Base.Type
46
+ // CHECK: [[METHOD:%.*]] = function_ref @$S4main4BaseC1xACSi_tcfC
47
+ // CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]](%1, [[SELF]])
48
+ // CHECK-NEXT: [[NEW_SELF:%.*]] = unchecked_ref_cast [[RESULT]] : $Base to $Derived
49
+ // CHECK-NEXT: store [[NEW_SELF]] to [init] %0 : $*Derived
50
+ // CHECK-NEXT: [[TUPLE:%.*]] = tuple ()
51
+ // CHECK-NEXT: return [[TUPLE]]
You can’t perform that action at this time.
0 commit comments