1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 20:12:21 +02:00

Allow 'ref' on case matching

This commit is contained in:
Brian Fiete 2025-02-04 06:45:05 -08:00
parent b92b561867
commit 8b7dd19f4b

View file

@ -2381,6 +2381,7 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr
BfTypedValue mArgValue; BfTypedValue mArgValue;
BfTypedValue mTupleElement; BfTypedValue mTupleElement;
int mFieldIdx; int mFieldIdx;
bool mIsOut;
}; };
Array<DeferredAssign> deferredAssigns; Array<DeferredAssign> deferredAssigns;
@ -2532,7 +2533,7 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr
BfExprEvaluator exprEvaluator(this); BfExprEvaluator exprEvaluator(this);
exprEvaluator.mExpectingType = tupleFieldInstance->GetResolvedType(); exprEvaluator.mExpectingType = tupleFieldInstance->GetResolvedType();
exprEvaluator.mBfEvalExprFlags = BfEvalExprFlags_AllowOutExpr; exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(BfEvalExprFlags_AllowOutExpr | BfEvalExprFlags_AllowRefExpr);
if (mCurMethodState->mDeferredLocalAssignData != NULL) if (mCurMethodState->mDeferredLocalAssignData != NULL)
{ {
SetAndRestoreValue<bool> prevIsIfCondition(mCurMethodState->mDeferredLocalAssignData->mIsIfCondition, true); SetAndRestoreValue<bool> prevIsIfCondition(mCurMethodState->mDeferredLocalAssignData->mIsIfCondition, true);
@ -2554,16 +2555,20 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr
if (argValue.mType->IsRef()) if (argValue.mType->IsRef())
{ {
auto refType = (BfRefType*)argValue.mType; auto refType = (BfRefType*)argValue.mType;
if (refType->mRefKind != BfRefType::RefKind_Out) bool isOut = refType->mRefKind == BfRefType::RefKind_Out;
if ((refType->mRefKind != BfRefType::RefKind_Out) && (refType->mRefKind != BfRefType::RefKind_Ref))
{ {
BfAstNode* refNode = expr; BfAstNode* refNode = expr;
if (auto unaryOperatorExpr = BfNodeDynCast<BfUnaryOperatorExpression>(expr)) if (auto unaryOperatorExpr = BfNodeDynCast<BfUnaryOperatorExpression>(expr))
refNode = unaryOperatorExpr->mOpToken; refNode = unaryOperatorExpr->mOpToken;
Fail("Only 'out' refs can be used to assign to an existing value", refNode); Fail("Invalid ref type", refNode);
} }
DeferredAssign deferredAssign = { expr, argValue, tupleElement, tupleFieldIdx }; DeferredAssign deferredAssign = { expr, argValue, tupleElement, tupleFieldIdx, isOut };
deferredAssigns.push_back(deferredAssign); deferredAssigns.push_back(deferredAssign);
if (isOut)
{
if (mCurMethodState->mDeferredLocalAssignData != NULL) if (mCurMethodState->mDeferredLocalAssignData != NULL)
{ {
SetAndRestoreValue<bool> prevIsIfCondition(mCurMethodState->mDeferredLocalAssignData->mIsIfCondition, true); SetAndRestoreValue<bool> prevIsIfCondition(mCurMethodState->mDeferredLocalAssignData->mIsIfCondition, true);
@ -2574,6 +2579,7 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr
{ {
exprEvaluator.MarkResultAssigned(); exprEvaluator.MarkResultAssigned();
} }
}
continue; continue;
} }
@ -2626,6 +2632,9 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr
mBfIRBuilder->SetInsertPoint(falseBlockEnd); mBfIRBuilder->SetInsertPoint(falseBlockEnd);
for (auto& deferredAssign : deferredAssigns) for (auto& deferredAssign : deferredAssigns)
{ {
if (!deferredAssign.mIsOut)
continue;
auto tupleFieldInstance = &tupleType->mFieldInstances[deferredAssign.mFieldIdx]; auto tupleFieldInstance = &tupleType->mFieldInstances[deferredAssign.mFieldIdx];
// We have to re-process the expr because we haven't done it in this branch, and then clear the result out // We have to re-process the expr because we haven't done it in this branch, and then clear the result out
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, mHadBuildError); // Don't fail twice SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, mHadBuildError); // Don't fail twice