diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index 04586c5e..242e6b6a 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -4640,6 +4640,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) bool prevHadFallthrough = false; Dictionary handledCases; + HashSet condCases; for (BfSwitchCase* switchCase : switchStmt->mSwitchCases) { deferredLocalAssignDataVec[blockIdx].mScopeData = mCurMethodState->mCurScope; @@ -4810,22 +4811,42 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) } else if ((constantInt != NULL) && (!hadWhen) && (!isConstSwitch)) { - if (!hadConditional) + if (hadConditional) + { + condCases.Add(constantInt->mInt64); + } + else { _CaseState* caseState = NULL; handledCases.TryAdd(constantInt->mInt64, NULL, &caseState); - if (caseState->mUncondBlock) + if (condCases.Contains(constantInt->mInt64)) { - _ShowCaseError(constantInt->mInt64, caseExpr); + // This is a 'case .A:' after a 'case .A(let value):' + eqResult = mBfIRBuilder->CreateCmpEQ(enumTagVal.mValue, caseValue.mValue); + notEqBB = mBfIRBuilder->CreateBlock(StrFormat("switch.notEq.%d", blockIdx)); + + mayHaveMatch = true; + mBfIRBuilder->CreateCondBr(eqResult, caseBlock, notEqBB); + + mBfIRBuilder->AddBlock(notEqBB); + mBfIRBuilder->SetInsertPoint(notEqBB); } else { - caseState->mUncondBlock = doBlock; - mBfIRBuilder->AddSwitchCase(switchStatement, caseIntVal.mValue, doBlock); - hadConstIntVals = true; + if (caseState->mUncondBlock) + { + _ShowCaseError(constantInt->mInt64, caseExpr); + } + else + { + caseState->mUncondBlock = doBlock; + mBfIRBuilder->AddSwitchCase(switchStatement, caseIntVal.mValue, doBlock); + hadConstIntVals = true; + } } } + mayHaveMatch = true; } else if (!handled) diff --git a/IDEHelper/Tests/src/Enums.bf b/IDEHelper/Tests/src/Enums.bf index 44f014de..3f24b0bf 100644 --- a/IDEHelper/Tests/src/Enums.bf +++ b/IDEHelper/Tests/src/Enums.bf @@ -112,6 +112,26 @@ namespace Tests Test.Assert(false); } + switch (ee) + { + case .B(123): + Test.Assert(true); + case .B: + Test.Assert(false); + default: + Test.Assert(false); + } + + switch (ee) + { + case .A: + case .B(123): + Test.Assert(true); + case .B: + Test.Assert(false); + case .C: + } + EnumF ef = .EE(.C(3, 4)); switch (ef) {