Skip to content

Commit 60d9316

Browse files
committed
[Dignostics] Diagnose weak declarations with non-optional types
Diagnose situations where `weak` attribute is used with a non-optional type in declaration e.g. `weak var x: <Type>`: ```swift class X { } weak var x: X = ... ``` `weak` declaration is required to use an optional type e.g. `X?`.
1 parent 3fac0fe commit 60d9316

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7776,3 +7776,27 @@ bool UnsupportedRuntimeCheckedCastFailure::diagnoseAsError() {
77767776
.fixItReplace(getCastRange(), "as");
77777777
return true;
77787778
}
7779+
7780+
bool InvalidWeakAttributeUse::diagnoseAsError() {
7781+
auto *pattern =
7782+
dyn_cast_or_null<NamedPattern>(getAnchor().dyn_cast<Pattern *>());
7783+
if (!pattern)
7784+
return false;
7785+
7786+
auto *var = pattern->getDecl();
7787+
auto varType = getType(var);
7788+
7789+
auto diagnostic =
7790+
emitDiagnosticAt(var, diag::invalid_ownership_not_optional,
7791+
ReferenceOwnership::Weak, varType);
7792+
7793+
auto typeRange = var->getTypeSourceRangeForDiagnostics();
7794+
if (varType->hasSimpleTypeRepr()) {
7795+
diagnostic.fixItInsertAfter(typeRange.End, "?");
7796+
} else {
7797+
diagnostic.fixItInsert(typeRange.Start, "(")
7798+
.fixItInsertAfter(typeRange.End, ")?");
7799+
}
7800+
7801+
return true;
7802+
}

lib/Sema/CSDiagnostics.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2589,6 +2589,25 @@ class InvalidMemberRefOnProtocolMetatype final : public FailureDiagnostic {
25892589
bool diagnoseAsError() override;
25902590
};
25912591

2592+
/// Diagnose situations where `weak` attribute is used with a non-optional type
2593+
/// in declaration e.g. `weak var x: <Type>`:
2594+
///
2595+
/// \code
2596+
/// class X {
2597+
/// }
2598+
///
2599+
/// weak var x: X = ...
2600+
/// \endcode
2601+
///
2602+
/// `weak` declaration is required to use an optional type e.g. `X?`.
2603+
class InvalidWeakAttributeUse final : public FailureDiagnostic {
2604+
public:
2605+
InvalidWeakAttributeUse(const Solution &solution, ConstraintLocator *locator)
2606+
: FailureDiagnostic(solution, locator) {}
2607+
2608+
bool diagnoseAsError() override;
2609+
};
2610+
25922611
} // end namespace constraints
25932612
} // end namespace swift
25942613

lib/Sema/CSFix.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1992,7 +1992,8 @@ AllowInvalidStaticMemberRefOnProtocolMetatype::create(
19921992

19931993
bool AllowNonOptionalWeak::diagnose(const Solution &solution,
19941994
bool asNote) const {
1995-
return false;
1995+
InvalidWeakAttributeUse failure(solution, getLocator());
1996+
return failure.diagnose(asNote);
19961997
}
19971998

19981999
AllowNonOptionalWeak *AllowNonOptionalWeak::create(ConstraintSystem &cs,

0 commit comments

Comments
 (0)