Skip to content

Commit db024d9

Browse files
committed
[CSDiagnostics] InitAccessors: Implement invalid member reference diagnostics within init accessors
1 parent 3c924be commit db024d9

File tree

5 files changed

+74
-2
lines changed

5 files changed

+74
-2
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7346,7 +7346,11 @@ ERROR(invalid_use_of_self_in_init_accessor,none,
73467346
"'self' within init accessors can only be used to reference "
73477347
"properties listed in 'initializes' and 'accesses'; "
73487348
"init accessors are run before 'self' is fully available", ())
7349-
7349+
ERROR(init_accessor_invalid_member_ref,none,
7350+
"cannot reference instance member %0; init accessors can only "
7351+
"refer to instance properties listed in 'initializes' and "
7352+
"'accesses' attributes",
7353+
(DeclNameRef))
73507354

73517355
#define UNDEFINE_DIAGNOSTIC_MACROS
73527356
#include "DefineDiagnosticMacros.h"

lib/Sema/CSDiagnostics.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9058,3 +9058,8 @@ bool MissingEachForValuePackReference::diagnoseAsError() {
90589058

90599059
return true;
90609060
}
9061+
9062+
bool InvalidMemberReferenceWithinInitAccessor::diagnoseAsError() {
9063+
emitDiagnostic(diag::init_accessor_invalid_member_ref, MemberName);
9064+
return true;
9065+
}

lib/Sema/CSDiagnostics.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3015,6 +3015,19 @@ class MissingEachForValuePackReference final : public FailureDiagnostic {
30153015
bool diagnoseAsError() override;
30163016
};
30173017

3018+
class InvalidMemberReferenceWithinInitAccessor final
3019+
: public FailureDiagnostic {
3020+
DeclNameRef MemberName;
3021+
3022+
public:
3023+
InvalidMemberReferenceWithinInitAccessor(const Solution &solution,
3024+
DeclNameRef memberName,
3025+
ConstraintLocator *locator)
3026+
: FailureDiagnostic(solution, locator), MemberName(memberName) {}
3027+
3028+
bool diagnoseAsError() override;
3029+
};
3030+
30183031
} // end namespace constraints
30193032
} // end namespace swift
30203033

lib/Sema/CSFix.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2799,7 +2799,9 @@ IgnoreMissingEachKeyword::create(ConstraintSystem &cs, Type valuePackTy,
27992799

28002800
bool AllowInvalidMemberReferenceInInitAccessor::diagnose(
28012801
const Solution &solution, bool asNote) const {
2802-
return false;
2802+
InvalidMemberReferenceWithinInitAccessor failure(solution, MemberName,
2803+
getLocator());
2804+
return failure.diagnose(asNote);
28032805
}
28042806

28052807
AllowInvalidMemberReferenceInInitAccessor *

test/decl/var/init_accessors.swift

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,51 @@ func test_invalid_self_uses() {
173173
static func test<T>(_: T) {}
174174
}
175175
}
176+
177+
func test_invalid_references() {
178+
struct Test {
179+
var _a: Int
180+
var _b: Int
181+
182+
var c: String
183+
static var c: String = ""
184+
185+
var _d: String
186+
187+
var data: Int {
188+
init(initialValue) initializes(_a) accesses(_d) {
189+
_a = initialValue // Ok
190+
191+
print(_d) // Ok
192+
self._d = "" // Ok
193+
194+
if self._b > 0 { // expected-error {{cannot reference instance member '_b'; init accessors can only refer to instance properties listed in 'initializes' and 'accesses' attributes}}
195+
}
196+
197+
let x = c.lowercased()
198+
// expected-error@-1 {{static member 'c' cannot be used on instance of type 'Test'}}
199+
200+
print(Test.c.lowercased()) // Ok
201+
202+
guard let v = test() else {
203+
// expected-error@-1 {{cannot reference instance member 'test'; init accessors can only refer to instance properties listed in 'initializes' and 'accesses' attributes}}
204+
return
205+
}
206+
207+
_ = {
208+
if true {
209+
print(_b)
210+
// expected-error@-1 {{cannot reference instance member '_b'; init accessors can only refer to instance properties listed in 'initializes' and 'accesses' attributes}}
211+
print(self._b)
212+
// expected-error@-1 {{cannot reference instance member '_b'; init accessors can only refer to instance properties listed in 'initializes' and 'accesses' attributes}}
213+
}
214+
}
215+
}
216+
217+
get { _a }
218+
set { }
219+
}
220+
221+
func test() -> Int? { 42 }
222+
}
223+
}

0 commit comments

Comments
 (0)