Skip to content

Commit cc10821

Browse files
committed
[Diagnostics] Unify DiagnosticFailure and ConstraintFix classes for extra & failures.
Make `InvalidUseOfAddressOf` a `ContextualFailure`, make `ReturnAddressOf` a `ContextualMismatch`, and extend this failure to cover using `&` with a non-inout argument.
1 parent d299925 commit cc10821

File tree

5 files changed

+47
-82
lines changed

5 files changed

+47
-82
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -908,17 +908,6 @@ bool MissingAddressOfFailure::diagnoseAsError() {
908908
return true;
909909
}
910910

911-
bool ExtraAddressOfFailure::diagnoseAsError() {
912-
if (hasComplexLocator())
913-
return false;
914-
915-
auto anchor = getAnchor();
916-
emitDiagnostic(getAnchor()->getLoc(), diag::extra_address_of, getToType())
917-
.highlight(anchor->getSourceRange())
918-
.fixItRemove(anchor->getStartLoc());
919-
return true;
920-
}
921-
922911
bool MissingExplicitConversionFailure::diagnoseAsError() {
923912
if (hasComplexLocator())
924913
return false;
@@ -3619,6 +3608,16 @@ SourceLoc InvalidUseOfAddressOf::getLoc() const {
36193608
}
36203609

36213610
bool InvalidUseOfAddressOf::diagnoseAsError() {
3611+
if (auto argApplyInfo = getFunctionArgApplyInfo(getLocator())) {
3612+
if (!argApplyInfo->getParameterFlags().isInOut()) {
3613+
auto anchor = getAnchor();
3614+
emitDiagnostic(anchor->getLoc(), diag::extra_address_of, getToType())
3615+
.highlight(anchor->getSourceRange())
3616+
.fixItRemove(anchor->getStartLoc());
3617+
return true;
3618+
}
3619+
}
3620+
36223621
emitDiagnostic(getLoc(), diag::extraneous_address_of);
36233622
return true;
36243623
}

lib/Sema/CSDiagnostics.h

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -843,14 +843,28 @@ class MissingAddressOfFailure final : public ContextualFailure {
843843
bool diagnoseAsError() override;
844844
};
845845

846-
/// Diagnose failures when passing an inout argument to a non-inout parameter.
847-
class ExtraAddressOfFailure final : public ContextualFailure {
846+
/// Diagnose extraneous use of address of (`&`) which could only be
847+
/// associated with arguments to inout parameters e.g.
848+
///
849+
/// ```swift
850+
/// struct S {}
851+
///
852+
/// var a: S = ...
853+
/// var b: S = ...
854+
///
855+
/// a = &b
856+
/// ```
857+
class InvalidUseOfAddressOf final : public ContextualFailure {
848858
public:
849-
ExtraAddressOfFailure(Expr *expr, ConstraintSystem &cs, Type argTy,
850-
Type paramTy, ConstraintLocator *locator)
851-
: ContextualFailure(expr, cs, argTy, paramTy, locator) {}
859+
InvalidUseOfAddressOf(Expr *root, ConstraintSystem &cs, Type lhs, Type rhs,
860+
ConstraintLocator *locator)
861+
: ContextualFailure(root, cs, lhs, rhs, locator) {}
852862

853863
bool diagnoseAsError() override;
864+
865+
protected:
866+
/// Compute location of the failure for diagnostic.
867+
SourceLoc getLoc() const;
854868
};
855869

856870
/// Diagnose mismatches relating to tuple destructuring.
@@ -1455,30 +1469,6 @@ class InvalidMethodRefInKeyPath final : public InvalidMemberRefInKeyPath {
14551469
bool diagnoseAsError() override;
14561470
};
14571471

1458-
/// Diagnose extraneous use of address of (`&`) which could only be
1459-
/// associated with arguments to inout parameters e.g.
1460-
///
1461-
/// ```swift
1462-
/// struct S {}
1463-
///
1464-
/// var a: S = ...
1465-
/// var b: S = ...
1466-
///
1467-
/// a = &b
1468-
/// ```
1469-
class InvalidUseOfAddressOf final : public FailureDiagnostic {
1470-
public:
1471-
InvalidUseOfAddressOf(Expr *root, ConstraintSystem &cs,
1472-
ConstraintLocator *locator)
1473-
: FailureDiagnostic(root, cs, locator) {}
1474-
1475-
bool diagnoseAsError() override;
1476-
1477-
protected:
1478-
/// Compute location of the failure for diagnostic.
1479-
SourceLoc getLoc() const;
1480-
};
1481-
14821472
/// Diagnose an attempt return something from a function which
14831473
/// doesn't have a return type specified e.g.
14841474
///

lib/Sema/CSFix.cpp

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -114,19 +114,6 @@ AddAddressOf *AddAddressOf::create(ConstraintSystem &cs, Type argTy,
114114
return new (cs.getAllocator()) AddAddressOf(cs, argTy, paramTy, locator);
115115
}
116116

117-
bool RemoveAddressOfArg::diagnose(Expr *root, bool asNote) const {
118-
auto &cs = getConstraintSystem();
119-
ExtraAddressOfFailure failure(root, cs, getFromType(), getToType(),
120-
getLocator());
121-
return failure.diagnose(asNote);
122-
}
123-
124-
RemoveAddressOfArg *
125-
RemoveAddressOfArg::create(ConstraintSystem &cs, Type argTy, Type paramTy,
126-
ConstraintLocator *locator) {
127-
return new (cs.getAllocator()) RemoveAddressOfArg(cs, argTy, paramTy, locator);
128-
}
129-
130117
bool TreatRValueAsLValue::diagnose(Expr *root, bool asNote) const {
131118
RValueTreatedAsLValueFailure failure(getConstraintSystem(), getLocator());
132119
return failure.diagnose(asNote);
@@ -636,13 +623,14 @@ KeyPathContextualMismatch::create(ConstraintSystem &cs, Type lhs, Type rhs,
636623
}
637624

638625
bool RemoveAddressOf::diagnose(Expr *root, bool asNote) const {
639-
InvalidUseOfAddressOf failure(root, getConstraintSystem(), getLocator());
626+
InvalidUseOfAddressOf failure(root, getConstraintSystem(), getFromType(),
627+
getToType(), getLocator());
640628
return failure.diagnose(asNote);
641629
}
642630

643-
RemoveAddressOf *RemoveAddressOf::create(ConstraintSystem &cs,
631+
RemoveAddressOf *RemoveAddressOf::create(ConstraintSystem &cs, Type lhs, Type rhs,
644632
ConstraintLocator *locator) {
645-
return new (cs.getAllocator()) RemoveAddressOf(cs, locator);
633+
return new (cs.getAllocator()) RemoveAddressOf(cs, lhs, rhs, locator);
646634
}
647635

648636
bool RemoveReturn::diagnose(Expr *root, bool asNote) const {

lib/Sema/CSFix.h

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -545,19 +545,20 @@ class AddAddressOf final : public ContextualMismatch {
545545
ConstraintLocator *locator);
546546
};
547547

548-
/// Remove the \c & of an argument for a non-inout parameter.
549-
class RemoveAddressOfArg final : public ContextualMismatch {
550-
RemoveAddressOfArg(ConstraintSystem &cs, Type argTy, Type paramTy,
551-
ConstraintLocator *locator)
552-
: ContextualMismatch(cs, argTy, paramTy, locator) {}
548+
class RemoveAddressOf final : public ContextualMismatch {
549+
RemoveAddressOf(ConstraintSystem &cs, Type lhs, Type rhs,
550+
ConstraintLocator *locator)
551+
: ContextualMismatch(cs, FixKind::RemoveAddressOf, lhs, rhs, locator) {}
553552

554553
public:
555-
std::string getName() const override { return "remove address of argument"; }
554+
std::string getName() const override {
555+
return "remove extraneous use of `&`";
556+
}
556557

557558
bool diagnose(Expr *root, bool asNote = false) const override;
558559

559-
static RemoveAddressOfArg *create(ConstraintSystem &cs, Type argTy,
560-
Type paramTy, ConstraintLocator *locator);
560+
static RemoveAddressOf *create(ConstraintSystem &cs, Type lhs, Type rhs,
561+
ConstraintLocator *locator);
561562
};
562563

563564
/// Detect situations where two type's generic arguments must
@@ -1180,21 +1181,6 @@ class AllowInvalidRefInKeyPath final : public ConstraintFix {
11801181
ConstraintLocator *locator);
11811182
};
11821183

1183-
class RemoveAddressOf final : public ConstraintFix {
1184-
RemoveAddressOf(ConstraintSystem &cs, ConstraintLocator *locator)
1185-
: ConstraintFix(cs, FixKind::RemoveAddressOf, locator) {}
1186-
1187-
public:
1188-
std::string getName() const override {
1189-
return "remove extraneous use of `&`";
1190-
}
1191-
1192-
bool diagnose(Expr *root, bool asNote = false) const override;
1193-
1194-
static RemoveAddressOf *create(ConstraintSystem &cs,
1195-
ConstraintLocator *locator);
1196-
};
1197-
11981184
class RemoveReturn final : public ConstraintFix {
11991185
RemoveReturn(ConstraintSystem &cs, ConstraintLocator *locator)
12001186
: ConstraintFix(cs, FixKind::RemoveReturn, locator) {}

lib/Sema/CSSimplify.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2357,7 +2357,8 @@ bool ConstraintSystem::repairFailures(
23572357

23582358
if (isa<InOutExpr>(AE->getSrc())) {
23592359
conversionsOrFixes.push_back(
2360-
RemoveAddressOf::create(*this, getConstraintLocator(locator)));
2360+
RemoveAddressOf::create(*this, lhs, rhs,
2361+
getConstraintLocator(locator)));
23612362
return true;
23622363
}
23632364

@@ -2443,7 +2444,7 @@ bool ConstraintSystem::repairFailures(
24432444
TypeMatchFlags::TMF_ApplyingFix, locator);
24442445

24452446
if (result.isSuccess())
2446-
conversionsOrFixes.push_back(RemoveAddressOfArg::create(*this, lhs,
2447+
conversionsOrFixes.push_back(RemoveAddressOf::create(*this, lhs,
24472448
rhs, getConstraintLocator(locator)));
24482449
}
24492450

@@ -3005,7 +3006,8 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
30053006

30063007
if (kind == ConstraintKind::OperatorArgumentConversion) {
30073008
conversionsOrFixes.push_back(
3008-
RemoveAddressOf::create(*this, getConstraintLocator(locator)));
3009+
RemoveAddressOf::create(*this, type1, type2,
3010+
getConstraintLocator(locator)));
30093011
break;
30103012
}
30113013

0 commit comments

Comments
 (0)