Skip to content

Commit 4f6cce7

Browse files
authored
Merge pull request #59833 from gottesmm/pr-816f80a06afa9ee661f077ea89193ef1cce5ece6
[no-implicit-copy] A few small fixes.
2 parents 8364d5b + d2a8cd1 commit 4f6cce7

File tree

6 files changed

+56
-64
lines changed

6 files changed

+56
-64
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,9 @@ ERROR(sil_moveonlychecker_value_consumed_more_than_once, none,
729729
"'%0' consumed more than once", (StringRef))
730730
NOTE(sil_moveonlychecker_consuming_use_here, none,
731731
"consuming use", ())
732+
ERROR(sil_moveonlychecker_not_understand_mark_move, none,
733+
"Usage of @noImplicitCopy that the move checker does not know how to "
734+
"check!", ())
732735

733736
// move kills copyable values checker diagnostics
734737
ERROR(sil_movekillscopyablevalue_value_consumed_more_than_once, none,

include/swift/SIL/TypeLowering.h

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,6 @@ enum IsInfiniteType_t : bool {
169169
IsInfiniteType = true,
170170
};
171171

172-
/// Does this type contain a move only type that affects type lowering?
173-
enum IsMoveOnly_t : bool {
174-
IsNotMoveOnly = false,
175-
IsMoveOnly = true,
176-
};
177-
178172
/// Extended type information used by SIL.
179173
class TypeLowering {
180174
public:
@@ -190,7 +184,6 @@ class TypeLowering {
190184
TypeExpansionSensitiveFlag = 1 << 4,
191185
InfiniteFlag = 1 << 5,
192186
HasRawPointerFlag = 1 << 6,
193-
MoveOnlyFlag = 1 << 7,
194187
};
195188
// clang-format on
196189

@@ -205,15 +198,13 @@ class TypeLowering {
205198
IsAddressOnly_t isAddressOnly, IsResilient_t isResilient,
206199
IsTypeExpansionSensitive_t isTypeExpansionSensitive =
207200
IsNotTypeExpansionSensitive,
208-
HasRawPointer_t hasRawPointer = DoesNotHaveRawPointer,
209-
IsMoveOnly_t isMoveOnly = IsNotMoveOnly)
201+
HasRawPointer_t hasRawPointer = DoesNotHaveRawPointer)
210202
: Flags((isTrivial ? 0U : NonTrivialFlag) |
211203
(isFixedABI ? 0U : NonFixedABIFlag) |
212204
(isAddressOnly ? AddressOnlyFlag : 0U) |
213205
(isResilient ? ResilientFlag : 0U) |
214206
(isTypeExpansionSensitive ? TypeExpansionSensitiveFlag : 0U) |
215-
(hasRawPointer ? HasRawPointerFlag : 0U) |
216-
(isMoveOnly ? MoveOnlyFlag : 0U)) {}
207+
(hasRawPointer ? HasRawPointerFlag : 0U)) {}
217208

218209
constexpr bool operator==(RecursiveProperties p) const {
219210
return Flags == p.Flags;
@@ -240,36 +231,6 @@ class TypeLowering {
240231
return {IsTrivial, IsFixedABI, IsNotAddressOnly, IsResilient};
241232
}
242233

243-
static constexpr RecursiveProperties forMoveOnlyReference() {
244-
return {IsNotTrivial,
245-
IsFixedABI,
246-
IsNotAddressOnly,
247-
IsNotResilient,
248-
IsNotTypeExpansionSensitive,
249-
DoesNotHaveRawPointer,
250-
IsMoveOnly};
251-
}
252-
253-
static constexpr RecursiveProperties forMoveOnlyOpaque() {
254-
return {IsNotTrivial,
255-
IsNotFixedABI,
256-
IsAddressOnly,
257-
IsNotResilient,
258-
IsNotTypeExpansionSensitive,
259-
DoesNotHaveRawPointer,
260-
IsMoveOnly};
261-
}
262-
263-
static constexpr RecursiveProperties forMoveOnlyResilient() {
264-
return {IsTrivial,
265-
IsFixedABI,
266-
IsNotAddressOnly,
267-
IsResilient,
268-
IsNotTypeExpansionSensitive,
269-
DoesNotHaveRawPointer,
270-
IsMoveOnly};
271-
}
272-
273234
void addSubobject(RecursiveProperties other) {
274235
Flags |= other.Flags;
275236
}
@@ -296,9 +257,6 @@ class TypeLowering {
296257
IsInfiniteType_t isInfinite() const {
297258
return IsInfiniteType_t((Flags & InfiniteFlag) != 0);
298259
}
299-
IsMoveOnly_t isMoveOnlyWrapped() const {
300-
return IsMoveOnly_t((Flags & MoveOnlyFlag) != 0);
301-
}
302260

303261
void setNonTrivial() { Flags |= NonTrivialFlag; }
304262
void setNonFixedABI() { Flags |= NonFixedABIFlag; }
@@ -309,7 +267,6 @@ class TypeLowering {
309267
(isTypeExpansionSensitive ? TypeExpansionSensitiveFlag : 0);
310268
}
311269
void setInfinite() { Flags |= InfiniteFlag; }
312-
void setMoveOnly() { Flags |= MoveOnlyFlag; }
313270
};
314271

315272
private:

lib/SIL/IR/TypeLowering.cpp

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -244,24 +244,12 @@ namespace {
244244
RecursiveProperties::forReference());
245245
}
246246

247-
RecursiveProperties getMoveOnlyReferenceRecursiveProperties(
248-
IsTypeExpansionSensitive_t isSensitive) {
249-
return mergeIsTypeExpansionSensitive(isSensitive,
250-
RecursiveProperties::forReference());
251-
}
252-
253247
RecursiveProperties
254248
getOpaqueRecursiveProperties(IsTypeExpansionSensitive_t isSensitive) {
255249
return mergeIsTypeExpansionSensitive(isSensitive,
256250
RecursiveProperties::forOpaque());
257251
}
258252

259-
RecursiveProperties getMoveOnlyOpaqueRecursiveProperties(
260-
IsTypeExpansionSensitive_t isSensitive) {
261-
return mergeIsTypeExpansionSensitive(
262-
isSensitive, RecursiveProperties::forMoveOnlyOpaque());
263-
}
264-
265253
#define IMPL(TYPE, LOWERING) \
266254
RetTy visit##TYPE##Type(Can##TYPE##Type type, AbstractionPattern orig, \
267255
IsTypeExpansionSensitive_t isSensitive) { \
@@ -704,12 +692,12 @@ namespace {
704692
if (lowering.isAddressOnly()) {
705693
return asImpl().handleMoveOnlyAddressOnly(
706694
type->getCanonicalType(),
707-
getMoveOnlyOpaqueRecursiveProperties(isSensitive));
695+
getOpaqueRecursiveProperties(isSensitive));
708696
}
709697

710698
return asImpl().handleMoveOnlyReference(
711699
type->getCanonicalType(),
712-
getMoveOnlyReferenceRecursiveProperties(isSensitive));
700+
getReferenceRecursiveProperties(isSensitive));
713701
}
714702

715703
RetTy handleAggregateByProperties(CanType type, RecursiveProperties props) {

lib/SILOptimizer/Mandatory/MoveOnlyChecker.cpp

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -476,17 +476,28 @@ struct MoveOnlyChecker {
476476
MoveOnlyChecker(SILFunction *fn, DeadEndBlocks *deBlocks)
477477
: fn(fn), copyOfBorrowedProjectionChecker(deBlocks) {}
478478

479+
/// Search through the current function for candidate mark_must_check
480+
/// [noimplicitcopy]. If we find one that does not fit a pattern that we
481+
/// understand, emit an error diagnostic telling the programmer that the move
482+
/// checker did not know how to recognize this code pattern.
483+
///
484+
/// \returns true if we deleted a mark_must_check inst that we didn't
485+
/// recognize after emitting the diagnostic.
486+
bool searchForCandidateMarkMustChecks();
487+
479488
bool check(NonLocalAccessBlockAnalysis *accessBlockAnalysis,
480489
DominanceInfo *domTree);
481490
};
482491

483492
} // namespace
484493

485-
bool MoveOnlyChecker::check(NonLocalAccessBlockAnalysis *accessBlockAnalysis,
486-
DominanceInfo *domTree) {
494+
bool MoveOnlyChecker::searchForCandidateMarkMustChecks() {
495+
bool changed = false;
487496
for (auto &block : *fn) {
488-
for (auto &ii : block) {
489-
auto *mmci = dyn_cast<MarkMustCheckInst>(&ii);
497+
for (auto ii = block.begin(), ie = block.end(); ii != ie;) {
498+
auto *mmci = dyn_cast<MarkMustCheckInst>(&*ii);
499+
++ii;
500+
490501
if (!mmci || !mmci->isNoImplicitCopy())
491502
continue;
492503

@@ -496,6 +507,7 @@ bool MoveOnlyChecker::check(NonLocalAccessBlockAnalysis *accessBlockAnalysis,
496507
if (auto *bbi = dyn_cast<BeginBorrowInst>(cvi->getOperand())) {
497508
if (bbi->isLexical()) {
498509
moveIntroducersToProcess.insert(mmci);
510+
continue;
499511
}
500512
}
501513
}
@@ -505,11 +517,44 @@ bool MoveOnlyChecker::check(NonLocalAccessBlockAnalysis *accessBlockAnalysis,
505517
if (auto *bbi = dyn_cast<BeginBorrowInst>(cvi->getOperand())) {
506518
if (bbi->isLexical()) {
507519
moveIntroducersToProcess.insert(mmci);
520+
continue;
508521
}
509522
}
510523
}
524+
525+
// If we see a mark_must_check that is marked no implicit copy that we
526+
// don't understand, emit a diagnostic to fail the compilation. This
527+
// ensures that if someone marks something no implicit copy and we fail to
528+
// check it, we fail the compilation.
529+
//
530+
// We then RAUW the mark_must_check once we have emitted the error since
531+
// later passes expect that mark_must_check has been eliminated by
532+
// us. Since we are failing already, this is ok to do.
533+
diagnose(fn->getASTContext(), mmci->getLoc().getSourceLoc(),
534+
diag::sil_moveonlychecker_not_understand_mark_move);
535+
mmci->replaceAllUsesWith(mmci->getOperand());
536+
mmci->eraseFromParent();
537+
changed = true;
511538
}
512539
}
540+
return changed;
541+
}
542+
543+
bool MoveOnlyChecker::check(NonLocalAccessBlockAnalysis *accessBlockAnalysis,
544+
DominanceInfo *domTree) {
545+
bool changed = false;
546+
547+
// First search for candidates to process and emit diagnostics on any
548+
// mark_must_check [noimplicitcopy] we didn't recognize.
549+
changed |= searchForCandidateMarkMustChecks();
550+
551+
// If we didn't find any introducers to check, just return changed.
552+
//
553+
// NOTE: changed /can/ be true here if we had any mark_must_check
554+
// [noimplicitcopy] that we didn't understand and emitting a diagnostic upon
555+
// and then deleting.
556+
if (moveIntroducersToProcess.empty())
557+
return changed;
513558

514559
auto callbacks =
515560
InstModCallbacks().onDelete([&](SILInstruction *instToDelete) {
@@ -518,7 +563,6 @@ bool MoveOnlyChecker::check(NonLocalAccessBlockAnalysis *accessBlockAnalysis,
518563
instToDelete->eraseFromParent();
519564
});
520565
InstructionDeleter deleter(std::move(callbacks));
521-
bool changed = false;
522566

523567
SmallVector<Operand *, 32> consumingUsesNeedingCopy;
524568
auto foundConsumingUseNeedingCopy = [&](Operand *use) {

0 commit comments

Comments
 (0)