@@ -2485,7 +2485,22 @@ static CanSILFunctionType getNativeSILFunctionType(
24852485 case SILFunctionType::Representation::Method:
24862486 case SILFunctionType::Representation::Closure:
24872487 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) {
24892504 case SILDeclRef::Kind::Initializer:
24902505 case SILDeclRef::Kind::EnumElement:
24912506 return getSILFunctionTypeForConventions (DefaultInitializerConventions ());
0 commit comments