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) {
33453345 // A natively ObjC method witness referenced this way will end up going
33463346 // through its native thunk, which will redispatch the method after doing
33473347 // 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 ())
33513349 return WitnessDispatchKind::Static;
33523350
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+
33533362 // Otherwise emit a class method.
33543363 return WitnessDispatchKind::Class;
33553364}
Original file line number Diff line number Diff line change @@ -20,3 +20,32 @@ class Dog: Animal, BestFriend {}
2020// CHECK-LABEL: sil private [transparent] [thunk] @$S4main3DogCAA10BestFriendA2aDP6createxyFZTW
2121// CHECK: [[SELF:%.*]] = apply
2222// 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