1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48:20 +02:00

Better handling of extern generic constraints

This commit is contained in:
Brian Fiete 2025-01-15 11:25:51 -08:00
parent 4fa46b6a92
commit 1e44392da8
4 changed files with 75 additions and 5 deletions

View file

@ -8566,6 +8566,20 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
if (checkArgType->IsObjectOrInterface())
argIsReferenceType = true;
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecialized) && (mCurMethodInstance->mMethodInfoEx != NULL))
{
for (int genericParamIdx = (int)mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size();
genericParamIdx < mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
{
auto genericParamInst = mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
if (genericParamInst->mExternType == checkArgType)
{
checkGenericParamFlags |= genericParamInst->mGenericParamFlags;
}
}
}
BfTypeInstance* typeConstraintInst = NULL;
if (genericParamInst->mTypeConstraint != NULL)
typeConstraintInst = genericParamInst->mTypeConstraint->ToTypeInstance();

View file

@ -1959,7 +1959,7 @@ public:
BfGenericParamInstance* GetGenericTypeParamInstance(int paramIdx);
BfGenericParamInstance* GetGenericParamInstance(BfGenericParamType* type, bool checkMixinBind = false, BfFailHandleKind failHandleKind = BfFailHandleKind_Normal);
void GetActiveTypeGenericParamInstances(SizedArray<BfGenericParamInstance*, 4>& genericParamInstance);
BfGenericParamInstance* GetMergedGenericParamData(BfGenericParamType* type, BfGenericParamFlags& outFlags, BfType*& outTypeConstraint);
BfGenericParamInstance* GetMergedGenericParamData(BfType* type, BfGenericParamFlags& outFlags, BfType*& outTypeConstraint);
BfTypeInstance* GetBaseType(BfTypeInstance* typeInst);
void HandleTypeGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, int typeGenericParamIdx);
void HandleMethodGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, BfMethodDef* methodDef, int typeGenericParamIdx);

View file

@ -9621,11 +9621,39 @@ void BfModule::GetActiveTypeGenericParamInstances(SizedArray<BfGenericParamInsta
genericParamInstances.Add(entry);
}
BfGenericParamInstance* BfModule::GetMergedGenericParamData(BfGenericParamType* type, BfGenericParamFlags& outFlags, BfType*& outTypeConstraint)
BfGenericParamInstance* BfModule::GetMergedGenericParamData(BfType* type, BfGenericParamFlags& outFlags, BfType*& outTypeConstraint)
{
BfGenericParamInstance* genericParam = GetGenericParamInstance(type);
outFlags = genericParam->mGenericParamFlags;
outTypeConstraint = genericParam->mTypeConstraint;
BfGenericParamType* genericParamType = NULL;
if (type->IsGenericParam())
genericParamType = (BfGenericParamType*)type;
BfGenericParamInstance* genericParam = NULL;
if (genericParamType != NULL)
{
genericParam = GetGenericParamInstance(genericParamType);
outFlags = (BfGenericParamFlags)(outFlags | genericParam->mGenericParamFlags);
if (genericParam->mTypeConstraint != NULL)
outTypeConstraint = genericParam->mTypeConstraint;
}
else
{
outFlags = BfGenericParamFlag_None;
outTypeConstraint = NULL;
if ((mCurTypeInstance != NULL) && (mCurTypeInstance->mGenericTypeInfo != NULL))
{
for (int genericIdx = mCurTypeInstance->mTypeDef->mGenericParamDefs.mSize; genericIdx < mCurTypeInstance->mGenericTypeInfo->mGenericParams.mSize; genericIdx++)
{
auto genericParam = mCurTypeInstance->mGenericTypeInfo->mGenericParams[genericIdx];
if (genericParam->mExternType == type)
{
outFlags = (BfGenericParamFlags)(outFlags | genericParam->mGenericParamFlags);
if (genericParam->mTypeConstraint != NULL)
outTypeConstraint = genericParam->mTypeConstraint;
}
}
}
}
// Check method generic constraints
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecialized) && (mCurMethodInstance->mMethodInfoEx != NULL))

View file

@ -1,3 +1,5 @@
#pragma warning disable 168
using System;
using System.Collections;
@ -21,6 +23,32 @@ namespace Tests
}
}
interface IZop
{
void Zop();
}
interface IZag
{
void Zag();
}
class ClassC<T> where T : IDisposable
{
public void MethodA(T val) where T : IZop, delete, new
{
val.Zop();
MethodB(val);
delete val;
}
public void MethodB(T val) where T : IZop, delete, new
{
alloctype(T) z = new T();
delete val;
}
}
struct TestFunc<T, Del>
{
private int mId;