Skip to content

Commit 9ae7ff3

Browse files
committed
[move-only] Wire up emission of the location for non-consuming uses for objects and emit more precise errors for consuming use errors.
Specifically, previously if we emitted an error we just dumped all of the consuming uses. Now instead for each consuming use that needs a copy, we perform a search for a specific boundary use (consuming or non-consuming) that is reachable from the former and emit a specialized error for it. Thus we emit for the two consuming case the normal consumed twice error, and now for non-consuming errors we emit the "use after consume" error.
1 parent 20479c9 commit 9ae7ff3

14 files changed

+646
-459
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ ERROR(sil_moveonlychecker_owned_value_consumed_more_than_once, none,
730730
ERROR(sil_moveonlychecker_owned_value_consumed_and_used_at_same_time, none,
731731
"'%0' consumed and used at the same time", (StringRef))
732732
ERROR(sil_moveonlychecker_value_used_after_consume, none,
733-
"'%0' used after consume. Lifetime extension of variable requires a copy", (StringRef))
733+
"'%0' used after consume", (StringRef))
734734
ERROR(sil_moveonlychecker_guaranteed_value_consumed, none,
735735
"'%0' has guaranteed ownership but was consumed", (StringRef))
736736
ERROR(sil_moveonlychecker_guaranteed_value_captured_by_closure, none,
@@ -754,6 +754,8 @@ NOTE(sil_moveonlychecker_boundary_use, none,
754754
"boundary use here", ())
755755
NOTE(sil_moveonlychecker_consuming_use_here, none,
756756
"consuming use here", ())
757+
NOTE(sil_moveonlychecker_other_consuming_use_here, none,
758+
"other consuming use here", ())
757759
NOTE(sil_moveonlychecker_two_consuming_uses_here, none,
758760
"two consuming uses here", ())
759761
NOTE(sil_moveonlychecker_consuming_and_non_consuming_uses_here, none,
@@ -762,6 +764,9 @@ NOTE(sil_moveonlychecker_consuming_closure_use_here, none,
762764
"closure capture here", ())
763765
NOTE(sil_moveonlychecker_nonconsuming_use_here, none,
764766
"non-consuming use here", ())
767+
NOTE(sil_movekillscopyablevalue_value_cyclic_consumed_in_loop_here, none,
768+
"consuming in loop use here", ())
769+
765770
ERROR(sil_moveonlychecker_not_understand_no_implicit_copy, none,
766771
"Usage of @noImplicitCopy that the move checker does not know how to "
767772
"check!", ())

include/swift/SIL/PrunedLiveness.h

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ class PrunedLiveness {
553553
/// A namespace containing helper functors for use with various mapped
554554
/// ranges. Intended to be used to hide these noise types when working in an
555555
/// IDE.
556-
struct LifetimeEndingUserIteratorHelpers {
556+
struct RangeIterationHelpers {
557557
struct MapFunctor {
558558
SILInstruction *
559559
operator()(const std::pair<SILInstruction *, bool> &pair) const {
@@ -562,27 +562,56 @@ class PrunedLiveness {
562562
}
563563
};
564564

565-
struct FilterFunctor {
566-
bool operator()(const std::pair<SILInstruction *, bool> &pair) const {
567-
return pair.second;
568-
}
565+
struct LifetimeEnding {
566+
struct FilterFunctor {
567+
bool operator()(const std::pair<SILInstruction *, bool> &pair) const {
568+
return pair.second;
569+
}
570+
};
571+
572+
using MapFilterIter = llvm::mapped_iterator<
573+
llvm::filter_iterator<const std::pair<SILInstruction *, bool> *,
574+
FilterFunctor>,
575+
MapFunctor>;
569576
};
570577

571-
using MapFilterIter = llvm::mapped_iterator<
572-
llvm::filter_iterator<const std::pair<SILInstruction *, bool> *,
573-
FilterFunctor>,
574-
MapFunctor>;
578+
struct NonLifetimeEnding {
579+
struct FilterFunctor {
580+
bool operator()(const std::pair<SILInstruction *, bool> &pair) const {
581+
return !pair.second;
582+
}
583+
};
584+
585+
using MapFilterIter = llvm::mapped_iterator<
586+
llvm::filter_iterator<const std::pair<SILInstruction *, bool> *,
587+
FilterFunctor>,
588+
MapFunctor>;
589+
};
575590
};
576-
using LifetimeEndingUserRange =
577-
llvm::iterator_range<LifetimeEndingUserIteratorHelpers::MapFilterIter>;
591+
using LifetimeEndingUserRange = llvm::iterator_range<
592+
RangeIterationHelpers::LifetimeEnding::MapFilterIter>;
578593

579594
/// Return a range consisting of the current set of consuming users fed into
580595
/// this PrunedLiveness instance.
581596
LifetimeEndingUserRange getLifetimeEndingUsers() const {
582597
return map_range(
583598
llvm::make_filter_range(
584-
getAllUsers(), LifetimeEndingUserIteratorHelpers::FilterFunctor()),
585-
LifetimeEndingUserIteratorHelpers::MapFunctor());
599+
getAllUsers(),
600+
RangeIterationHelpers::LifetimeEnding::FilterFunctor()),
601+
RangeIterationHelpers::MapFunctor());
602+
}
603+
604+
using NonLifetimeEndingUserRange = llvm::iterator_range<
605+
RangeIterationHelpers::NonLifetimeEnding::MapFilterIter>;
606+
607+
/// Return a range consisting of the current set of non lifetime ending users
608+
/// fed into this PrunedLiveness instance.
609+
NonLifetimeEndingUserRange getNonLifetimeEndingUsers() const {
610+
return map_range(
611+
llvm::make_filter_range(
612+
getAllUsers(),
613+
RangeIterationHelpers::NonLifetimeEnding::FilterFunctor()),
614+
RangeIterationHelpers::MapFunctor());
586615
}
587616

588617
void print(llvm::raw_ostream &OS) const;

include/swift/SILOptimizer/Utils/CanonicalizeOSSALifetime.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,11 @@ class CanonicalizeOSSALifetime final {
360360
return liveness.getLifetimeEndingUsers();
361361
}
362362

363+
using NonLifetimeEndingUserRange = PrunedLiveness::NonLifetimeEndingUserRange;
364+
NonLifetimeEndingUserRange getNonLifetimeEndingUsers() const {
365+
return liveness.getNonLifetimeEndingUsers();
366+
}
367+
363368
using UserRange = PrunedLiveness::ConstUserRange;
364369
UserRange getUsers() const { return liveness.getAllUsers(); }
365370

0 commit comments

Comments
 (0)