1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 04:22:20 +02:00

Improved ability of methodrefs to be used for Delegate constraints

This commit is contained in:
Brian Fiete 2022-06-13 06:52:12 -07:00
parent 7aa2fdf976
commit 46947636f7
3 changed files with 30 additions and 20 deletions

View file

@ -1920,10 +1920,10 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
goto NoMatch; goto NoMatch;
} }
if ((checkMethod->mParams.mSize > 0) && (methodInstance->GetParamKind(checkMethod->mParams.mSize - 1) == BfParamKind_Params)) if ((methodInstance->mParams.mSize > 0) && (methodInstance->GetParamKind(methodInstance->mParams.mSize - 1) == BfParamKind_Params))
{ {
// Handle `params int[C]` generic sized array params case // Handle `params int[C]` generic sized array params case
auto paramsType = methodInstance->GetParamType(checkMethod->mParams.mSize - 1); auto paramsType = methodInstance->GetParamType(methodInstance->mParams.mSize - 1);
if (paramsType->IsUnknownSizedArrayType()) if (paramsType->IsUnknownSizedArrayType())
{ {
auto unknownSizedArray = (BfUnknownSizedArrayType*)paramsType; auto unknownSizedArray = (BfUnknownSizedArrayType*)paramsType;

View file

@ -8319,25 +8319,29 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
convCheckConstraint = ResolveGenericType(convCheckConstraint, NULL, methodGenericArgs, mCurTypeInstance); convCheckConstraint = ResolveGenericType(convCheckConstraint, NULL, methodGenericArgs, mCurTypeInstance);
if (convCheckConstraint == NULL) if (convCheckConstraint == NULL)
return false; return false;
if (((checkArgType->IsMethodRef()) || (checkArgType->IsFunction())) && (convCheckConstraint->IsDelegate())) if ((checkArgType->IsMethodRef()) || (checkArgType->IsFunction()))
{ {
BfMethodInstance* checkMethodInstance; if (convCheckConstraint->IsDelegate())
if (checkArgType->IsMethodRef())
{ {
auto methodRefType = (BfMethodRefType*)checkArgType; BfMethodInstance* checkMethodInstance;
checkMethodInstance = methodRefType->mMethodRef; if (checkArgType->IsMethodRef())
} {
else auto methodRefType = (BfMethodRefType*)checkArgType;
{ checkMethodInstance = methodRefType->mMethodRef;
checkMethodInstance = GetRawMethodInstanceAtIdx(checkArgType->ToTypeInstance(), 0, "Invoke"); }
} else
{
auto invokeMethod = GetRawMethodInstanceAtIdx(convCheckConstraint->ToTypeInstance(), 0, "Invoke"); checkMethodInstance = GetRawMethodInstanceAtIdx(checkArgType->ToTypeInstance(), 0, "Invoke");
}
BfExprEvaluator exprEvaluator(this); auto invokeMethod = GetRawMethodInstanceAtIdx(convCheckConstraint->ToTypeInstance(), 0, "Invoke");
if (exprEvaluator.IsExactMethodMatch(checkMethodInstance, invokeMethod))
BfExprEvaluator exprEvaluator(this);
if (exprEvaluator.IsExactMethodMatch(checkMethodInstance, invokeMethod))
constraintMatched = true;
}
else if (convCheckConstraint->IsInstanceOf(mCompiler->mDelegateTypeDef))
constraintMatched = true; constraintMatched = true;
} }
else if (CanCast(GetFakeTypedValue(checkArgType), convCheckConstraint)) else if (CanCast(GetFakeTypedValue(checkArgType), convCheckConstraint))
{ {
@ -23466,7 +23470,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
{ {
isValid = true; isValid = true;
} }
else if ((resolvedParamType->IsDelegate()) || (resolvedParamType->IsFunction())) else if ((resolvedParamType->IsDelegate()) || (resolvedParamType->IsFunction()) || (resolvedParamType->IsMethodRef()))
{ {
hadDelegateParams = true; hadDelegateParams = true;
@ -23487,7 +23491,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
} }
isValid = true; isValid = true;
addParams = false; addParams = false;
} }
else if (resolvedParamType->IsGenericParam()) else if (resolvedParamType->IsGenericParam())
{ {
auto genericParamInstance = GetGenericParamInstance((BfGenericParamType*)resolvedParamType); auto genericParamInstance = GetGenericParamInstance((BfGenericParamType*)resolvedParamType);
@ -23745,7 +23749,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
{ {
// If we have generic delegate params, it's possible we will fail constraints later if we specialize with an invalid type, but we can't allow that // If we have generic delegate params, it's possible we will fail constraints later if we specialize with an invalid type, but we can't allow that
// to cause us to throw an assertion in the declaration here // to cause us to throw an assertion in the declaration here
if (!defaultMethodInstance->mHadGenericDelegateParams) if ((!defaultMethodInstance->mHadGenericDelegateParams) && (!methodInstance->mHasFailed) && (!defaultMethodInstance->mHasFailed))
BF_ASSERT((isDone) && (isDefaultDone)); BF_ASSERT((isDone) && (isDefaultDone));
break; break;

View file

@ -568,6 +568,12 @@ BfMethodCustomAttributes::~BfMethodCustomAttributes()
BfMethodInstance* BfMethodParam::GetDelegateParamInvoke() BfMethodInstance* BfMethodParam::GetDelegateParamInvoke()
{ {
if (mResolvedType->IsMethodRef())
{
auto methodRefType = (BfMethodRefType*)mResolvedType;
return methodRefType->mMethodRef;
}
BF_ASSERT(mResolvedType->IsDelegate() || mResolvedType->IsFunction()); BF_ASSERT(mResolvedType->IsDelegate() || mResolvedType->IsFunction());
auto bfModule = BfModule::GetModuleFor(mResolvedType); auto bfModule = BfModule::GetModuleFor(mResolvedType);
BfMethodInstance* invokeMethodInstance = bfModule->GetRawMethodInstanceAtIdx(mResolvedType->ToTypeInstance(), 0, "Invoke"); BfMethodInstance* invokeMethodInstance = bfModule->GetRawMethodInstanceAtIdx(mResolvedType->ToTypeInstance(), 0, "Invoke");