Skip to content

Commit ca48ebf

Browse files
committed
Improve type coercion fixits for optional-to-optional conversions.
1 parent df34cdc commit ca48ebf

File tree

2 files changed

+15
-12
lines changed

2 files changed

+15
-12
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2869,6 +2869,10 @@ static bool addTypeCoerceFixit(InFlightDiagnostic &diag, ConstraintSystem &CS,
28692869
Type fromType, Type toType, Expr *expr) {
28702870
// Look through optional types; casts can add them, but can't remove extra
28712871
// ones.
2872+
bool bothOptional =
2873+
fromType->getOptionalObjectType() && toType->getOptionalObjectType();
2874+
if (bothOptional)
2875+
fromType = fromType->getOptionalObjectType();
28722876
toType = toType->lookThroughAllOptionalTypes();
28732877

28742878
CheckedCastKind Kind = CS.getTypeChecker().typeCheckCheckedCast(
@@ -2883,7 +2887,8 @@ static bool addTypeCoerceFixit(InFlightDiagnostic &diag, ConstraintSystem &CS,
28832887
diag.fixItInsert(
28842888
Lexer::getLocForEndOfToken(CS.DC->getASTContext().SourceMgr,
28852889
expr->getEndLoc()),
2886-
(llvm::Twine(canUseAs ? " as " : " as! ") + OS.str()).str());
2890+
(llvm::Twine(canUseAs ? " as " : " as! ") + OS.str() +
2891+
llvm::Twine(canUseAs && bothOptional ? "?" : "")).str());
28872892
return true;
28882893
}
28892894
return false;

test/Constraints/bridging.swift

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -276,27 +276,25 @@ func rdar19831698() {
276276
// <rdar://problem/19836341> Incorrect fixit for NSString? to String? conversions
277277
func rdar19836341(_ ns: NSString?, vns: NSString?) {
278278
var vns = vns
279-
let _: String? = ns // expected-error{{cannot convert value of type 'NSString?' to specified type 'String?'}}
280-
var _: String? = ns // expected-error{{cannot convert value of type 'NSString?' to specified type 'String?'}}
281-
// FIXME: there should be a fixit appending "as String?" to the line; for now
282-
// it's sufficient that it doesn't suggest appending "as String"
279+
let _: String? = ns // expected-error{{cannot convert value of type 'NSString?' to specified type 'String?'}}{{22-22= as String?}}
280+
var _: String? = ns // expected-error{{cannot convert value of type 'NSString?' to specified type 'String?'}}{{22-22= as String?}}
283281

284282
// Important part about below diagnostic is that from-type is described as
285283
// 'NSString?' and not '@lvalue NSString?':
286-
let _: String? = vns // expected-error{{cannot convert value of type 'NSString?' to specified type 'String?'}}
287-
var _: String? = vns // expected-error{{cannot convert value of type 'NSString?' to specified type 'String?'}}
288-
284+
let _: String? = vns // expected-error{{cannot convert value of type 'NSString?' to specified type 'String?'}}{{23-23= as String?}}
285+
var _: String? = vns // expected-error{{cannot convert value of type 'NSString?' to specified type 'String?'}}{{23-23= as String?}}
286+
289287
vns = ns
290288
}
291289

292290
// <rdar://problem/20029786> Swift compiler sometimes suggests changing "as!" to "as?!"
293291
func rdar20029786(_ ns: NSString?) {
294-
var s: String = ns ?? "str" as String as String // expected-error{{cannot convert value of type 'NSString?' to expected argument type 'String?'}}
295-
var s2 = ns ?? "str" as String as String // expected-error {{cannot convert value of type 'String' to expected argument type 'NSString'}}
292+
var s: String = ns ?? "str" as String as String // expected-error{{cannot convert value of type 'NSString?' to expected argument type 'String?'}}{{21-21= as String?}}
293+
var s2 = ns ?? "str" as String as String // expected-error {{cannot convert value of type 'String' to expected argument type 'NSString'}}{{43-43= as NSString}}
296294

297-
let s3: NSString? = "str" as String? // expected-error {{cannot convert value of type 'String?' to specified type 'NSString?'}}
295+
let s3: NSString? = "str" as String? // expected-error {{cannot convert value of type 'String?' to specified type 'NSString?'}}{{39-39= as NSString?}}
298296

299-
var s4: String = ns ?? "str" // expected-error{{cannot convert value of type 'NSString' to specified type 'String'}}
297+
var s4: String = ns ?? "str" // expected-error{{cannot convert value of type 'NSString' to specified type 'String'}}{{31-31= as String}}
300298
var s5: String = (ns ?? "str") as String // fixed version
301299
}
302300

0 commit comments

Comments
 (0)