Skip to content

Commit 6cd476b

Browse files
authored
Merge pull request #24522 from xedin/diag-extraneous-addr-of
[ConstraintSystem] Detect and fix extraneous use of `&`
2 parents 13f85af + 3af163a commit 6cd476b

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
@@ -2727,3 +2727,9 @@ bool InvalidMethodRefInKeyPath::diagnoseAsError() {
27272727
getName(), isForKeyPathDynamicMemberLookup());
27282728
return true;
27292729
}
2730+
2731+
bool InvalidUseOfAddressOf::diagnoseAsError() {
2732+
auto *anchor = cast<AssignExpr>(getAnchor());
2733+
emitDiagnostic(anchor->getSrc()->getLoc(), diag::extraneous_address_of);
2734+
return true;
2735+
}

lib/Sema/CSDiagnostics.h

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

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

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)