Skip to content

Commit 5227355

Browse files
authored
[FixCode] Add diagnosis/fixit to help users deal with BooleanType's removal (#4392)
* [FixCode] Add diagnosis/fixit to help users deal with BooleanType's removal. Due to migration reasons, types used to conform to BooleanType, which must contain a member var 'boolValue', now does not convert to Bool. This patch adds a specific diagnosis/fixit to explicitly invoke 'boolValue' to please the context types. * Address Jordan's code review comments.
1 parent 7f3f0f8 commit 5227355

File tree

4 files changed

+44
-2
lines changed

4 files changed

+44
-2
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,9 @@ NOTE(in_cast_expr_types,none,
686686
"in cast from type %0 to %1",
687687
(Type, Type))
688688

689+
ERROR(types_not_convertible_use_bool_value,none,
690+
"%0 is not convertible to %1; did you mean %0.boolValue", (Type, Type))
691+
689692
ERROR(tuple_types_not_convertible_nelts,none,
690693
"%0 is not convertible to %1, "
691694
"tuples have a different number of elements", (Type, Type))

lib/Sema/CSDiag.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2928,6 +2928,27 @@ bool FailureDiagnosis::diagnoseGeneralConversionFailure(Constraint *constraint){
29282928
}
29292929
return true;
29302930
}
2931+
2932+
// Due to migration reasons, types used to conform to BooleanType, which
2933+
// contain a member var 'boolValue', now does not convert to Bool. This block
2934+
// tries to add a specific diagnosis/fixit to explicitly invoke 'boolValue'.
2935+
if (toType->isBool()) {
2936+
auto LookupResult = CS->TC.lookupMember(CS->DC, fromType,
2937+
DeclName(CS->TC.Context.getIdentifier("boolValue")));
2938+
if (!LookupResult.empty()) {
2939+
if (isa<VarDecl>(LookupResult.begin()->Decl)) {
2940+
if (anchor->canAppendCallParentheses())
2941+
diagnose(anchor->getLoc(), diag::types_not_convertible_use_bool_value,
2942+
fromType, toType).fixItInsertAfter(anchor->getEndLoc(),
2943+
".boolValue");
2944+
else
2945+
diagnose(anchor->getLoc(), diag::types_not_convertible_use_bool_value,
2946+
fromType, toType).fixItInsert(anchor->getStartLoc(), "(").
2947+
fixItInsertAfter(anchor->getEndLoc(), ").boolValue");
2948+
return true;
2949+
}
2950+
}
2951+
}
29312952

29322953
diagnose(anchor->getLoc(), diag::types_not_convertible,
29332954
constraint->getKind() == ConstraintKind::Subtype,

test/FixCode/fixits-apply.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func baz(var x: Int) {
118118
x += 10
119119
}
120120
func foo(let y: String, inout x: Int) {
121-
121+
122122
}
123123

124124
struct Test1 : OptionSet {
@@ -261,3 +261,12 @@ func disable_unnamed_param_reorder(p: Int, _: String) {}
261261
disable_unnamed_param_reorder(0, "") // no change.
262262

263263
prefix operator ***** {}
264+
265+
class BoolFoo : BooleanType {
266+
var boolValue: Bool {return false}
267+
}
268+
func testBoolValue(a : BoolFoo) {
269+
if a { }
270+
guard a {}
271+
if a as BoolFoo {}
272+
}

test/FixCode/fixits-apply.swift.result

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func baz(x: Int) {
121121
x += 10
122122
}
123123
func foo(y: String, x: inout Int) {
124-
124+
125125
}
126126

127127
struct Test1 : OptionSet {
@@ -264,3 +264,12 @@ func disable_unnamed_param_reorder(p: Int, _: String) {}
264264
disable_unnamed_param_reorder(0, "") // no change.
265265

266266
prefix operator *****
267+
268+
class BoolFoo : Bool {
269+
var boolValue: Bool {return false}
270+
}
271+
func testBoolValue(a : BoolFoo) {
272+
if a.boolValue { }
273+
guard a.boolValue {}
274+
if (a as BoolFoo).boolValue {}
275+
}

0 commit comments

Comments
 (0)