mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-14 14:24:10 +02:00
Fixed false destructuring error
This commit is contained in:
parent
dd6e7f0c2a
commit
45edfc8604
3 changed files with 19 additions and 22 deletions
|
@ -3608,11 +3608,11 @@ void BfExprEvaluator::Visit(BfCaseExpression* caseExpr)
|
||||||
auto dscrType = caseValAddr.mType->ToTypeInstance()->GetDiscriminatorType(&dscrDataIdx);
|
auto dscrType = caseValAddr.mType->ToTypeInstance()->GetDiscriminatorType(&dscrDataIdx);
|
||||||
auto enumTagVal = mModule->LoadValue(mModule->ExtractValue(caseValAddr, NULL, 2));
|
auto enumTagVal = mModule->LoadValue(mModule->ExtractValue(caseValAddr, NULL, 2));
|
||||||
int uncondTagId = -1;
|
int uncondTagId = -1;
|
||||||
mResult = mModule->TryCaseEnumMatch(caseValAddr, enumTagVal, caseExpr->mCaseExpression, NULL, NULL, NULL, uncondTagId, hadConditional, clearOutOnMismatch);
|
mResult = mModule->TryCaseEnumMatch(caseValAddr, enumTagVal, caseExpr->mCaseExpression, NULL, NULL, NULL, uncondTagId, hadConditional, clearOutOnMismatch, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mResult = mModule->TryCaseTupleMatch(caseValAddr, tupleExpr, NULL, NULL, NULL, hadConditional, clearOutOnMismatch);
|
mResult = mModule->TryCaseTupleMatch(caseValAddr, tupleExpr, NULL, NULL, NULL, hadConditional, clearOutOnMismatch, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mResult)
|
if (mResult)
|
||||||
|
|
|
@ -1854,9 +1854,10 @@ public:
|
||||||
void CheckTupleVariableDeclaration(BfTupleExpression* tupleExpr, BfType* initType);
|
void CheckTupleVariableDeclaration(BfTupleExpression* tupleExpr, BfType* initType);
|
||||||
void HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl, BfTupleExpression* tupleExpr, BfTypedValue initTupleValue, bool isReadOnly, bool isConst, bool forceAddr, BfIRBlock* declBlock = NULL);
|
void HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl, BfTupleExpression* tupleExpr, BfTypedValue initTupleValue, bool isReadOnly, bool isConst, bool forceAddr, BfIRBlock* declBlock = NULL);
|
||||||
void HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl);
|
void HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl);
|
||||||
void HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArray<BfExpression*>& arguments, BfAstNode* tooFewRef, BfIRValue phiVal, BfIRBlock& matchedBlockStart, BfIRBlock& matchedBlockEnd, BfIRBlock& falseBlockStart, BfIRBlock& falseBlockEnd, bool& hadConditional, bool clearOutOnMismatch);
|
void HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArray<BfExpression*>& arguments, BfAstNode* tooFewRef, BfIRValue phiVal, BfIRBlock& matchedBlockStart,
|
||||||
BfTypedValue TryCaseTupleMatch(BfTypedValue tupleVal, BfTupleExpression* tupleExpr, BfIRBlock* eqBlock, BfIRBlock* notEqBlock, BfIRBlock* matchBlock, bool& hadConditional, bool clearOutOnMismatch);
|
BfIRBlock& matchedBlockEnd, BfIRBlock& falseBlockStart, BfIRBlock& falseBlockEnd, bool& hadConditional, bool clearOutOnMismatch, bool prevHadFallthrough);
|
||||||
BfTypedValue TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVal, BfExpression* expr, BfIRBlock* eqBlock, BfIRBlock* notEqBlock, BfIRBlock* matchBlock, int& uncondTagId, bool& hadConditional, bool clearOutOnMismatch);
|
BfTypedValue TryCaseTupleMatch(BfTypedValue tupleVal, BfTupleExpression* tupleExpr, BfIRBlock* eqBlock, BfIRBlock* notEqBlock, BfIRBlock* matchBlock, bool& hadConditional, bool clearOutOnMismatch, bool prevHadFallthrough);
|
||||||
|
BfTypedValue TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVal, BfExpression* expr, BfIRBlock* eqBlock, BfIRBlock* notEqBlock, BfIRBlock* matchBlock, int& uncondTagId, bool& hadConditional, bool clearOutOnMismatch, bool prevHadFallthrough);
|
||||||
BfTypedValue HandleCaseBind(BfTypedValue enumVal, const BfTypedValue& tagVal, BfEnumCaseBindExpression* bindExpr, BfIRBlock* eqBlock = NULL, BfIRBlock* notEqBlock = NULL, BfIRBlock* matchBlock = NULL, int* outEnumIdx = NULL);
|
BfTypedValue HandleCaseBind(BfTypedValue enumVal, const BfTypedValue& tagVal, BfEnumCaseBindExpression* bindExpr, BfIRBlock* eqBlock = NULL, BfIRBlock* notEqBlock = NULL, BfIRBlock* matchBlock = NULL, int* outEnumIdx = NULL);
|
||||||
void TryInitVar(BfAstNode* checkNode, BfLocalVariable* varDecl, BfTypedValue initValue, BfTypedValue& checkResult);
|
void TryInitVar(BfAstNode* checkNode, BfLocalVariable* varDecl, BfTypedValue initValue, BfTypedValue& checkResult);
|
||||||
BfLocalVariable* HandleVariableDeclaration(BfVariableDeclaration* varDecl, BfExprEvaluator* exprEvaluator = NULL);
|
BfLocalVariable* HandleVariableDeclaration(BfVariableDeclaration* varDecl, BfExprEvaluator* exprEvaluator = NULL);
|
||||||
|
|
|
@ -2256,7 +2256,7 @@ void BfModule::HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl)
|
||||||
AssertErrorState();
|
AssertErrorState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArray<BfExpression*>& arguments, BfAstNode* tooFewRef, BfIRValue phiVal, BfIRBlock& matchedBlockStart, BfIRBlock& matchedBlockEnd, BfIRBlock& falseBlockStart, BfIRBlock& falseBlockEnd, bool& hadConditional, bool clearOutOnMismatch)
|
void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArray<BfExpression*>& arguments, BfAstNode* tooFewRef, BfIRValue phiVal, BfIRBlock& matchedBlockStart, BfIRBlock& matchedBlockEnd, BfIRBlock& falseBlockStart, BfIRBlock& falseBlockEnd, bool& hadConditional, bool clearOutOnMismatch, bool prevHadFallthrough)
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<bool> prevInCondBlock(mCurMethodState->mInConditionalBlock);
|
SetAndRestoreValue<bool> prevInCondBlock(mCurMethodState->mInConditionalBlock);
|
||||||
|
|
||||||
|
@ -2316,6 +2316,10 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr
|
||||||
PopulateType(tupleElement.mType);
|
PopulateType(tupleElement.mType);
|
||||||
if (!isRef)
|
if (!isRef)
|
||||||
tupleElement = LoadValue(tupleElement);
|
tupleElement = LoadValue(tupleElement);
|
||||||
|
|
||||||
|
if (prevHadFallthrough)
|
||||||
|
Fail("Destructuring cannot be used when the previous case contains a fallthrough", expr);
|
||||||
|
|
||||||
auto localVar = HandleVariableDeclaration(varDecl, tupleElement, false, true);
|
auto localVar = HandleVariableDeclaration(varDecl, tupleElement, false, true);
|
||||||
localVar->mReadFromId = 0; // Don't give usage errors for binds
|
localVar->mReadFromId = 0; // Don't give usage errors for binds
|
||||||
continue;
|
continue;
|
||||||
|
@ -2337,7 +2341,7 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr
|
||||||
tooFewRef = tupleExpr->mValues[tupleExpr->mValues.size() - 1];
|
tooFewRef = tupleExpr->mValues[tupleExpr->mValues.size() - 1];
|
||||||
if (tooFewRef == NULL)
|
if (tooFewRef == NULL)
|
||||||
tooFewRef = tupleExpr->mOpenParen;
|
tooFewRef = tupleExpr->mOpenParen;
|
||||||
HandleCaseEnumMatch_Tuple(tupleElement, tupleExpr->mValues, tooFewRef, phiVal, matchedBlockStart, matchedBlockEnd, falseBlockStart, falseBlockEnd, hadConditional, clearOutOnMismatch);
|
HandleCaseEnumMatch_Tuple(tupleElement, tupleExpr->mValues, tooFewRef, phiVal, matchedBlockStart, matchedBlockEnd, falseBlockStart, falseBlockEnd, hadConditional, clearOutOnMismatch, prevHadFallthrough);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2375,7 +2379,7 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr
|
||||||
|
|
||||||
int uncondTagId = -1;
|
int uncondTagId = -1;
|
||||||
bool hadConditional = false;
|
bool hadConditional = false;
|
||||||
exprResult = TryCaseEnumMatch(tupleElementAddr, enumTagVal, expr, NULL, NULL, NULL, uncondTagId, hadConditional, clearOutOnMismatch);
|
exprResult = TryCaseEnumMatch(tupleElementAddr, enumTagVal, expr, NULL, NULL, NULL, uncondTagId, hadConditional, clearOutOnMismatch, prevHadFallthrough);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2515,7 +2519,7 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypedValue BfModule::TryCaseTupleMatch(BfTypedValue tupleVal, BfTupleExpression* tupleExpr, BfIRBlock* eqBlock, BfIRBlock* notEqBlock, BfIRBlock* matchBlock, bool& hadConditional, bool clearOutOnMismatch)
|
BfTypedValue BfModule::TryCaseTupleMatch(BfTypedValue tupleVal, BfTupleExpression* tupleExpr, BfIRBlock* eqBlock, BfIRBlock* notEqBlock, BfIRBlock* matchBlock, bool& hadConditional, bool clearOutOnMismatch, bool prevHadFallthrough)
|
||||||
{
|
{
|
||||||
if (!tupleVal.mType->IsTuple())
|
if (!tupleVal.mType->IsTuple())
|
||||||
return BfTypedValue();
|
return BfTypedValue();
|
||||||
|
@ -2642,7 +2646,7 @@ BfTypedValue BfModule::TryCaseTupleMatch(BfTypedValue tupleVal, BfTupleExpressio
|
||||||
mBfIRBuilder->SetInsertPoint(matchedBlockStart);
|
mBfIRBuilder->SetInsertPoint(matchedBlockStart);
|
||||||
BfIRBlock matchedBlockEnd = matchedBlockStart;
|
BfIRBlock matchedBlockEnd = matchedBlockStart;
|
||||||
HandleCaseEnumMatch_Tuple(tupleVal, tupleExpr->mValues, tooFewRef, falseBlockStart ? BfIRValue() : phiVal, matchedBlockStart, matchedBlockEnd,
|
HandleCaseEnumMatch_Tuple(tupleVal, tupleExpr->mValues, tooFewRef, falseBlockStart ? BfIRValue() : phiVal, matchedBlockStart, matchedBlockEnd,
|
||||||
falseBlockStart ? falseBlockStart : doneBlockStart, falseBlockEnd ? falseBlockEnd : doneBlockEnd, hadConditional, clearOutOnMismatch);
|
falseBlockStart ? falseBlockStart : doneBlockStart, falseBlockEnd ? falseBlockEnd : doneBlockEnd, hadConditional, clearOutOnMismatch, prevHadFallthrough);
|
||||||
|
|
||||||
if (phiVal)
|
if (phiVal)
|
||||||
{
|
{
|
||||||
|
@ -2675,7 +2679,7 @@ BfTypedValue BfModule::TryCaseTupleMatch(BfTypedValue tupleVal, BfTupleExpressio
|
||||||
return GetDefaultTypedValue(boolType);
|
return GetDefaultTypedValue(boolType);
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVal, BfExpression* expr, BfIRBlock* eqBlock, BfIRBlock* notEqBlock, BfIRBlock* matchBlock, int& tagId, bool& hadConditional, bool clearOutOnMismatch)
|
BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVal, BfExpression* expr, BfIRBlock* eqBlock, BfIRBlock* notEqBlock, BfIRBlock* matchBlock, int& tagId, bool& hadConditional, bool clearOutOnMismatch, bool prevHadFallthrough)
|
||||||
{
|
{
|
||||||
auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(expr);
|
auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(expr);
|
||||||
if (invocationExpr == NULL)
|
if (invocationExpr == NULL)
|
||||||
|
@ -2916,7 +2920,7 @@ BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVa
|
||||||
|
|
||||||
HandleCaseEnumMatch_Tuple(tupleVal, invocationExpr->mArguments, tooFewRef, falseBlockStart ? BfIRValue() : phiVal, matchedBlockStart, matchedBlockEnd,
|
HandleCaseEnumMatch_Tuple(tupleVal, invocationExpr->mArguments, tooFewRef, falseBlockStart ? BfIRValue() : phiVal, matchedBlockStart, matchedBlockEnd,
|
||||||
falseBlockStart ? falseBlockStart : doneBlockStart, falseBlockEnd ? falseBlockEnd : doneBlockEnd,
|
falseBlockStart ? falseBlockStart : doneBlockStart, falseBlockEnd ? falseBlockEnd : doneBlockEnd,
|
||||||
hadConditional, clearOutOnMismatch);
|
hadConditional, clearOutOnMismatch, prevHadFallthrough);
|
||||||
|
|
||||||
///////
|
///////
|
||||||
|
|
||||||
|
@ -4499,14 +4503,6 @@ void BfModule::Visit(BfSwitchStatement* switchStmt)
|
||||||
hadWhen = true;
|
hadWhen = true;
|
||||||
whenExpr = checkWhenExpr;
|
whenExpr = checkWhenExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(caseExpr))
|
|
||||||
{
|
|
||||||
if (prevHadFallthrough)
|
|
||||||
{
|
|
||||||
Fail("Destructuring cannot be used when the previous case contains a fallthrough", caseExpr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wantsOpenedScope = isPayloadEnum || isTuple;
|
bool wantsOpenedScope = isPayloadEnum || isTuple;
|
||||||
|
@ -4555,7 +4551,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
eqTypedResult = TryCaseEnumMatch(switchValueAddr, enumTagVal, caseExpr, &caseBlock, ¬EqBB, &matchBlock, tagId, hadConditional, false);
|
eqTypedResult = TryCaseEnumMatch(switchValueAddr, enumTagVal, caseExpr, &caseBlock, ¬EqBB, &matchBlock, tagId, hadConditional, false, prevHadFallthrough);
|
||||||
if (hadConditional)
|
if (hadConditional)
|
||||||
hadCondCase = true;
|
hadCondCase = true;
|
||||||
}
|
}
|
||||||
|
@ -4579,7 +4575,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt)
|
||||||
notEqBB = mBfIRBuilder->CreateBlock(StrFormat("switch.notEq.%d", blockIdx), false);
|
notEqBB = mBfIRBuilder->CreateBlock(StrFormat("switch.notEq.%d", blockIdx), false);
|
||||||
|
|
||||||
BfIRBlock matchBlock;
|
BfIRBlock matchBlock;
|
||||||
BfTypedValue eqTypedResult = TryCaseTupleMatch(switchValue, tupleExpr, &caseBlock, ¬EqBB, &matchBlock, hadConditional, false);
|
BfTypedValue eqTypedResult = TryCaseTupleMatch(switchValue, tupleExpr, &caseBlock, ¬EqBB, &matchBlock, hadConditional, false, prevHadFallthrough);
|
||||||
if (hadConditional)
|
if (hadConditional)
|
||||||
hadCondCase = true;
|
hadCondCase = true;
|
||||||
if (eqTypedResult)
|
if (eqTypedResult)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue