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

Constraint check fixes

This commit is contained in:
Brian Fiete 2022-01-18 06:44:08 -05:00
parent b2eac81857
commit bac91516e7
3 changed files with 38 additions and 11 deletions

View file

@ -21479,17 +21479,19 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
{ {
bool handled = false; bool handled = false;
BfType* expectingType = mExpectingType;
if (leftValue.mType == rightValue.mType) if (leftValue.mType == rightValue.mType)
{ {
// All good // All good
handled = true; handled = true;
} }
else if ((mExpectingType != NULL) && else if ((expectingType != NULL) &&
(mModule->CanCast(leftValue, mExpectingType, BfCastFlags_NoBox)) && (mModule->CanCast(leftValue, expectingType, BfCastFlags_NoBox)) &&
(mModule->CanCast(rightValue, mExpectingType, BfCastFlags_NoBox)) && (mModule->CanCast(rightValue, expectingType, BfCastFlags_NoBox)) &&
(!leftValue.mType->IsVar()) && (!rightValue.mType->IsVar())) (!leftValue.mType->IsVar()) && (!rightValue.mType->IsVar()))
{ {
resultType = mExpectingType; resultType = expectingType;
handled = true; handled = true;
} }
else else

View file

@ -10600,18 +10600,23 @@ BfType* BfModule::CheckOperator(BfTypeInstance* typeInstance, BfOperatorDef* ope
return NULL; return NULL;
if (operatorInfo->mReturnType == NULL) if (operatorInfo->mReturnType == NULL)
return NULL; return NULL;
auto castFlags = BfCastFlags_IsConstraintCheck;
if (operatorDef->mOperatorDeclaration->mIsConvOperator)
castFlags = (BfCastFlags)(castFlags | BfCastFlags_NoConversionOperator);
if (lhs) if (lhs)
{ {
if (operatorInfo->mLHSType == NULL) if (operatorInfo->mLHSType == NULL)
return NULL; return NULL;
if (!CanCast(lhs, operatorInfo->mLHSType, BfCastFlags_IsConstraintCheck)) if (!CanCast(lhs, operatorInfo->mLHSType, castFlags))
return NULL; return NULL;
} }
if (rhs) if (rhs)
{ {
if (operatorInfo->mRHSType == NULL) if (operatorInfo->mRHSType == NULL)
return NULL; return NULL;
if (!CanCast(rhs, operatorInfo->mRHSType, BfCastFlags_IsConstraintCheck)) if (!CanCast(rhs, operatorInfo->mRHSType, castFlags))
return NULL; return NULL;
} }
return operatorInfo->mReturnType; return operatorInfo->mReturnType;

View file

@ -12521,7 +12521,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
if (explicitCast) if (explicitCast)
{ {
if (((fromPrimType->IsIntegral()) || (fromPrimType->IsFloat()) || (fromPrimType->IsBoolean())) && if (((fromPrimType->IsIntegral()) || (fromPrimType->IsFloat())) &&
((toType->IsIntegral()) || (toType->IsFloat()))) ((toType->IsIntegral()) || (toType->IsFloat())))
allowCast = true; allowCast = true;
} }
@ -12595,7 +12595,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
methodMatcher.mAllowImplicitWrap = true; methodMatcher.mAllowImplicitWrap = true;
BfBaseClassWalker baseClassWalker(walkFromType, walkToType, this); BfBaseClassWalker baseClassWalker(walkFromType, walkToType, this);
bool isConstraintCheck = false;// ((opFlags& BfUnaryOpFlag_IsConstraintCheck) != 0); bool isConstraintCheck = ((castFlags & BfCastFlags_IsConstraintCheck) != 0);
BfType* operatorConstraintReturnType = NULL; BfType* operatorConstraintReturnType = NULL;
BfType* bestSelfType = NULL; BfType* bestSelfType = NULL;
@ -12622,8 +12622,20 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
args.mSize = 0; args.mSize = 0;
} }
if (methodMatcher.CheckMethod(NULL, checkType, operatorDef, false)) if (isConstraintCheck)
methodMatcher.mSelfType = entry.mSrcType; {
auto returnType = CheckOperator(checkType, operatorDef, typedVal, BfTypedValue());
if (returnType != NULL)
{
operatorConstraintReturnType = returnType;
methodMatcher.mBestMethodDef = operatorDef;
}
}
else
{
if (methodMatcher.CheckMethod(NULL, checkType, operatorDef, false))
methodMatcher.mSelfType = entry.mSrcType;
}
args.mSize = prevArgSize; args.mSize = prevArgSize;
} }
@ -12683,6 +12695,14 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
} }
} }
} }
else if (isConstraintCheck)
{
auto result = BfTypedValue(mBfIRBuilder->GetFakeVal(), operatorConstraintReturnType);
if (result.mType != toType)
return CastToValue(srcNode, result, toType, BfCastFlags_Explicit, resultFlags);
if (result)
return result.mValue;
}
else else
{ {
BfTypedValue result; BfTypedValue result;