|
11 | 11 | //===----------------------------------------------------------------------===//
|
12 | 12 |
|
13 | 13 | #include "ArgumentSource.h"
|
| 14 | +#include "Conversion.h" |
14 | 15 | #include "Initialization.h"
|
15 | 16 | #include "LValue.h"
|
16 | 17 | #include "RValue.h"
|
@@ -1058,8 +1059,37 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
|
1058 | 1059 | // Figure out what we're initializing.
|
1059 | 1060 | auto memberInit = emitMemberInit(*this, selfDecl, varPattern);
|
1060 | 1061 |
|
1061 |
| - emitAndStoreInitialValueInto(*this, varPattern, pbd, i, subs, |
1062 |
| - origType, substType, memberInit.get()); |
| 1062 | + // This whole conversion thing is about eliminating the |
| 1063 | + // paired orig-to-subst subst-to-orig conversions that |
| 1064 | + // will happen if the storage is at a different abstraction |
| 1065 | + // level than the constructor. When emitApply() is used |
| 1066 | + // to call the stored property initializer, it naturally |
| 1067 | + // wants to convert the result back to the most substituted |
| 1068 | + // abstraction level. To undo this, we use a converting |
| 1069 | + // initialization and rely on the peephole that optimizes |
| 1070 | + // out the redundant conversion. |
| 1071 | + auto loweredResultTy = getLoweredType(origType, substType); |
| 1072 | + auto loweredSubstTy = getLoweredType(substType); |
| 1073 | + |
| 1074 | + if (loweredResultTy != loweredSubstTy) { |
| 1075 | + Conversion conversion = Conversion::getSubstToOrig( |
| 1076 | + origType, substType, |
| 1077 | + loweredResultTy); |
| 1078 | + |
| 1079 | + ConvertingInitialization convertingInit(conversion, |
| 1080 | + SGFContext(memberInit.get())); |
| 1081 | + |
| 1082 | + emitAndStoreInitialValueInto(*this, varPattern, pbd, i, subs, |
| 1083 | + origType, substType, &convertingInit); |
| 1084 | + |
| 1085 | + auto finalValue = convertingInit.finishEmission( |
| 1086 | + *this, varPattern, ManagedValue::forInContext()); |
| 1087 | + if (!finalValue.isInContext()) |
| 1088 | + finalValue.forwardInto(*this, varPattern, memberInit.get()); |
| 1089 | + } else { |
| 1090 | + emitAndStoreInitialValueInto(*this, varPattern, pbd, i, subs, |
| 1091 | + origType, substType, memberInit.get()); |
| 1092 | + } |
1063 | 1093 | }
|
1064 | 1094 | }
|
1065 | 1095 | }
|
|
0 commit comments