mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Properly checking extern method constraints, fixed dtor body scopes
This commit is contained in:
parent
b1f741b1f0
commit
bec6f1d007
4 changed files with 67 additions and 37 deletions
|
@ -4989,7 +4989,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
|
||||||
|
|
||||||
BfTypedValue BfExprEvaluator::CreateCall(BfMethodMatcher* methodMatcher, BfTypedValue target)
|
BfTypedValue BfExprEvaluator::CreateCall(BfMethodMatcher* methodMatcher, BfTypedValue target)
|
||||||
{
|
{
|
||||||
auto moduleMethodInstance = mModule->GetMethodInstance(methodMatcher->mBestMethodTypeInstance, methodMatcher->mBestMethodDef, methodMatcher->mBestMethodGenericArguments);
|
auto moduleMethodInstance = GetSelectedMethod(methodMatcher->mTargetSrc, methodMatcher->mBestMethodTypeInstance, methodMatcher->mBestMethodDef, *methodMatcher);
|
||||||
if (moduleMethodInstance.mMethodInstance == NULL)
|
if (moduleMethodInstance.mMethodInstance == NULL)
|
||||||
return BfTypedValue();
|
return BfTypedValue();
|
||||||
if ((target) && (target.mType != moduleMethodInstance.mMethodInstance->GetOwner()))
|
if ((target) && (target.mType != moduleMethodInstance.mMethodInstance->GetOwner()))
|
||||||
|
@ -12934,38 +12934,56 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
|
||||||
if (methodDef->IsEmptyPartial())
|
if (methodDef->IsEmptyPartial())
|
||||||
return methodInstance;
|
return methodInstance;
|
||||||
|
|
||||||
for (int checkGenericIdx = 0; checkGenericIdx < (int)methodMatcher.mBestMethodGenericArguments.size(); checkGenericIdx++)
|
if (methodInstance.mMethodInstance->mMethodInfoEx != NULL)
|
||||||
{
|
{
|
||||||
auto& genericParams = methodInstance.mMethodInstance->mMethodInfoEx->mGenericParams;
|
for (int checkGenericIdx = 0; checkGenericIdx < (int)methodInstance.mMethodInstance->mMethodInfoEx->mGenericParams.size(); checkGenericIdx++)
|
||||||
auto genericArg = methodMatcher.mBestMethodGenericArguments[checkGenericIdx];
|
|
||||||
if (genericArg->IsVar())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
BfAstNode* paramSrc;
|
|
||||||
if (methodMatcher.mBestMethodGenericArgumentSrcs.size() == 0)
|
|
||||||
{
|
{
|
||||||
paramSrc = targetSrc;
|
auto genericParams = methodInstance.mMethodInstance->mMethodInfoEx->mGenericParams[checkGenericIdx];
|
||||||
}
|
BfTypeVector* checkMethodGenericArgs = NULL;
|
||||||
else
|
BfType* genericArg = NULL;
|
||||||
paramSrc = methodMatcher.mArguments[methodMatcher.mBestMethodGenericArgumentSrcs[checkGenericIdx]].mExpression;
|
|
||||||
|
|
||||||
// Note: don't pass methodMatcher.mBestMethodGenericArguments into here, this method is already specialized
|
if (checkGenericIdx < (int)methodMatcher.mBestMethodGenericArguments.size())
|
||||||
BfError* error = NULL;
|
|
||||||
if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance.mMethodInstance), genericArg, paramSrc, genericParams[checkGenericIdx], NULL,
|
|
||||||
failed ? NULL : &error))
|
|
||||||
{
|
|
||||||
if (methodInstance.mMethodInstance->IsSpecializedGenericMethod())
|
|
||||||
{
|
{
|
||||||
// We mark this as failed to make sure we don't try to process a method that doesn't even follow the constraints
|
genericArg = methodMatcher.mBestMethodGenericArguments[checkGenericIdx];
|
||||||
methodInstance.mMethodInstance->mFailedConstraints = true;
|
|
||||||
}
|
}
|
||||||
if (methodInstance.mMethodInstance->mMethodDef->mMethodDeclaration != NULL)
|
else
|
||||||
{
|
{
|
||||||
if (error != NULL)
|
checkMethodGenericArgs = &methodMatcher.mBestMethodGenericArguments;
|
||||||
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance.mMethodInstance->mMethodDef->GetRefNode());
|
genericArg = genericParams->mExternType;
|
||||||
|
genericArg = mModule->ResolveGenericType(genericArg, NULL, checkMethodGenericArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (genericArg->IsVar())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BfAstNode* paramSrc;
|
||||||
|
if (checkGenericIdx >= methodMatcher.mBestMethodGenericArgumentSrcs.size())
|
||||||
|
{
|
||||||
|
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.mMethodInstance), genericArg, paramSrc, genericParams, checkMethodGenericArgs,
|
||||||
|
failed ? NULL : &error))
|
||||||
|
{
|
||||||
|
if (methodInstance.mMethodInstance->IsSpecializedGenericMethod())
|
||||||
|
{
|
||||||
|
// We mark this as failed to make sure we don't try to process a method that doesn't even follow the constraints
|
||||||
|
methodInstance.mMethodInstance->mFailedConstraints = true;
|
||||||
|
}
|
||||||
|
if (methodInstance.mMethodInstance->mMethodDef->mMethodDeclaration != NULL)
|
||||||
|
{
|
||||||
|
if (error != NULL)
|
||||||
|
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance.mMethodInstance->mMethodDef->GetRefNode());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
BF_ASSERT(methodMatcher.mBestMethodGenericArguments.IsEmpty());
|
||||||
|
|
||||||
return methodInstance;
|
return methodInstance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7276,10 +7276,18 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
||||||
(!CanCast(exprEvaluator.mResult, origCheckArgType)))
|
(!CanCast(exprEvaluator.mResult, origCheckArgType)))
|
||||||
{
|
{
|
||||||
if (!ignoreErrors)
|
if (!ignoreErrors)
|
||||||
*errorOut = Fail(StrFormat("Generic argument '%s', declared to be '%s' for '%s', must result from binary operation '%s %s %s'", genericParamInst->GetName().c_str(),
|
{
|
||||||
TypeToString(origCheckArgType).c_str(), GenericParamSourceToString(genericParamSource).c_str(),
|
if (genericParamInst->mExternType != NULL)
|
||||||
TypeToString(leftType).c_str(), BfGetOpName(checkOpConstraint.mBinaryOp), TypeToString(rightType).c_str()
|
*errorOut = Fail(StrFormat("Binary operation for '%s' must result in '%s' from binary operation '%s %s %s'",
|
||||||
), checkArgTypeRef);
|
GenericParamSourceToString(genericParamSource).c_str(), TypeToString(origCheckArgType).c_str(),
|
||||||
|
TypeToString(leftType).c_str(), BfGetOpName(checkOpConstraint.mBinaryOp), TypeToString(rightType).c_str()
|
||||||
|
), checkArgTypeRef);
|
||||||
|
else
|
||||||
|
*errorOut = Fail(StrFormat("Generic argument '%s', declared to be '%s' for '%s', must result from binary operation '%s %s %s'", genericParamInst->GetName().c_str(),
|
||||||
|
TypeToString(origCheckArgType).c_str(), GenericParamSourceToString(genericParamSource).c_str(),
|
||||||
|
TypeToString(leftType).c_str(), BfGetOpName(checkOpConstraint.mBinaryOp), TypeToString(rightType).c_str()
|
||||||
|
), checkArgTypeRef);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12297,10 +12305,14 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generic constraints
|
// Generic constraints
|
||||||
for (int genericParamIdx = 0; genericParamIdx < (int)methodDef->mGenericParams.size(); genericParamIdx++)
|
if (!methodDef->mGenericParams.IsEmpty())
|
||||||
{
|
{
|
||||||
auto genericParamInstance = new BfGenericMethodParamInstance(methodDef, genericParamIdx);
|
BF_ASSERT(methodInstance->GetMethodInfoEx()->mGenericParams.IsEmpty());
|
||||||
methodInstance->GetMethodInfoEx()->mGenericParams.push_back(genericParamInstance);
|
for (int genericParamIdx = 0; genericParamIdx < (int)methodDef->mGenericParams.size(); genericParamIdx++)
|
||||||
|
{
|
||||||
|
auto genericParamInstance = new BfGenericMethodParamInstance(methodDef, genericParamIdx);
|
||||||
|
methodInstance->GetMethodInfoEx()->mGenericParams.push_back(genericParamInstance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int externConstraintIdx = 0; externConstraintIdx < (int)methodDef->mExternalConstraints.size(); externConstraintIdx++)
|
for (int externConstraintIdx = 0; externConstraintIdx < (int)methodDef->mExternalConstraints.size(); externConstraintIdx++)
|
||||||
|
@ -14245,7 +14257,7 @@ void BfModule::EmitDtorBody()
|
||||||
|
|
||||||
if (auto bodyBlock = BfNodeDynCast<BfBlock>(methodDef->mBody))
|
if (auto bodyBlock = BfNodeDynCast<BfBlock>(methodDef->mBody))
|
||||||
{
|
{
|
||||||
VisitCodeBlock(bodyBlock);
|
VisitEmbeddedStatement(bodyBlock);
|
||||||
if (bodyBlock->mCloseBrace != NULL)
|
if (bodyBlock->mCloseBrace != NULL)
|
||||||
{
|
{
|
||||||
UpdateSrcPos(bodyBlock->mCloseBrace);
|
UpdateSrcPos(bodyBlock->mCloseBrace);
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace System.Collections
|
||||||
|
|
||||||
extension Dictionary<K, V>
|
extension Dictionary<K, V>
|
||||||
{
|
{
|
||||||
public static bool operator==(Self lhs, Self rhs) where K : IOpEquals where V : IOpEquals
|
public static bool operator==(Self lhs, Self rhs)
|
||||||
{
|
{
|
||||||
if (lhs.mCount != rhs.mCount)
|
if (lhs.mCount != rhs.mCount)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -82,7 +82,7 @@ namespace Tests
|
||||||
return -val;
|
return -val;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T GetInt() where T : Int
|
public T GetInt() where T : Int32
|
||||||
{
|
{
|
||||||
return mVal;
|
return mVal;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue