Skip to content

Commit 256e0e0

Browse files
committed
reword diagnostics for partial consume of fields
also moves the error to the invalid partial consume. rdar://109281444 (cherry picked from commit d3730d8)
1 parent 81f9603 commit 256e0e0

File tree

3 files changed

+44
-75
lines changed

3 files changed

+44
-75
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -775,12 +775,9 @@ ERROR(sil_moveonlychecker_notconsumable_but_assignable_was_consumed, none,
775775
"cannot consume noncopyable stored property '%0' %select{of a class|that is global}1",
776776
(StringRef, bool))
777777

778-
ERROR(sil_moveonlychecker_cannot_destructure_deinit_nominal_type_self, none,
779-
"Cannot partially consume '%0' since it has a user defined deinit",
778+
ERROR(sil_moveonlychecker_cannot_destructure_has_deinit, none,
779+
"cannot partially consume '%0' since it has a user defined deinit",
780780
(StringRef))
781-
ERROR(sil_moveonlychecker_cannot_destructure_deinit_nominal_type_field, none,
782-
"Cannot partially consume '%0' since it contains field '%1.%2' whose type %3 has a user defined deinit",
783-
(StringRef, StringRef, StringRef, DeclBaseName))
784781

785782
NOTE(sil_moveonlychecker_partial_consume_here, none,
786783
"partial consume here", ())

lib/SILOptimizer/Mandatory/MoveOnlyDiagnostics.cpp

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -683,25 +683,21 @@ void DiagnosticEmitter::emitCannotDestructureDeinitNominalError(
683683
MarkMustCheckInst *markedValue, StringRef pathString,
684684
NominalTypeDecl *deinitedNominal, SILInstruction *consumingUser) {
685685
auto &astContext = fn->getASTContext();
686+
686687
SmallString<64> varName;
687688
getVariableNameForValue(markedValue, varName);
688689

690+
if (!pathString.empty())
691+
varName.append(pathString);
692+
693+
diagnose(
694+
astContext, consumingUser,
695+
diag::sil_moveonlychecker_cannot_destructure_has_deinit,
696+
varName);
689697
registerDiagnosticEmitted(markedValue);
690698

691-
if (pathString.empty()) {
692-
diagnose(
693-
astContext, markedValue,
694-
diag::sil_moveonlychecker_cannot_destructure_deinit_nominal_type_self,
695-
varName);
696-
} else {
697-
diagnose(
698-
astContext, markedValue,
699-
diag::sil_moveonlychecker_cannot_destructure_deinit_nominal_type_field,
700-
varName, varName, pathString.drop_front(),
701-
deinitedNominal->getBaseName());
702-
}
703-
diagnose(astContext, consumingUser,
704-
diag::sil_moveonlychecker_consuming_use_here);
705-
astContext.Diags.diagnose(deinitedNominal->getValueTypeDestructor(),
706-
diag::sil_moveonlychecker_deinit_here);
699+
// point to the deinit if we know where it is.
700+
if (auto deinitLoc =
701+
deinitedNominal->getValueTypeDestructor()->getLoc(/*SerializedOK=*/false))
702+
astContext.Diags.diagnose(deinitLoc, diag::sil_moveonlychecker_deinit_here);
707703
}

test/SILOptimizer/moveonly_addresschecker_destructure_through_deinit_diagnostics.swift

Lines changed: 30 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,7 @@ struct DeinitStruct : ~Copyable {
6464
var fourth: (MoveOnlyKlass, MoveOnlyKlass)
6565
var fifth: MoveOnlyKlass
6666

67-
deinit {}
68-
// expected-note @-1 {{deinit declared here}}
69-
// expected-note @-2 {{deinit declared here}}
70-
// expected-note @-3 {{deinit declared here}}
71-
// expected-note @-4 {{deinit declared here}}
72-
// expected-note @-5 {{deinit declared here}}
73-
// expected-note @-6 {{deinit declared here}}
74-
// expected-note @-7 {{deinit declared here}}
75-
// expected-note @-8 {{deinit declared here}}
76-
// expected-note @-9 {{deinit declared here}}
77-
// expected-note @-10 {{deinit declared here}}
67+
deinit {} // expected-note 10{{deinit declared here}}
7868
}
7969

8070
func testConsumeCopyable(_ x: consuming DeinitStruct) {
@@ -84,24 +74,24 @@ func testConsumeCopyable(_ x: consuming DeinitStruct) {
8474
}
8575

8676
func testConsumeNonCopyable1(_ x: consuming DeinitStruct) {
87-
// expected-error @-1 {{Cannot partially consume 'x' since it has a user defined deinit}}
88-
consume(x.third.rhs) // expected-note {{consuming use here}}
77+
// expected-error @+1 {{cannot partially consume 'x' since it has a user defined deinit}}
78+
consume(x.third.rhs)
8979
}
9080

9181
func testConsumeNonCopyable2(_ x: consuming DeinitStruct) {
92-
// expected-error @-1 {{Cannot partially consume 'x' since it has a user defined deinit}}
93-
consume(x.fourth.0) // expected-note {{consuming use here}}
82+
// expected-error @+1 {{cannot partially consume 'x' since it has a user defined deinit}}
83+
consume(x.fourth.0)
9484
}
9585

9686
func testConsumeNonCopyable3(_ x: consuming DeinitStruct) {
97-
// expected-error @-1 {{Cannot partially consume 'x' since it has a user defined deinit}}
98-
consume(x.fourth.1) // expected-note {{consuming use here}}
87+
// expected-error @+1 {{cannot partially consume 'x' since it has a user defined deinit}}
88+
consume(x.fourth.1)
9989
}
10090

10191

10292
func testConsumeNonCopyable4(_ x: consuming DeinitStruct) {
103-
// expected-error @-1 {{Cannot partially consume 'x' since it has a user defined deinit}}
104-
consume(x.fifth) // expected-note {{consuming use here}}
93+
// expected-error @+1 {{cannot partially consume 'x' since it has a user defined deinit}}
94+
consume(x.fifth)
10595
}
10696

10797

@@ -129,35 +119,35 @@ func testStructContainDeinitStructConsumeCopyable1(_ x: consuming StructContainD
129119
}
130120

131121

132-
func testStructContainStructContainDeinitStructConsumeNonCopyable1(_ x: consuming StructContainDeinitStruct) {
133-
// expected-error @-1 {{Cannot partially consume 'x' since it contains field 'x.first' whose type 'DeinitStruct' has a user defined deinit}}
134-
consume(x.first.third.rhs) // expected-note {{consuming use here}}
122+
func testStructContainStructContainDeinitStructConsumeNonCopyable1(_ xyz: consuming StructContainDeinitStruct) {
123+
// expected-error @+1 {{cannot partially consume 'xyz.first' since it has a user defined deinit}}
124+
consume(xyz.first.third.rhs)
135125
}
136126

137127
func testStructContainStructContainDeinitStructConsumeNonCopyable1a(_ x: consuming StructContainDeinitStruct) {
138-
// expected-error @-1 {{Cannot partially consume 'x' since it contains field 'x.second.0' whose type 'DeinitStruct' has a user defined deinit}}
139-
consume(x.second.0.third.rhs) // expected-note {{consuming use here}}
128+
// expected-error @+1 {{cannot partially consume 'x.second.0' since it has a user defined deinit}}
129+
consume(x.second.0.third.rhs)
140130
}
141131

142132
func testStructContainStructContainDeinitStructConsumeNonCopyable2(_ x: consuming StructContainDeinitStruct) {
143-
// expected-error @-1 {{Cannot partially consume 'x' since it contains field 'x.first' whose type 'DeinitStruct' has a user defined deinit}}
144-
consume(x.first.fourth.0) // expected-note {{consuming use here}}
133+
// expected-error @+1 {{cannot partially consume 'x.first' since it has a user defined deinit}}
134+
consume(x.first.fourth.0)
145135
}
146136

147137
func testStructContainStructContainDeinitStructConsumeNonCopyable2a(_ x: consuming StructContainDeinitStruct) {
148-
// expected-error @-1 {{Cannot partially consume 'x' since it contains field 'x.second.1' whose type 'DeinitStruct' has a user defined deinit}}
149-
consume(x.second.1.fourth.0) // expected-note {{consuming use here}}
138+
// expected-error @+1 {{cannot partially consume 'x.second.1' since it has a user defined deinit}}
139+
consume(x.second.1.fourth.0)
150140
}
151141

152142
func testStructContainStructContainDeinitStructConsumeNonCopyable3(_ x: consuming StructContainDeinitStruct) {
153-
// expected-error @-1 {{Cannot partially consume 'x' since it contains field 'x.first' whose type 'DeinitStruct' has a user defined deinit}}
154-
consume(x.first.fourth.1) // expected-note {{consuming use here}}
143+
// expected-error @+1 {{cannot partially consume 'x.first' since it has a user defined deinit}}
144+
consume(x.first.fourth.1)
155145
}
156146

157147

158148
func testStructContainStructContainDeinitStructConsumeNonCopyable4(_ x: consuming StructContainDeinitStruct) {
159-
// expected-error @-1 {{Cannot partially consume 'x' since it contains field 'x.first' whose type 'DeinitStruct' has a user defined deinit}}
160-
consume(x.first.fifth) // expected-note {{consuming use here}}
149+
// expected-error @+1 {{cannot partially consume 'x.first' since it has a user defined deinit}}
150+
consume(x.first.fifth)
161151
}
162152

163153
////////////////////////
@@ -169,12 +159,7 @@ struct AddressOnlyDeinitStruct<T : P> : ~Copyable {
169159
var moveOnly = SingleIntContainingStruct()
170160
var moveOnlyPair = MoveOnlyPair()
171161

172-
deinit {}
173-
// expected-note @-1 {{deinit declared here}}
174-
// expected-note @-2 {{deinit declared here}}
175-
// expected-note @-3 {{deinit declared here}}
176-
// expected-note @-4 {{deinit declared here}}
177-
// expected-note @-5 {{deinit declared here}}
162+
deinit {} // expected-note 5{{deinitializer declared here}}
178163
}
179164

180165
func consume<T : P>(_ x: consuming AddressOnlyDeinitStruct<T>) {}
@@ -187,10 +172,8 @@ func testAddressOnlyCanConsumeEntireType<T : P>(_ x: consuming AddressOnlyDeinit
187172
}
188173

189174
func testAddressOnlyCannotPartialConsume<T : P>(_ x: consuming AddressOnlyDeinitStruct<T>) {
190-
// expected-error @-1 {{Cannot partially consume 'x' since it has a user defined deinit}}
191-
// expected-error @-2 {{Cannot partially consume 'x' since it has a user defined deinit}}
192-
consume(x.moveOnly) // expected-note {{consuming use here}}
193-
consume(x.moveOnlyPair.first) // expected-note {{consuming use here}}
175+
consume(x.moveOnly) // expected-error {{cannot partially consume 'x' when it has a deinitializer}}
176+
consume(x.moveOnlyPair.first) // expected-error {{cannot partially consume 'x' when it has a deinitializer}}
194177
consume(x.copyable)
195178
}
196179

@@ -199,17 +182,14 @@ struct AddressOnlyContainingDeinitStruct<T : P> : ~Copyable {
199182
}
200183

201184
func testAddressOnlyCannotPartialConsumeEvenIfSingleElt<T : P>(_ x: consuming AddressOnlyContainingDeinitStruct<T>) {
202-
// expected-error @-1 {{Cannot partially consume 'x' since it contains field 'x.a' whose type 'AddressOnlyDeinitStruct' has a user defined deinit}}
203-
204185
// We do not error here since we can partially consume x, but not x.a
205186
consume(x.a)
206-
consume(x.a.moveOnlyPair) // expected-note {{consuming use here}}
187+
consume(x.a.moveOnlyPair) // expected-error {{cannot partially consume 'x.a' when it has a deinitializer}}
207188
}
208189

209190
struct AddressOnlyContainingDeinitSingleField<T : P> : ~Copyable {
210191
var moveOnly = SingleIntContainingStruct()
211-
deinit {}
212-
// expected-note @-1 {{deinit declared here}}
192+
deinit {} // expected-note {{deinitializer declared here}}
213193
}
214194

215195
struct AddressOnlyContainingDeinitStruct3<T : P> : ~Copyable {
@@ -219,11 +199,9 @@ struct AddressOnlyContainingDeinitStruct3<T : P> : ~Copyable {
219199
func consume<T : P>(_ x: consuming AddressOnlyContainingDeinitSingleField<T>) {}
220200

221201
func testAddressOnlyCannotPartialConsumeEvenIfSingleElt<T : P>(_ x: consuming AddressOnlyContainingDeinitStruct3<T>) {
222-
// expected-error @-1 {{Cannot partially consume 'x' since it contains field 'x.a' whose type 'AddressOnlyContainingDeinitSingleField' has a user defined deinit}}
223-
224202
// We do not error here since we can partially consume x, but not x.a
225203
consume(x.a)
226-
consume(x.a.moveOnly) // expected-note {{consuming use here}}
204+
consume(x.a.moveOnly) // expected-error {{cannot partially consume 'x.a' when it has a deinitializer}}
227205
}
228206

229207

@@ -235,9 +213,7 @@ struct AddressOnlyContainingDeinitStructPair<T : P> : ~Copyable {
235213
// Make sure that if the deinit is in an intermediate element of the path that
236214
// we still handle it appropriately.
237215
func testAddressOnlyDeinitInMiddlePath<T : P>(_ x: consuming AddressOnlyContainingDeinitStructPair<T>) {
238-
// expected-error @-1 {{Cannot partially consume 'x' since it contains field 'x.first' whose type 'AddressOnlyDeinitStruct' has a user defined deinit}}
239-
// expected-error @-2 {{Cannot partially consume 'x' since it contains field 'x.first' whose type 'AddressOnlyDeinitStruct' has a user defined deinit}}
240-
consume(x.first.moveOnly) // expected-note {{consuming use here}}
241-
consume(x.first.moveOnlyPair.first) // expected-note {{consuming use here}}
216+
consume(x.first.moveOnly) // expected-error {{cannot partially consume 'x.first' when it has a deinitializer}}
217+
consume(x.first.moveOnlyPair.first) // expected-error {{cannot partially consume 'x.first' when it has a deinitializer}}
242218
consume(x.first.copyable)
243219
}

0 commit comments

Comments
 (0)