@@ -815,7 +815,12 @@ SILInstruction *SILCombiner::visitIndexAddrInst(IndexAddrInst *IA) {
815815// / operation for \p value is required. This differs from a simple `isTrivial`
816816// / check, because it treats a value_to_bridge_object instruction as "trivial".
817817// / It can also handle non-trivial enums with trivial cases.
818- static bool isTrivial (SILValue value, SILFunction *function) {
818+ // /
819+ // / TODO: Define this as a top-level SILValue API. It needs to be updated
820+ // / whenever we refine the specification of isTrivial. For example, in the
821+ // / future we will check for the existence of a user-defined deinitializer and
822+ // / handle C++ types specially.
823+ static bool isValueTrivial (SILValue value, SILFunction *function) {
819824 SmallVector<ValueBase *, 32 > workList;
820825 SmallPtrSet<ValueBase *, 16 > visited;
821826 workList.push_back (value);
@@ -825,6 +830,11 @@ static bool isTrivial(SILValue value, SILFunction *function) {
825830 continue ;
826831 if (isa<ValueToBridgeObjectInst>(v))
827832 continue ;
833+
834+ // MoveOnly types may have a user-defined deinit.
835+ if (v->getType ().isPureMoveOnly ())
836+ return false ;
837+
828838 if (isa<StructInst>(v) || isa<TupleInst>(v)) {
829839 for (SILValue op : cast<SingleValueInstruction>(v)->getOperandValues ()) {
830840 if (visited.insert (op).second )
@@ -876,7 +886,7 @@ SILInstruction *SILCombiner::visitReleaseValueInst(ReleaseValueInst *RVI) {
876886 RVI->getAtomicity ());
877887
878888 // ReleaseValueInst of a trivial type is a no-op.
879- if (isTrivial (Operand, RVI->getFunction ()))
889+ if (isValueTrivial (Operand, RVI->getFunction ()))
880890 return eraseInstFromFunction (*RVI);
881891
882892 // Do nothing for non-trivial non-reference types.
@@ -2297,4 +2307,4 @@ SILCombiner::visitCopyAddrInst(CopyAddrInst *CAI) {
22972307 return Builder.createCopyAddr (
22982308 CAI->getLoc (), Src->getOperand (), Dst->getOperand (),
22992309 CAI->isTakeOfSrc (), CAI->isInitializationOfDest ());
2300- }
2310+ }
0 commit comments