mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Fix for generic constraints checking with mixins
This commit is contained in:
parent
e865e675a7
commit
1e7bd7d43f
2 changed files with 77 additions and 0 deletions
|
@ -13286,6 +13286,31 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
|||
return;
|
||||
auto methodInstance = moduleMethodInstance.mMethodInstance;
|
||||
|
||||
for (int checkGenericIdx = 0; checkGenericIdx < (int)methodMatcher.mBestMethodGenericArguments.size(); checkGenericIdx++)
|
||||
{
|
||||
auto& genericParams = methodInstance->mMethodInfoEx->mGenericParams;
|
||||
auto genericArg = methodMatcher.mBestMethodGenericArguments[checkGenericIdx];
|
||||
if (genericArg->IsVar())
|
||||
continue;
|
||||
|
||||
BfAstNode* paramSrc;
|
||||
if (methodMatcher.mBestMethodGenericArgumentSrcs.size() == 0)
|
||||
paramSrc = targetSrc;
|
||||
else
|
||||
paramSrc = methodMatcher.mArguments[methodMatcher.mBestMethodGenericArgumentSrcs[checkGenericIdx]].mExpression;
|
||||
|
||||
// Note: don't pass methodMatcher.mBestMethodGenericArguments into here, this method is already specialized
|
||||
BfError* error = NULL;
|
||||
if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), genericArg, paramSrc, genericParams[checkGenericIdx], NULL, &error))
|
||||
{
|
||||
if (methodInstance->mMethodDef->mMethodDeclaration != NULL)
|
||||
{
|
||||
if (error != NULL)
|
||||
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check circular ref based on methodInstance
|
||||
{
|
||||
bool hasCircularRef = false;
|
||||
|
|
|
@ -6836,6 +6836,52 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Delete) != 0)
|
||||
{
|
||||
bool canDelete = false;
|
||||
if (checkArgType->IsPointer())
|
||||
canDelete = true;
|
||||
else if (checkArgType->IsObjectOrInterface())
|
||||
canDelete = true;
|
||||
|
||||
if (!canDelete)
|
||||
{
|
||||
if (!ignoreErrors)
|
||||
*errorOut = Fail(StrFormat("The type '%s' must be a deletable type in order to use it as parameter '%s' for '%s'",
|
||||
_TypeToString(origCheckArgType).c_str(), genericParamInst->GetName().c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_New) != 0)
|
||||
{
|
||||
bool canAlloc = false;
|
||||
if (auto checkTypeInst = checkArgType->ToTypeInstance())
|
||||
{
|
||||
if (checkTypeInst->IsObjectOrStruct())
|
||||
{
|
||||
auto ctorClear = GetRawMethodByName(checkTypeInst, "__BfCtor", 0);
|
||||
if (ctorClear->mMethodDef->mProtection == BfProtection_Public)
|
||||
canAlloc = true;
|
||||
else if ((ctorClear->mMethodDef->mProtection == BfProtection_Protected) && (mCurTypeInstance != NULL))
|
||||
canAlloc = TypeIsSubTypeOf(mCurTypeInstance, checkTypeInst, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Any primitive types and stuff can be allocated
|
||||
canAlloc = true;
|
||||
}
|
||||
|
||||
if (!canAlloc)
|
||||
{
|
||||
if (!ignoreErrors)
|
||||
*errorOut = Fail(StrFormat("The type '%s' must have an accessible default constructor in order to use it as parameter '%s' for '%s'",
|
||||
_TypeToString(origCheckArgType).c_str(), genericParamInst->GetName().c_str(), GenericParamSourceToString(genericParamSource).c_str()), checkArgTypeRef);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((genericParamInst->mInterfaceConstraints.IsEmpty()) && (genericParamInst->mOperatorConstraints.IsEmpty()) && (genericParamInst->mTypeConstraint == NULL))
|
||||
return true;
|
||||
|
@ -12101,6 +12147,12 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
|||
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(declareModule->mCurTypeInstance, typeInst);
|
||||
SetAndRestoreValue<BfFilePosition> prevFilePos(declareModule->mCurFilePosition);
|
||||
|
||||
if ((methodDef->mMethodType == BfMethodType_Mixin) && (methodDef->mGenericParams.size() != 0) && (!isUnspecializedPass))
|
||||
{
|
||||
// For mixins we only process the unspecialized version
|
||||
addToWorkList = false;
|
||||
}
|
||||
|
||||
declareModule->DoMethodDeclaration(methodDef->GetMethodDeclaration(), false, addToWorkList);
|
||||
|
||||
if (processNow)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue