@@ -552,6 +552,74 @@ class LetValueInitialization : public Initialization {
552
552
SplitCleanups);
553
553
}
554
554
555
+ // / This is a helper method for bindValue that handles any changes to the
556
+ // / value needed for lexical lifetime or no implicit copy purposes.
557
+ SILValue getValueForLexicalLifetimeBinding (SILGenFunction &SGF,
558
+ SILLocation PrologueLoc,
559
+ SILValue value, bool wasPlusOne) {
560
+ // If we have none...
561
+ if (value->getOwnershipKind () == OwnershipKind::None) {
562
+ // ... and we don't have a no implicit copy trivial type, just return
563
+ // value.
564
+ if (!SGF.getASTContext ().LangOpts .Features .count (Feature::MoveOnly) ||
565
+ !vd->getAttrs ().hasAttribute <NoImplicitCopyAttr>() ||
566
+ !value->getType ().isTrivial (SGF.F ))
567
+ return value;
568
+
569
+ // Otherwise, we have a no implicit copy trivial type, so wrap it in the
570
+ // move only wrapper and mark it as needing checking by the move cherk.
571
+ value =
572
+ SGF.B .createOwnedCopyableToMoveOnlyWrapperValue (PrologueLoc, value);
573
+ value = SGF.B .createMoveValue (PrologueLoc, value, /* isLexical*/ true );
574
+ return SGF.B .createMarkMustCheckInst (
575
+ PrologueLoc, value, MarkMustCheckInst::CheckKind::NoImplicitCopy);
576
+ }
577
+
578
+ // Then if we don't have move only, just perform a lexical borrow.
579
+ if (!SGF.getASTContext ().LangOpts .Features .count (Feature::MoveOnly))
580
+ return SGF.B .createBeginBorrow (PrologueLoc, value, /* isLexical*/ true );
581
+
582
+ // Otherwise, we need to perform some additional processing. First, if we
583
+ // have an owned moveonly value that had a cleanup, then create a move_value
584
+ // that acts as a consuming use of the value. The reason why we want this is
585
+ // even if we are only performing a borrow for our lexical lifetime, we want
586
+ // to ensure that our defs see this initialization as consuming this value.
587
+ if (value->getOwnershipKind () == OwnershipKind::Owned) {
588
+ assert (wasPlusOne);
589
+ // NOTE: If our type is trivial when not wrapped in a
590
+ // SILMoveOnlyWrappedType, this will return a trivial value. We rely
591
+ // on the checker to determine if this is an acceptable use of the
592
+ // value.
593
+ if (value->getType ().isMoveOnly ()) {
594
+ if (value->getType ().isMoveOnlyWrapped ()) {
595
+ value = SGF.B .createOwnedMoveOnlyWrapperToCopyableValue (PrologueLoc,
596
+ value);
597
+ } else {
598
+ // Change this to be lexical and get rid of borrow scope?
599
+ value = SGF.B .createMoveValue (PrologueLoc, value);
600
+ }
601
+ }
602
+ }
603
+
604
+ // If we still have a trivial thing, just return that.
605
+ if (value->getType ().isTrivial (SGF.F ))
606
+ return value;
607
+
608
+ // Otherwise, if we do not have a no implicit copy variable, just do a
609
+ // borrow lexical.
610
+ if (!vd->getAttrs ().hasAttribute <NoImplicitCopyAttr>())
611
+ return SGF.B .createBeginBorrow (PrologueLoc, value, /* isLexical*/ true );
612
+
613
+ // If we have a no implicit copy lexical, emit the instruction stream so
614
+ // that the move checker knows to check this variable.
615
+ value = SGF.B .createBeginBorrow (PrologueLoc, value,
616
+ /* isLexical*/ true );
617
+ value = SGF.B .createCopyValue (PrologueLoc, value);
618
+ value = SGF.B .createOwnedCopyableToMoveOnlyWrapperValue (PrologueLoc, value);
619
+ return SGF.B .createMarkMustCheckInst (
620
+ PrologueLoc, value, MarkMustCheckInst::CheckKind::NoImplicitCopy);
621
+ }
622
+
555
623
void bindValue (SILValue value, SILGenFunction &SGF, bool wasPlusOne) {
556
624
assert (!SGF.VarLocs .count (vd) && " Already emitted this vardecl?" );
557
625
// If we're binding an address to this let value, then we can use it as an
@@ -562,66 +630,8 @@ class LetValueInitialization : public Initialization {
562
630
SILLocation PrologueLoc (vd);
563
631
564
632
if (SGF.getASTContext ().SILOpts .supportsLexicalLifetimes (SGF.getModule ())) {
565
- if (value->getOwnershipKind () != OwnershipKind::None) {
566
- if (!SGF.getASTContext ().LangOpts .Features .count (Feature::MoveOnly)) {
567
- value =
568
- SGF.B .createBeginBorrow (PrologueLoc, value, /* isLexical*/ true );
569
- } else {
570
- // If we have an owned moveonly value that had a cleanup, then create
571
- // a move_value that acts as a consuming use of the value. The reason
572
- // why we want this is even if we are only performing a borrow for our
573
- // lexical lifetime, we want to ensure that our defs see this
574
- // initialization as consuming this value.
575
- if (value->getOwnershipKind () == OwnershipKind::Owned) {
576
- assert (wasPlusOne);
577
- // NOTE: If our type is trivial when not wrapped in a
578
- // SILMoveOnlyWrappedType, this will return a trivial value. We rely
579
- // on the checker to determine if this is an acceptable use of the
580
- // value.
581
- if (value->getType ().isMoveOnly ()) {
582
- if (value->getType ().isMoveOnlyWrapped ()) {
583
- value = SGF.B .createOwnedMoveOnlyWrapperToCopyableValue (
584
- PrologueLoc, value);
585
- } else {
586
- // Change this to be lexical and get rid of borrow scope?
587
- value = SGF.B .createMoveValue (PrologueLoc, value);
588
- }
589
- }
590
- }
591
-
592
- // If we still have a non-trivial thing, emit code that will need to
593
- // be cleaned up. If we are now trivial, we do not need to cleanup
594
- // anything.
595
- if (!value->getType ().isTrivial (SGF.F )) {
596
- if (vd->getAttrs ().hasAttribute <NoImplicitCopyAttr>()) {
597
- value = SGF.B .createBeginBorrow (PrologueLoc, value,
598
- /* isLexical*/ true );
599
- value = SGF.B .createCopyValue (PrologueLoc, value);
600
- value = SGF.B .createOwnedCopyableToMoveOnlyWrapperValue (
601
- PrologueLoc, value);
602
- value = SGF.B .createMarkMustCheckInst (
603
- PrologueLoc, value,
604
- MarkMustCheckInst::CheckKind::NoImplicitCopy);
605
- } else {
606
- value = SGF.B .createBeginBorrow (PrologueLoc, value,
607
- /* isLexical*/ true );
608
- }
609
- }
610
- }
611
- } else {
612
- if (SGF.getASTContext ().LangOpts .Features .count (Feature::MoveOnly) &&
613
- vd->getAttrs ().hasAttribute <NoImplicitCopyAttr>() &&
614
- value->getType ().isTrivial (SGF.F )) {
615
- // We are abusing this. This should be a separate instruction just for
616
- // converting from copyable trivial to move only. I am abusing it
617
- // here by using it multiple times in different ways.
618
- value = SGF.B .createOwnedCopyableToMoveOnlyWrapperValue (PrologueLoc,
619
- value);
620
- value = SGF.B .createMoveValue (PrologueLoc, value, /* isLexical*/ true );
621
- value = SGF.B .createMarkMustCheckInst (
622
- PrologueLoc, value, MarkMustCheckInst::CheckKind::NoImplicitCopy);
623
- }
624
- }
633
+ value = getValueForLexicalLifetimeBinding (SGF, PrologueLoc, value,
634
+ wasPlusOne);
625
635
}
626
636
627
637
SGF.VarLocs [vd] = SILGenFunction::VarLoc::get (value);
0 commit comments