@@ -2485,7 +2485,22 @@ static CanSILFunctionType getNativeSILFunctionType(
2485
2485
case SILFunctionType::Representation::Method:
2486
2486
case SILFunctionType::Representation::Closure:
2487
2487
case SILFunctionType::Representation::WitnessMethod: {
2488
- switch (constant ? constant->kind : SILDeclRef::Kind::Func) {
2488
+ // FIXME: We should use origConstant unconditionally here, since in the
2489
+ // case of protocol witness thunk type lowering, we want to lower the
2490
+ // witness's calling convention according to the convention of the protocol
2491
+ // requirement, even if the witness has a different kind. Previously we
2492
+ // would base this on the witness `constant`, and this worked because
2493
+ // witnesses had always been the same decl kind as the requirement, but
2494
+ // enum cases as static witnesses broke this invariant.
2495
+ //
2496
+ // To minimize the change in behavior for Swift 5.4, we only consider
2497
+ // origConstant when constant is an EnumElement, to avoid affecting other
2498
+ // potential corner cases I'm not thinking of in the moment.
2499
+ auto constantToTest = constant;
2500
+ if (constant && constant->kind == SILDeclRef::Kind::EnumElement) {
2501
+ constantToTest = origConstant;
2502
+ }
2503
+ switch (constantToTest ? constantToTest->kind : SILDeclRef::Kind::Func) {
2489
2504
case SILDeclRef::Kind::Initializer:
2490
2505
case SILDeclRef::Kind::EnumElement:
2491
2506
return getSILFunctionTypeForConventions (DefaultInitializerConventions ());
0 commit comments