mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Fixed extern generic constraint and var constraint issues
This commit is contained in:
parent
dfb16336a2
commit
7a8592268c
5 changed files with 59 additions and 28 deletions
|
@ -7917,27 +7917,30 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst
|
||||||
|
|
||||||
bool BfExprEvaluator::CheckGenericCtor(BfGenericParamType* genericParamType, BfResolvedArgs& argValues, BfAstNode* targetSrc)
|
bool BfExprEvaluator::CheckGenericCtor(BfGenericParamType* genericParamType, BfResolvedArgs& argValues, BfAstNode* targetSrc)
|
||||||
{
|
{
|
||||||
auto genericConstraint = mModule->GetGenericParamInstance(genericParamType);
|
BfGenericParamFlags genericParamFlags = BfGenericParamFlag_None;
|
||||||
|
BfType* typeConstraint = NULL;
|
||||||
|
auto genericParam = mModule->GetMergedGenericParamData((BfGenericParamType*)genericParamType, genericParamFlags, typeConstraint);
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
if ((argValues.mArguments != NULL) && (argValues.mArguments->size() != 0))
|
if ((argValues.mArguments != NULL) && (argValues.mArguments->size() != 0))
|
||||||
{
|
{
|
||||||
mModule->Fail(StrFormat("Only default parameterless constructors can be called on generic argument '%s'", genericConstraint->GetGenericParamDef()->mName.c_str()), targetSrc);
|
mModule->Fail(StrFormat("Only default parameterless constructors can be called on generic argument '%s'", genericParam->GetGenericParamDef()->mName.c_str()), targetSrc);
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
else if ((genericConstraint->mGenericParamFlags & (BfGenericParamFlag_New | BfGenericParamFlag_Struct)) == 0)
|
else if ((genericParamFlags & (BfGenericParamFlag_New | BfGenericParamFlag_Struct | BfGenericParamFlag_Var)) == 0)
|
||||||
{
|
{
|
||||||
mModule->Fail(StrFormat("Must add 'where %s : new, struct' constraint to generic parameter to instantiate type", genericConstraint->GetGenericParamDef()->mName.c_str()), targetSrc);
|
mModule->Fail(StrFormat("Must add 'where %s : new, struct' constraint to generic parameter to instantiate type", genericParam->GetGenericParamDef()->mName.c_str()), targetSrc);
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
else if ((genericConstraint->mGenericParamFlags & BfGenericParamFlag_New) == 0)
|
else if ((genericParamFlags & (BfGenericParamFlag_New | BfGenericParamFlag_Var)) == 0)
|
||||||
{
|
{
|
||||||
mModule->Fail(StrFormat("Must add 'where %s : new' constraint to generic parameter to instantiate type", genericConstraint->GetGenericParamDef()->mName.c_str()), targetSrc);
|
mModule->Fail(StrFormat("Must add 'where %s : new' constraint to generic parameter to instantiate type", genericParam->GetGenericParamDef()->mName.c_str()), targetSrc);
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
else if ((genericConstraint->mGenericParamFlags & BfGenericParamFlag_Struct) == 0)
|
else if ((genericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_Var)) == 0)
|
||||||
{
|
{
|
||||||
mModule->Fail(StrFormat("Must add 'where %s : struct' constraint to generic parameter to instantiate type without allocator", genericConstraint->GetGenericParamDef()->mName.c_str()), targetSrc);
|
mModule->Fail(StrFormat("Must add 'where %s : struct' constraint to generic parameter to instantiate type without allocator", genericParam->GetGenericParamDef()->mName.c_str()), targetSrc);
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14200,16 +14203,19 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
bool isGenericParam = unresolvedTypeRef->IsGenericParam();
|
bool isGenericParam = unresolvedTypeRef->IsGenericParam();
|
||||||
if (resolvedTypeRef->IsGenericParam())
|
if (resolvedTypeRef->IsGenericParam())
|
||||||
{
|
{
|
||||||
auto genericParam = mModule->GetGenericParamInstance((BfGenericParamType*)resolvedTypeRef);
|
BfGenericParamFlags genericParamFlags = BfGenericParamFlag_None;
|
||||||
if (genericParam->mTypeConstraint == NULL)
|
BfType* typeConstraint = NULL;
|
||||||
|
auto genericParam = mModule->GetMergedGenericParamData((BfGenericParamType*)resolvedTypeRef, genericParamFlags, typeConstraint);
|
||||||
|
|
||||||
|
if (typeConstraint == NULL)
|
||||||
{
|
{
|
||||||
if ((genericParam->mGenericParamFlags & BfGenericParamFlag_Var) != 0)
|
if ((genericParamFlags & BfGenericParamFlag_Var) != 0)
|
||||||
{
|
{
|
||||||
// Allow it
|
// Allow it
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((genericParam->mGenericParamFlags & BfGenericParamFlag_New) == 0)
|
if ((genericParamFlags & BfGenericParamFlag_New) == 0)
|
||||||
{
|
{
|
||||||
mModule->Fail(StrFormat("Must add 'where %s : new' constraint to generic parameter to instantiate type", genericParam->GetName().c_str()), objCreateExpr->mTypeRef);
|
mModule->Fail(StrFormat("Must add 'where %s : new' constraint to generic parameter to instantiate type", genericParam->GetName().c_str()), objCreateExpr->mTypeRef);
|
||||||
}
|
}
|
||||||
|
@ -14220,13 +14226,13 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((genericParam->mTypeConstraint != NULL) && (genericParam->mTypeConstraint->IsValueType())) ||
|
if (((typeConstraint != NULL) && (typeConstraint->IsValueType())) ||
|
||||||
((genericParam->mGenericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr)) != 0))
|
((genericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr)) != 0))
|
||||||
{
|
{
|
||||||
resultType = mModule->CreatePointerType(resolvedTypeRef);
|
resultType = mModule->CreatePointerType(resolvedTypeRef);
|
||||||
}
|
}
|
||||||
else if (((genericParam->mTypeConstraint != NULL) && (!genericParam->mTypeConstraint->IsValueType())) ||
|
else if (((typeConstraint != NULL) && (!typeConstraint->IsValueType())) ||
|
||||||
((genericParam->mGenericParamFlags & (BfGenericParamFlag_Class)) != 0))
|
((genericParamFlags & (BfGenericParamFlag_Class)) != 0))
|
||||||
{
|
{
|
||||||
// Leave as 'T'
|
// Leave as 'T'
|
||||||
resultType = resolvedTypeRef;
|
resultType = resolvedTypeRef;
|
||||||
|
|
|
@ -7464,7 +7464,7 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar
|
||||||
if (constraintType->IsVar())
|
if (constraintType->IsVar())
|
||||||
{
|
{
|
||||||
// From a `comptype` generic undef resolution. Ignore.
|
// From a `comptype` generic undef resolution. Ignore.
|
||||||
genericParamInstance->mGenericParamFlags |= BfGenericParamFlag_ComptypeExpr;
|
genericParamInstance->mGenericParamFlags = (BfGenericParamFlags)(genericParamInstance->mGenericParamFlags | BfGenericParamFlag_ComptypeExpr);
|
||||||
genericParamInstance->mComptypeConstraint.Add(constraintTypeRef);
|
genericParamInstance->mComptypeConstraint.Add(constraintTypeRef);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -7526,7 +7526,7 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar
|
||||||
if ((startingTypeConstraint != NULL) && (startingTypeConstraint->IsDelegate()))
|
if ((startingTypeConstraint != NULL) && (startingTypeConstraint->IsDelegate()))
|
||||||
{
|
{
|
||||||
// 'System.Delegate' means that we are expecting an actual delegate instance. Simulate this by wanting a class.
|
// 'System.Delegate' means that we are expecting an actual delegate instance. Simulate this by wanting a class.
|
||||||
genericParamInstance->mGenericParamFlags |= BfGenericParamFlag_Class;
|
genericParamInstance->mGenericParamFlags = (BfGenericParamFlags)(genericParamInstance->mGenericParamFlags | BfGenericParamFlag_Class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -1818,6 +1818,7 @@ public:
|
||||||
BfGenericParamInstance* GetGenericTypeParamInstance(int paramIdx);
|
BfGenericParamInstance* GetGenericTypeParamInstance(int paramIdx);
|
||||||
BfGenericParamInstance* GetGenericParamInstance(BfGenericParamType* type);
|
BfGenericParamInstance* GetGenericParamInstance(BfGenericParamType* type);
|
||||||
void GetActiveTypeGenericParamInstances(SizedArray<BfGenericParamInstance*, 4>& genericParamInstance);
|
void GetActiveTypeGenericParamInstances(SizedArray<BfGenericParamInstance*, 4>& genericParamInstance);
|
||||||
|
BfGenericParamInstance* GetMergedGenericParamData(BfGenericParamType* type, BfGenericParamFlags& outFlags, BfType*& outTypeConstraint);
|
||||||
BfTypeInstance* GetBaseType(BfTypeInstance* typeInst);
|
BfTypeInstance* GetBaseType(BfTypeInstance* typeInst);
|
||||||
void HandleTypeGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, int typeGenericParamIdx);
|
void HandleTypeGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, int typeGenericParamIdx);
|
||||||
void HandleMethodGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, BfMethodDef* methodDef, int typeGenericParamIdx);
|
void HandleMethodGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, BfMethodDef* methodDef, int typeGenericParamIdx);
|
||||||
|
|
|
@ -102,7 +102,7 @@ BfGenericExtensionEntry* BfModule::BuildGenericExtensionInfo(BfTypeInstance* gen
|
||||||
auto rootGenericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx];
|
auto rootGenericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx];
|
||||||
genericParamInstance->mTypeConstraint = rootGenericParamInstance->mTypeConstraint;
|
genericParamInstance->mTypeConstraint = rootGenericParamInstance->mTypeConstraint;
|
||||||
genericParamInstance->mInterfaceConstraints = rootGenericParamInstance->mInterfaceConstraints;
|
genericParamInstance->mInterfaceConstraints = rootGenericParamInstance->mInterfaceConstraints;
|
||||||
genericParamInstance->mGenericParamFlags |= rootGenericParamInstance->mGenericParamFlags;
|
genericParamInstance->mGenericParamFlags = (BfGenericParamFlags)(genericParamInstance->mGenericParamFlags | rootGenericParamInstance->mGenericParamFlags);
|
||||||
|
|
||||||
ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType());
|
ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType());
|
||||||
}
|
}
|
||||||
|
@ -390,25 +390,25 @@ 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
|
// 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;
|
auto outerFlags = checkOuter->mGenericParamFlags;
|
||||||
if ((outerFlags & BfGenericParamFlag_Enum) != 0)
|
if ((outerFlags & BfGenericParamFlag_Enum) != 0)
|
||||||
outerFlags |= BfGenericParamFlag_Struct;
|
outerFlags = (BfGenericParamFlags)(outerFlags | BfGenericParamFlag_Struct);
|
||||||
|
|
||||||
if (checkOuter->mTypeConstraint != NULL)
|
if (checkOuter->mTypeConstraint != NULL)
|
||||||
{
|
{
|
||||||
if (checkOuter->mTypeConstraint->IsStruct())
|
if (checkOuter->mTypeConstraint->IsStruct())
|
||||||
outerFlags |= BfGenericParamFlag_Struct;
|
outerFlags = (BfGenericParamFlags)(outerFlags | BfGenericParamFlag_Struct);
|
||||||
else if (checkOuter->mTypeConstraint->IsStructOrStructPtr())
|
else if (checkOuter->mTypeConstraint->IsStructOrStructPtr())
|
||||||
outerFlags |= BfGenericParamFlag_StructPtr;
|
outerFlags = (BfGenericParamFlags)(outerFlags | BfGenericParamFlag_StructPtr);
|
||||||
else if (checkOuter->mTypeConstraint->IsObject())
|
else if (checkOuter->mTypeConstraint->IsObject())
|
||||||
outerFlags |= BfGenericParamFlag_Class;
|
outerFlags = (BfGenericParamFlags)(outerFlags | BfGenericParamFlag_Class);
|
||||||
else if (checkOuter->mTypeConstraint->IsEnum())
|
else if (checkOuter->mTypeConstraint->IsEnum())
|
||||||
outerFlags |= BfGenericParamFlag_Enum | BfGenericParamFlag_Struct;
|
outerFlags = (BfGenericParamFlags)(outerFlags | BfGenericParamFlag_Enum | BfGenericParamFlag_Struct);
|
||||||
else if (checkOuter->mTypeConstraint->IsInterface())
|
else if (checkOuter->mTypeConstraint->IsInterface())
|
||||||
outerFlags |= BfGenericParamFlag_Interface;
|
outerFlags = (BfGenericParamFlags)(outerFlags | BfGenericParamFlag_Interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto innerFlags = checkInner->mGenericParamFlags;
|
auto innerFlags = checkInner->mGenericParamFlags;
|
||||||
if ((innerFlags & BfGenericParamFlag_Enum) != 0)
|
if ((innerFlags & BfGenericParamFlag_Enum) != 0)
|
||||||
innerFlags |= BfGenericParamFlag_Struct;
|
innerFlags = (BfGenericParamFlags)(innerFlags | BfGenericParamFlag_Struct);
|
||||||
|
|
||||||
if (((innerFlags | outerFlags) & ~BfGenericParamFlag_Var) != (outerFlags & ~BfGenericParamFlag_Var))
|
if (((innerFlags | outerFlags) & ~BfGenericParamFlag_Var) != (outerFlags & ~BfGenericParamFlag_Var))
|
||||||
return false;
|
return false;
|
||||||
|
@ -8057,6 +8057,30 @@ void BfModule::GetActiveTypeGenericParamInstances(SizedArray<BfGenericParamInsta
|
||||||
genericParamInstances.Add(entry);
|
genericParamInstances.Add(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfGenericParamInstance* BfModule::GetMergedGenericParamData(BfGenericParamType* type, BfGenericParamFlags& outFlags, BfType*& outTypeConstraint)
|
||||||
|
{
|
||||||
|
BfGenericParamInstance* genericParam = GetGenericParamInstance(type);
|
||||||
|
outFlags = genericParam->mGenericParamFlags;
|
||||||
|
outTypeConstraint = genericParam->mTypeConstraint;
|
||||||
|
|
||||||
|
// Check method generic constraints
|
||||||
|
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecialized) && (mCurMethodInstance->mMethodInfoEx != NULL))
|
||||||
|
{
|
||||||
|
for (int genericParamIdx = (int)mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size();
|
||||||
|
genericParamIdx < mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
|
||||||
|
{
|
||||||
|
auto genericParam = mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
|
||||||
|
if (genericParam->mExternType == type)
|
||||||
|
{
|
||||||
|
outFlags = (BfGenericParamFlags)(outFlags | genericParam->mGenericParamFlags);
|
||||||
|
if (genericParam->mTypeConstraint != NULL)
|
||||||
|
outTypeConstraint = genericParam->mTypeConstraint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return genericParam;
|
||||||
|
}
|
||||||
|
|
||||||
BfGenericParamInstance* BfModule::GetGenericParamInstance(BfGenericParamType* type)
|
BfGenericParamInstance* BfModule::GetGenericParamInstance(BfGenericParamType* type)
|
||||||
{
|
{
|
||||||
if (type->mGenericParamKind == BfGenericParamKind_Method)
|
if (type->mGenericParamKind == BfGenericParamKind_Method)
|
||||||
|
|
|
@ -1118,7 +1118,7 @@ public:
|
||||||
class BfGenericParamInstance
|
class BfGenericParamInstance
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int mGenericParamFlags;
|
BfGenericParamFlags mGenericParamFlags;
|
||||||
BfType* mExternType;
|
BfType* mExternType;
|
||||||
Array<BfTypeInstance*> mInterfaceConstraints;
|
Array<BfTypeInstance*> mInterfaceConstraints;
|
||||||
Array<BfGenericOperatorConstraintInstance> mOperatorConstraints;
|
Array<BfGenericOperatorConstraintInstance> mOperatorConstraints;
|
||||||
|
@ -1129,7 +1129,7 @@ public:
|
||||||
BfGenericParamInstance()
|
BfGenericParamInstance()
|
||||||
{
|
{
|
||||||
mExternType = NULL;
|
mExternType = NULL;
|
||||||
mGenericParamFlags = 0;
|
mGenericParamFlags = BfGenericParamFlag_None;
|
||||||
mTypeConstraint = NULL;
|
mTypeConstraint = NULL;
|
||||||
mRefCount = 1;
|
mRefCount = 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue