mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Added 'interface' and 'enum' constraints
This commit is contained in:
parent
f63b9236d0
commit
f41365a58e
8 changed files with 110 additions and 27 deletions
|
@ -363,6 +363,9 @@ bool BfModule::AreConstraintsSubset(BfGenericParamInstance* checkInner, BfGeneri
|
|||
{
|
||||
// If the outer had a type flag and the inner has a specific type constraint, then see if those are compatible
|
||||
auto outerFlags = checkOuter->mGenericParamFlags;
|
||||
if ((outerFlags & BfGenericParamFlag_Enum) != 0)
|
||||
outerFlags |= BfGenericParamFlag_Struct;
|
||||
|
||||
if (checkOuter->mTypeConstraint != NULL)
|
||||
{
|
||||
if (checkOuter->mTypeConstraint->IsStruct())
|
||||
|
@ -371,9 +374,17 @@ bool BfModule::AreConstraintsSubset(BfGenericParamInstance* checkInner, BfGeneri
|
|||
outerFlags |= BfGenericParamFlag_StructPtr;
|
||||
else if (checkOuter->mTypeConstraint->IsObject())
|
||||
outerFlags |= BfGenericParamFlag_Class;
|
||||
else if (checkOuter->mTypeConstraint->IsEnum())
|
||||
outerFlags |= BfGenericParamFlag_Enum | BfGenericParamFlag_Struct;
|
||||
else if (checkOuter->mTypeConstraint->IsInterface())
|
||||
outerFlags |= BfGenericParamFlag_Interface;
|
||||
}
|
||||
|
||||
if (((checkInner->mGenericParamFlags | outerFlags) & ~BfGenericParamFlag_Var) != (outerFlags & ~BfGenericParamFlag_Var))
|
||||
auto innerFlags = checkInner->mGenericParamFlags;
|
||||
if ((innerFlags & BfGenericParamFlag_Enum) != 0)
|
||||
innerFlags |= BfGenericParamFlag_Struct;
|
||||
|
||||
if (((innerFlags | outerFlags) & ~BfGenericParamFlag_Var) != (outerFlags & ~BfGenericParamFlag_Var))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -8481,7 +8492,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
{
|
||||
auto genericParam = GetGenericParamInstance((BfGenericParamType*)resolvedType);
|
||||
if (((genericParam->mTypeConstraint != NULL) && (genericParam->mTypeConstraint->IsValueType())) ||
|
||||
((genericParam->mGenericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr)) != 0))
|
||||
((genericParam->mGenericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr | BfGenericParamFlag_Enum)) != 0))
|
||||
{
|
||||
resolvedType = CreatePointerType(resolvedType);
|
||||
}
|
||||
|
@ -9970,7 +9981,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
// Generic constrained with class or pointer type -> void*
|
||||
if (toType->IsVoidPtr())
|
||||
{
|
||||
if ((genericParamInst->mGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_StructPtr)) ||
|
||||
if (((genericParamInst->mGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_StructPtr | BfGenericParamFlag_Interface)) != 0) ||
|
||||
((genericParamInst->mTypeConstraint != NULL) &&
|
||||
((genericParamInst->mTypeConstraint->IsPointer()) ||
|
||||
(genericParamInst->mTypeConstraint->IsInstanceOf(mCompiler->mFunctionTypeDef)) ||
|
||||
|
@ -9980,6 +9991,14 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
}
|
||||
}
|
||||
|
||||
if (toType->IsInteger())
|
||||
{
|
||||
if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Enum) != 0)
|
||||
{
|
||||
return mBfIRBuilder->GetFakeVal();
|
||||
}
|
||||
}
|
||||
|
||||
return BfIRValue();
|
||||
};
|
||||
|
||||
|
@ -10029,7 +10048,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
|
||||
if (typedVal.mType->IsNull())
|
||||
{
|
||||
bool allowCast = (genericParamInst->mGenericParamFlags & BfGenericParamFlag_Class) || (genericParamInst->mGenericParamFlags & BfGenericParamFlag_StructPtr);
|
||||
bool allowCast = (genericParamInst->mGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_StructPtr | BfGenericParamFlag_Interface)) != 0;
|
||||
if ((!allowCast) && (genericParamInst->mTypeConstraint != NULL))
|
||||
allowCast = genericParamInst->mTypeConstraint->IsObject() || genericParamInst->mTypeConstraint->IsPointer();
|
||||
if (allowCast)
|
||||
|
@ -10052,7 +10071,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
|
||||
if (explicitCast)
|
||||
{
|
||||
if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_StructPtr) ||
|
||||
if (((genericParamInst->mGenericParamFlags & BfGenericParamFlag_StructPtr) != 0) ||
|
||||
((genericParamInst->mTypeConstraint != NULL) && genericParamInst->mTypeConstraint->IsInstanceOf(mCompiler->mFunctionTypeDef)))
|
||||
{
|
||||
auto voidPtrType = CreatePointerType(GetPrimitiveType(BfTypeCode_None));
|
||||
|
@ -10061,6 +10080,24 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
return castedVal;
|
||||
}
|
||||
}
|
||||
|
||||
if ((typedVal.mType->IsIntegral()) && ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Enum) != 0))
|
||||
{
|
||||
bool allowCast = explicitCast;
|
||||
if ((!allowCast) && (typedVal.mType->IsIntegral()))
|
||||
{
|
||||
// Allow implicit cast of zero
|
||||
auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
|
||||
if ((constant != NULL) && (mBfIRBuilder->IsInt(constant->mTypeCode)))
|
||||
{
|
||||
allowCast = constant->mInt64 == 0;
|
||||
}
|
||||
}
|
||||
if (allowCast)
|
||||
{
|
||||
return mBfIRBuilder->GetFakeVal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((typedVal.mType->IsTypeInstance()) && (toType->IsTypeInstance()))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue