Skip to content

Commit 35c0228

Browse files
committed
[ConstraintSystem] Detect and fix extraneous use of &
Diagnose extraneous use of address of (`&`) which could only be associated with arguments to `inout` parameters e.g. ```swift struct S {} var a: S = ... var b: S = ... a = &b ``` (cherry picked from commit 3af163a)
1 parent 7252dc9 commit 35c0228

File tree

5 files changed

+61
-1
lines changed

5 files changed

+61
-1
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2670,3 +2670,9 @@ bool InvalidMethodRefInKeyPath::diagnoseAsError() {
26702670
getName(), isForKeyPathDynamicMemberLookup());
26712671
return true;
26722672
}
2673+
2674+
bool InvalidUseOfAddressOf::diagnoseAsError() {
2675+
auto *anchor = cast<AssignExpr>(getAnchor());
2676+
emitDiagnostic(anchor->getSrc()->getLoc(), diag::extraneous_address_of);
2677+
return true;
2678+
}

lib/Sema/CSDiagnostics.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,26 @@ class InvalidMethodRefInKeyPath final : public InvalidMemberRefInKeyPath {
11381138
bool diagnoseAsError() override;
11391139
};
11401140

1141+
/// Diagnose extraneous use of address of (`&`) which could only be
1142+
/// associated with arguments to inout parameters e.g.
1143+
///
1144+
/// ```swift
1145+
/// struct S {}
1146+
///
1147+
/// var a: S = ...
1148+
/// var b: S = ...
1149+
///
1150+
/// a = &b
1151+
/// ```
1152+
class InvalidUseOfAddressOf final : public FailureDiagnostic {
1153+
public:
1154+
InvalidUseOfAddressOf(Expr *root, ConstraintSystem &cs,
1155+
ConstraintLocator *locator)
1156+
: FailureDiagnostic(root, cs, locator) {}
1157+
1158+
bool diagnoseAsError() override;
1159+
};
1160+
11411161
} // end namespace constraints
11421162
} // end namespace swift
11431163

lib/Sema/CSFix.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,3 +484,13 @@ KeyPathContextualMismatch::create(ConstraintSystem &cs, Type lhs, Type rhs,
484484
return new (cs.getAllocator())
485485
KeyPathContextualMismatch(cs, lhs, rhs, locator);
486486
}
487+
488+
bool RemoveAddressOf::diagnose(Expr *root, bool asNote) const {
489+
InvalidUseOfAddressOf failure(root, getConstraintSystem(), getLocator());
490+
return failure.diagnose(asNote);
491+
}
492+
493+
RemoveAddressOf *RemoveAddressOf::create(ConstraintSystem &cs,
494+
ConstraintLocator *locator) {
495+
return new (cs.getAllocator()) RemoveAddressOf(cs, locator);
496+
}

lib/Sema/CSFix.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ enum class FixKind : uint8_t {
5757

5858
/// Introduce a '&' to take the address of an lvalue.
5959
AddressOf,
60+
/// Remove extraneous use of `&`.
61+
RemoveAddressOf,
6062

6163
/// Replace a coercion ('as') with a forced checked cast ('as!').
6264
CoerceToCheckedCast,
@@ -853,6 +855,21 @@ class AllowInvalidRefInKeyPath final : public ConstraintFix {
853855
ConstraintLocator *locator);
854856
};
855857

858+
class RemoveAddressOf final : public ConstraintFix {
859+
RemoveAddressOf(ConstraintSystem &cs, ConstraintLocator *locator)
860+
: ConstraintFix(cs, FixKind::RemoveAddressOf, locator) {}
861+
862+
public:
863+
std::string getName() const override {
864+
return "remove extraneous use of `&`";
865+
}
866+
867+
bool diagnose(Expr *root, bool asNote = false) const override;
868+
869+
static RemoveAddressOf *create(ConstraintSystem &cs,
870+
ConstraintLocator *locator);
871+
};
872+
856873
} // end namespace constraints
857874
} // end namespace swift
858875

lib/Sema/CSSimplify.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1993,7 +1993,7 @@ bool ConstraintSystem::repairFailures(
19931993
return true;
19941994
}
19951995

1996-
if (isa<AssignExpr>(anchor)) {
1996+
if (auto *AE = dyn_cast<AssignExpr>(anchor)) {
19971997
if (auto *fnType = lhs->getAs<FunctionType>()) {
19981998
// If left-hand side is a function type but right-hand
19991999
// side isn't, let's check it would be possible to fix
@@ -2009,6 +2009,12 @@ bool ConstraintSystem::repairFailures(
20092009
return true;
20102010
}
20112011
}
2012+
2013+
if (isa<InOutExpr>(AE->getSrc())) {
2014+
conversionsOrFixes.push_back(
2015+
RemoveAddressOf::create(*this, getConstraintLocator(locator)));
2016+
return true;
2017+
}
20122018
}
20132019

20142020
return false;
@@ -6476,6 +6482,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
64766482
}
64776483

64786484
case FixKind::InsertCall:
6485+
case FixKind::RemoveAddressOf:
64796486
case FixKind::SkipSameTypeRequirement:
64806487
case FixKind::SkipSuperclassRequirement:
64816488
case FixKind::ContextualMismatch:

0 commit comments

Comments
 (0)