diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 0de3463c..ce7b8faf 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -8246,6 +8246,20 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst if (argValue) { + if ((argValue.mType->IsRef()) && (argValue.mType->GetUnderlyingType() == resolvedFieldType)) + { + if (auto unaryOperator = BfNodeDynCast(argValues.mResolvedArgs[tupleFieldIdx].mExpression)) + { + mModule->Fail(StrFormat("Invalid use of '%s'. Enum payloads can only be retrieved through 'case' expressions.", BfGetOpName(unaryOperator->mOp)), unaryOperator->mOpToken); + argValue = mModule->GetDefaultTypedValue(resolvedFieldType); + } + else if (auto varDecl = BfNodeDynCast(argValues.mResolvedArgs[tupleFieldIdx].mExpression)) + { + mModule->Fail("Invalid variable declaration. Enum payloads can only be retrieved through 'case' expressions.", varDecl); + argValue = mModule->GetDefaultTypedValue(resolvedFieldType); + } + } + // argValue can have a value even if tuplePtr does not have a value. This can happen if we are assigning to a (void) tuple, // but we have a value that needs to be attempted to be casted to void argValue = mModule->Cast(argValues.mResolvedArgs[tupleFieldIdx].mExpression, argValue, resolvedFieldType, wantConst ? BfCastFlags_WantsConst : BfCastFlags_None); diff --git a/IDEHelper/Compiler/BfReducer.cpp b/IDEHelper/Compiler/BfReducer.cpp index 4f923bb7..49fc4efe 100644 --- a/IDEHelper/Compiler/BfReducer.cpp +++ b/IDEHelper/Compiler/BfReducer.cpp @@ -2571,7 +2571,7 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat } if (caseExpr->mCaseExpression == NULL) { - auto expr = CreateExpressionAfter(caseExpr, (CreateExprFlags)(CreateExprFlags_NoAssignment | CreateExprFlags_PermissiveVariableDecl)); + auto expr = CreateExpressionAfter(caseExpr, (CreateExprFlags)(CreateExprFlags_NoAssignment | CreateExprFlags_PermissiveVariableDecl | CreateExprFlags_EarlyExit)); if (expr == NULL) continue; MEMBER_SET(caseExpr, mCaseExpression, expr); diff --git a/IDEHelper/Compiler/BfSystem.cpp b/IDEHelper/Compiler/BfSystem.cpp index 50c66585..802ae90a 100644 --- a/IDEHelper/Compiler/BfSystem.cpp +++ b/IDEHelper/Compiler/BfSystem.cpp @@ -1124,15 +1124,16 @@ bool BfPassInstance::WantsRangeRecorded(BfSourceData* bfSource, int srcIdx, int if (bfSource == NULL) return true; - if (!mErrors.IsEmpty()) - { - // If the last error had a range that was a subset of this one, then just keep the first error - // This helps reduce cascading errors to their root cause - auto lastError = mErrors.back(); - if ((lastError->mSource == bfSource) && (isWarning == lastError->mIsWarning) && (isDeferred == lastError->mIsDeferred) && - (lastError->mSrcStart >= srcIdx) && (lastError->mSrcEnd <= srcIdx + srcLen)) - return false; - } + //TODO: Was this useful, or does 'var' resolution do this better? +// if (!mErrors.IsEmpty()) +// { +// // If the last error had a range that was a subset of this one, then just keep the first error +// // This helps reduce cascading errors to their root cause +// auto lastError = mErrors.back(); +// if ((lastError->mSource == bfSource) && (isWarning == lastError->mIsWarning) && (isDeferred == lastError->mIsDeferred) && +// (lastError->mSrcStart >= srcIdx) && (lastError->mSrcEnd <= srcIdx + srcLen)) +// return false; +// } // Don't record errors that have already occurred at this location BfErrorBase checkError;