@@ -3159,8 +3159,37 @@ static void tryRawRepresentableFixIts(InFlightDiagnostic &diag,
3159
3159
KnownProtocolKind kind,
3160
3160
Expr *expr) {
3161
3161
// The following fixes apply for optional destination types as well.
3162
+ bool toTypeIsOptional = !toType->getAnyOptionalObjectType ().isNull ();
3162
3163
toType = toType->lookThroughAllAnyOptionalTypes ();
3163
3164
3165
+ Type fromTypeUnwrapped = fromType->getAnyOptionalObjectType ();
3166
+ bool fromTypeIsOptional = !fromTypeUnwrapped.isNull ();
3167
+ if (fromTypeIsOptional)
3168
+ fromType = fromTypeUnwrapped;
3169
+
3170
+ auto fixIt = [&](StringRef convWrapBefore, StringRef convWrapAfter) {
3171
+ SourceRange exprRange = expr->getSourceRange ();
3172
+ if (fromTypeIsOptional && toTypeIsOptional) {
3173
+ // Use optional's map function to convert conditionally, like so:
3174
+ // expr.map{ T(rawValue: $0) }
3175
+ bool needsParens = !expr->canAppendCallParentheses ();
3176
+ std::string mapCodeFix;
3177
+ if (needsParens) {
3178
+ diag.fixItInsert (exprRange.Start , " (" );
3179
+ mapCodeFix += " )" ;
3180
+ }
3181
+ mapCodeFix += " .map{ " ;
3182
+ mapCodeFix += convWrapBefore;
3183
+ mapCodeFix += " $0" ;
3184
+ mapCodeFix += convWrapAfter;
3185
+ mapCodeFix += " }" ;
3186
+ diag.fixItInsertAfter (exprRange.End , mapCodeFix);
3187
+ } else if (!fromTypeIsOptional) {
3188
+ diag.fixItInsert (exprRange.Start , convWrapBefore);
3189
+ diag.fixItInsertAfter (exprRange.End , convWrapAfter);
3190
+ }
3191
+ };
3192
+
3164
3193
if (isLiteralConvertibleType (fromType, kind, CS)) {
3165
3194
if (auto rawTy = isRawRepresentable (toType, kind, CS)) {
3166
3195
// Produce before/after strings like 'Result(rawValue: RawType(<expr>))'
@@ -3173,9 +3202,7 @@ static void tryRawRepresentableFixIts(InFlightDiagnostic &diag,
3173
3202
convWrapBefore += " (" ;
3174
3203
convWrapAfter += " )" ;
3175
3204
}
3176
- SourceRange exprRange = expr->getSourceRange ();
3177
- diag.fixItInsert (exprRange.Start , convWrapBefore);
3178
- diag.fixItInsertAfter (exprRange.End , convWrapAfter);
3205
+ fixIt (convWrapBefore, convWrapAfter);
3179
3206
return ;
3180
3207
}
3181
3208
}
@@ -3189,9 +3216,7 @@ static void tryRawRepresentableFixIts(InFlightDiagnostic &diag,
3189
3216
convWrapBefore += " (" ;
3190
3217
convWrapAfter += " )" ;
3191
3218
}
3192
- SourceRange exprRange = expr->getSourceRange ();
3193
- diag.fixItInsert (exprRange.Start , convWrapBefore);
3194
- diag.fixItInsertAfter (exprRange.End , convWrapAfter);
3219
+ fixIt (convWrapBefore, convWrapAfter);
3195
3220
return ;
3196
3221
}
3197
3222
}
0 commit comments