mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Improved constraint checks where generic param type constraint passes
This commit is contained in:
parent
116d9c6f01
commit
b7725d0ed0
4 changed files with 76 additions and 1 deletions
|
@ -23367,6 +23367,15 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr,
|
||||||
mResult = opResult;
|
mResult = opResult;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto typeConstraint = mModule->GetGenericParamInstanceTypeConstraint(mResult.mType);
|
||||||
|
if ((typeConstraint != NULL) && (!typeConstraint->IsGenericParam()))
|
||||||
|
{
|
||||||
|
// Handle cases such as 'where T : float'
|
||||||
|
mResult.mType = typeConstraint;
|
||||||
|
PerformUnaryOperation_OnResult(unaryOpExpr, unaryOp, opToken, opFlags);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (unaryOp)
|
switch (unaryOp)
|
||||||
|
@ -25316,6 +25325,48 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
findBinaryOp = flippedBinaryOp;
|
findBinaryOp = flippedBinaryOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto _FixOpCheckGenericParam = [&](BfTypedValue& typedVal)
|
||||||
|
{
|
||||||
|
if ((typedVal.mType != NULL) && (typedVal.mType->IsGenericParam()))
|
||||||
|
{
|
||||||
|
auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)typedVal.mType);
|
||||||
|
if (genericParamInstance->mTypeConstraint != NULL)
|
||||||
|
{
|
||||||
|
typedVal.mType = genericParamInstance->mTypeConstraint;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto leftTypeConstraint = mModule->GetGenericParamInstanceTypeConstraint(leftValue.mType);
|
||||||
|
auto rightTypeConstraint = mModule->GetGenericParamInstanceTypeConstraint(rightValue.mType);
|
||||||
|
if ((leftTypeConstraint != NULL) || (rightTypeConstraint != NULL))
|
||||||
|
{
|
||||||
|
// Handle cases such as 'where T : float'
|
||||||
|
bool needNewCheck = false;
|
||||||
|
|
||||||
|
BfTypedValue newLeftValue = leftValue;
|
||||||
|
if ((leftTypeConstraint != NULL) && (!leftTypeConstraint->IsGenericParam()))
|
||||||
|
{
|
||||||
|
newLeftValue.mType = leftTypeConstraint;
|
||||||
|
needNewCheck = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
BfTypedValue newRightValue = rightValue;
|
||||||
|
if ((rightTypeConstraint != NULL) && (!rightTypeConstraint->IsGenericParam()))
|
||||||
|
{
|
||||||
|
newRightValue.mType = rightTypeConstraint;
|
||||||
|
needNewCheck = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needNewCheck)
|
||||||
|
{
|
||||||
|
PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, flags, newLeftValue, newRightValue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool resultHandled = false;
|
bool resultHandled = false;
|
||||||
if (((origLeftType != NULL) && (origLeftType->IsIntUnknown())) ||
|
if (((origLeftType != NULL) && (origLeftType->IsIntUnknown())) ||
|
||||||
((origRightType != NULL) && (origRightType->IsIntUnknown())))
|
((origRightType != NULL) && (origRightType->IsIntUnknown())))
|
||||||
|
|
|
@ -1972,6 +1972,7 @@ public:
|
||||||
bool IsUnboundGeneric(BfType* type);
|
bool IsUnboundGeneric(BfType* type);
|
||||||
BfGenericParamInstance* GetGenericTypeParamInstance(int paramIdx, BfFailHandleKind failHandleKind = BfFailHandleKind_Normal);
|
BfGenericParamInstance* GetGenericTypeParamInstance(int paramIdx, BfFailHandleKind failHandleKind = BfFailHandleKind_Normal);
|
||||||
BfGenericParamInstance* GetGenericParamInstance(BfGenericParamType* type, bool checkMixinBind = false, BfFailHandleKind failHandleKind = BfFailHandleKind_Normal);
|
BfGenericParamInstance* GetGenericParamInstance(BfGenericParamType* type, bool checkMixinBind = false, BfFailHandleKind failHandleKind = BfFailHandleKind_Normal);
|
||||||
|
BfType* GetGenericParamInstanceTypeConstraint(BfType* type, bool checkMixinBind = false, BfFailHandleKind failHandleKind = BfFailHandleKind_Normal);
|
||||||
void GetActiveTypeGenericParamInstances(SizedArray<BfGenericParamInstance*, 4>& genericParamInstance);
|
void GetActiveTypeGenericParamInstances(SizedArray<BfGenericParamInstance*, 4>& genericParamInstance);
|
||||||
BfGenericParamInstance* GetMergedGenericParamData(BfType* type, BfGenericParamFlags& outFlags, BfType*& outTypeConstraint);
|
BfGenericParamInstance* GetMergedGenericParamData(BfType* type, BfGenericParamFlags& outFlags, BfType*& outTypeConstraint);
|
||||||
BfTypeInstance* GetBaseType(BfTypeInstance* typeInst);
|
BfTypeInstance* GetBaseType(BfTypeInstance* typeInst);
|
||||||
|
|
|
@ -9861,6 +9861,16 @@ BfGenericParamInstance* BfModule::GetGenericParamInstance(BfGenericParamType* ty
|
||||||
return GetGenericTypeParamInstance(type->mGenericParamIdx, failHandleKind);
|
return GetGenericTypeParamInstance(type->mGenericParamIdx, failHandleKind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfType* BfModule::GetGenericParamInstanceTypeConstraint(BfType* type, bool checkMixinBind, BfFailHandleKind failHandleKind)
|
||||||
|
{
|
||||||
|
if (!type->IsGenericParam())
|
||||||
|
return NULL;
|
||||||
|
auto genericParamInstance = GetGenericParamInstance((BfGenericParamType*)type, checkMixinBind, failHandleKind);
|
||||||
|
if (genericParamInstance != NULL)
|
||||||
|
return genericParamInstance->mTypeConstraint;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
bool BfModule::ResolveTypeResult_Validate(BfAstNode* typeRef, BfType* resolvedTypeRef)
|
bool BfModule::ResolveTypeResult_Validate(BfAstNode* typeRef, BfType* resolvedTypeRef)
|
||||||
{
|
{
|
||||||
if ((typeRef == NULL) || (resolvedTypeRef == NULL))
|
if ((typeRef == NULL) || (resolvedTypeRef == NULL))
|
||||||
|
|
|
@ -7,6 +7,19 @@ namespace Tests
|
||||||
{
|
{
|
||||||
class Constraints
|
class Constraints
|
||||||
{
|
{
|
||||||
|
struct Vector2<T>
|
||||||
|
{
|
||||||
|
public T mX;
|
||||||
|
public T mY;
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Vector2<T> where T : float
|
||||||
|
{
|
||||||
|
public T LengthSquared => mX * mX + mY * mY;
|
||||||
|
public T Length => Math.Sqrt(LengthSquared);
|
||||||
|
public T NegX = -mX;
|
||||||
|
}
|
||||||
|
|
||||||
class Dicto : Dictionary<int, float>
|
class Dicto : Dictionary<int, float>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue