@@ -47,28 +47,48 @@ SILValue SILGenFunction::emitSelfDeclForDestructor(VarDecl *selfDecl) {
4747 selfType = F.mapTypeIntoContext (selfType);
4848 SILValue selfValue = F.begin ()->createFunctionArgument (selfType, selfDecl);
4949
50+ uint16_t ArgNo = 1 ; // Hardcoded for destructors.
51+ auto dv = SILDebugVariable (selfDecl->isLet (), ArgNo);
52+
5053 // If we have a move only type, then mark it with
5154 // mark_unresolved_non_copyable_value so we can't escape it.
52- if (selfType.isMoveOnly ()) {
53- // For now, we do not handle move only class deinits. This is because we
54- // need to do a bit more refactoring to handle the weird way that it deals
55- // with ownership. But for simple move only deinits (like struct/enum), that
56- // are owned, lets mark them as needing to be no implicit copy checked so
57- // they cannot escape.
58- if (selfValue->getOwnershipKind () == OwnershipKind::Owned) {
59- selfValue = B.createMarkUnresolvedNonCopyableValueInst (
60- selfDecl, selfValue,
55+ //
56+ // For now, we do not handle move only class deinits. This is because we need
57+ // to do a bit more refactoring to handle the weird way that it deals with
58+ // ownership. But for simple move only deinits (like struct/enum), that are
59+ // owned, lets mark them as needing to be no implicit copy checked so they
60+ // cannot escape.
61+ if (selfType.isMoveOnly () && !selfType.isAnyClassReferenceType ()) {
62+ if (getASTContext ().LangOpts .hasFeature (
63+ Feature::MoveOnlyPartialConsumption)) {
64+ SILValue addr = B.createAllocStack (selfDecl, selfValue->getType (), dv);
65+ addr = B.createMarkUnresolvedNonCopyableValueInst (
66+ selfDecl, addr,
6167 MarkUnresolvedNonCopyableValueInst::CheckKind::
6268 ConsumableAndAssignable);
69+ if (selfValue->getType ().isObject ()) {
70+ B.createStore (selfDecl, selfValue, addr, StoreOwnershipQualifier::Init);
71+ } else {
72+ B.createCopyAddr (selfDecl, selfValue, addr, IsTake, IsInitialization);
73+ }
74+ // drop_deinit invalidates any user-defined struct/enum deinit
75+ // before the individual members are destroyed.
76+ addr = B.createDropDeinit (selfDecl, addr);
77+ selfValue = addr;
78+ } else {
79+ if (selfValue->getOwnershipKind () == OwnershipKind::Owned) {
80+ selfValue = B.createMarkUnresolvedNonCopyableValueInst (
81+ selfDecl, selfValue,
82+ MarkUnresolvedNonCopyableValueInst::CheckKind::
83+ ConsumableAndAssignable);
84+ }
6385 }
6486 }
6587
6688 VarLocs[selfDecl] = VarLoc::get (selfValue);
6789 SILLocation PrologueLoc (selfDecl);
6890 PrologueLoc.markAsPrologue ();
69- uint16_t ArgNo = 1 ; // Hardcoded for destructors.
70- B.createDebugValue (PrologueLoc, selfValue,
71- SILDebugVariable (selfDecl->isLet (), ArgNo));
91+ B.createDebugValue (PrologueLoc, selfValue, dv);
7292 return selfValue;
7393}
7494
0 commit comments