瀏覽代碼

Improved struct returns from mixins and block expressions

Brian Fiete 3 年之前
父節點
當前提交
e3ca70c153
共有 3 個文件被更改,包括 36 次插入0 次删除
  1. 15 0
      IDEHelper/Compiler/BfAst.h
  2. 11 0
      IDEHelper/Compiler/BfExprEvaluator.cpp
  3. 10 0
      IDEHelper/Tests/src/Mixins.bf

+ 15 - 0
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;
 };
 

+ 11 - 0
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -3403,6 +3403,11 @@ void BfExprEvaluator::Visit(BfBlock* blockExpr)
 
 	mModule->VisitEmbeddedStatement(blockExpr, this, BfNodeIsA<BfUnscopedBlock>(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)

+ 10 - 0
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<StringView> svRes = "ab ";
+			var sv2 = Unwrap!(svRes)..Trim();
+			Test.Assert(svRes.Value == "ab ");
+			Test.Assert(sv2 == "ab");
 		}
 
 	}