Skip to content

Commit 3af163a

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 ```
1 parent 43526d0 commit 3af163a

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
@@ -2674,3 +2674,9 @@ bool InvalidMethodRefInKeyPath::diagnoseAsError() {
26742674
getName(), isForKeyPathDynamicMemberLookup());
26752675
return true;
26762676
}
2677+
2678+
bool InvalidUseOfAddressOf::diagnoseAsError() {
2679+
auto *anchor = cast<AssignExpr>(getAnchor());
2680+
emitDiagnostic(anchor->getSrc()->getLoc(), diag::extraneous_address_of);
2681+
return true;
2682+
}

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
@@ -2035,7 +2035,7 @@ bool ConstraintSystem::repairFailures(
20352035
return true;
20362036
}
20372037

2038-
if (isa<AssignExpr>(anchor)) {
2038+
if (auto *AE = dyn_cast<AssignExpr>(anchor)) {
20392039
if (auto *fnType = lhs->getAs<FunctionType>()) {
20402040
// If left-hand side is a function type but right-hand
20412041
// side isn't, let's check it would be possible to fix
@@ -2051,6 +2051,12 @@ bool ConstraintSystem::repairFailures(
20512051
return true;
20522052
}
20532053
}
2054+
2055+
if (isa<InOutExpr>(AE->getSrc())) {
2056+
conversionsOrFixes.push_back(
2057+
RemoveAddressOf::create(*this, getConstraintLocator(locator)));
2058+
return true;
2059+
}
20542060
}
20552061

20562062
return false;
@@ -6508,6 +6514,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
65086514
}
65096515

65106516
case FixKind::InsertCall:
6517+
case FixKind::RemoveAddressOf:
65116518
case FixKind::SkipSameTypeRequirement:
65126519
case FixKind::SkipSuperclassRequirement:
65136520
case FixKind::ContextualMismatch:

0 commit comments

Comments
 (0)