diff --git a/IDEHelper/Compiler/BfAst.h b/IDEHelper/Compiler/BfAst.h index 86457f95..2c2eac7d 100644 --- a/IDEHelper/Compiler/BfAst.h +++ b/IDEHelper/Compiler/BfAst.h @@ -798,6 +798,21 @@ public: } } + void MakeTemporary(bool restricted = false) + { + switch (mKind) + { + case BfTypedValueKind_Addr: + mKind = restricted ? BfTypedValueKind_RestrictedTempAddr : BfTypedValueKind_TempAddr; + break; + case BfTypedValueKind_ReadOnlyAddr: + mKind = BfTypedValueKind_ReadOnlyTempAddr; + break; + default: + break; + } + } + bool CanModify() const; }; diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index ed75baf9..cde323dc 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -3403,6 +3403,11 @@ void BfExprEvaluator::Visit(BfBlock* blockExpr) mModule->VisitEmbeddedStatement(blockExpr, this, BfNodeIsA(blockExpr) ? BfEmbeddedStatementFlags_Unscoped : BfEmbeddedStatementFlags_None); mResult = mModule->SanitizeAddr(mResult); + if ((mResult) && (mResult.mType->IsStruct())) + { + mResult = mModule->MakeAddressable(mResult, true); + mResult.MakeTemporary(true); + } } bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail) @@ -17248,6 +17253,12 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo mModule->mBfIRBuilder->RestoreDebugLocation(); mModule->mBfIRBuilder->DupDebugLocation(); + + if ((mResult) && (mResult.mType->IsStruct())) + { + mResult = mModule->MakeAddressable(mResult, true); + mResult.MakeTemporary(true); + } } void BfExprEvaluator::SetMethodElementType(BfAstNode* target) diff --git a/IDEHelper/Tests/src/Mixins.bf b/IDEHelper/Tests/src/Mixins.bf index 993e06b9..33f31501 100644 --- a/IDEHelper/Tests/src/Mixins.bf +++ b/IDEHelper/Tests/src/Mixins.bf @@ -79,6 +79,11 @@ namespace Tests ref a } + static mixin Unwrap(var res) + { + res.Value + } + [Test] public static void TestBasics() { @@ -139,6 +144,11 @@ namespace Tests var c = { ref b }; c = 99; Test.Assert(b == 99); + + Result svRes = "ab "; + var sv2 = Unwrap!(svRes)..Trim(); + Test.Assert(svRes.Value == "ab "); + Test.Assert(sv2 == "ab"); } }