1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00

Improved pointer generic constraints

This commit is contained in:
Brian Fiete 2025-03-21 11:37:26 -04:00
parent 0bdaa03545
commit 195463cb77
3 changed files with 27 additions and 9 deletions

View file

@ -23498,6 +23498,15 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr,
case BfUnaryOp_Dereference: case BfUnaryOp_Dereference:
{ {
CheckResultForReading(mResult); CheckResultForReading(mResult);
if (mResult.mType->IsGenericParam())
{
auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)mResult.mType);
if ((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsPointer()))
{
mResult = mModule->GetDefaultTypedValue(genericParamInstance->mTypeConstraint->GetUnderlyingType(), false, BfDefaultValueKind_Addr);
break;
}
}
if (!mResult.mType->IsPointer()) if (!mResult.mType->IsPointer())
{ {
mResult = BfTypedValue(); mResult = BfTypedValue();

View file

@ -8859,17 +8859,18 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
} }
} }
if (checkArgType->IsPointer()) auto checkArgElementType = checkArgType;
{ if (checkArgElementType->IsPointer())
auto ptrType = (BfPointerType*)checkArgType; {
checkArgType = ptrType->mElementType; auto ptrType = (BfPointerType*)checkArgElementType;
} checkArgElementType = ptrType->mElementType;
}
if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_New) != 0) if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_New) != 0)
{ {
bool canAlloc = false; bool canAlloc = false;
if (auto checkTypeInst = checkArgType->ToTypeInstance()) if (auto checkTypeInst = checkArgElementType->ToTypeInstance())
{ {
if (checkTypeInst->IsObjectOrStruct()) if (checkTypeInst->IsObjectOrStruct())
{ {
@ -8910,11 +8911,11 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
canAlloc = TypeIsSubTypeOf(mCurTypeInstance, checkTypeInst, false); canAlloc = TypeIsSubTypeOf(mCurTypeInstance, checkTypeInst, false);
} }
} }
else if (checkArgType->IsGenericParam()) else if (checkArgElementType->IsGenericParam())
{ {
canAlloc = (checkGenericParamFlags & (BfGenericParamFlag_New | BfGenericParamFlag_Var)) != 0; canAlloc = (checkGenericParamFlags & (BfGenericParamFlag_New | BfGenericParamFlag_Var)) != 0;
} }
else if (checkArgType->IsPrimitiveType()) else if (checkArgElementType->IsPrimitiveType())
{ {
// Any primitive types and stuff can be allocated // Any primitive types and stuff can be allocated
canAlloc = true; canAlloc = true;

View file

@ -199,6 +199,11 @@ namespace Tests
delete val2; delete val2;
} }
public static int IntPtrTest<T>(T val) where T : int*
{
return *val;
}
public class ClassE public class ClassE
{ {
public static Self Instance = new ClassE() ~ delete _; public static Self Instance = new ClassE() ~ delete _;
@ -513,6 +518,9 @@ namespace Tests
var innerC = OuterA<int, float>.InnerC.this<int32>(123); var innerC = OuterA<int, float>.InnerC.this<int32>(123);
Test.Assert(innerC.mVal == 123); Test.Assert(innerC.mVal == 123);
int iVal = 123;
Test.Assert(IntPtrTest(&iVal) == 123);
} }
} }