mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 12:02:21 +02:00
params operator implicit cast, params generic inference fix
This commit is contained in:
parent
4885871785
commit
64d646e130
3 changed files with 81 additions and 12 deletions
|
@ -1979,11 +1979,18 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
|||
mHasVarArguments = true;
|
||||
|
||||
if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params)
|
||||
{
|
||||
if ((mArguments[argIdx].mArgFlags & BfArgFlag_ParamsExpr) != 0)
|
||||
{
|
||||
// Match to entire thing
|
||||
}
|
||||
else
|
||||
{
|
||||
paramsParamIdx = paramIdx;
|
||||
if ((wantType->IsArray()) || (wantType->IsSizedArray()) || (wantType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
|
||||
wantType = wantType->GetUnderlyingType();
|
||||
}
|
||||
}
|
||||
|
||||
if (!genericInferContext.InferGenericArgument(methodInstance, type, wantType, argTypedValue.mValue))
|
||||
return ResultKind_Failed;
|
||||
|
@ -22954,15 +22961,60 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr,
|
|||
}
|
||||
else
|
||||
{
|
||||
auto origValue = mResult;
|
||||
auto isValid = false;
|
||||
|
||||
for (int pass = 0; pass < 2; pass++)
|
||||
{
|
||||
auto typeInst = mResult.mType->ToTypeInstance();
|
||||
auto genericTypeInst = mResult.mType->ToGenericTypeInstance();
|
||||
if ((genericTypeInst != NULL) && (genericTypeInst->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
|
||||
isValid = true;
|
||||
else if ((mResult.mType->IsArray()) || (mResult.mType->IsSizedArray()))
|
||||
isValid = true;
|
||||
else if ((typeInst != NULL) && (pass == 0))
|
||||
{
|
||||
BfBaseClassWalker baseClassWalker(typeInst, NULL, mModule);
|
||||
|
||||
BfType* bestCastType = NULL;
|
||||
while (true)
|
||||
{
|
||||
auto entry = baseClassWalker.Next();
|
||||
auto checkType = entry.mTypeInstance;
|
||||
if (checkType == NULL)
|
||||
break;
|
||||
for (auto operatorDef : checkType->mTypeDef->mOperators)
|
||||
{
|
||||
if (operatorDef->mOperatorDeclaration->mIsConvOperator)
|
||||
{
|
||||
if (operatorDef->IsExplicit())
|
||||
continue;
|
||||
|
||||
auto methodInstance = mModule->GetRawMethodInstanceAtIdx(typeInst, operatorDef->mIdx);
|
||||
|
||||
auto checkType = methodInstance->mReturnType;
|
||||
if (checkType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef))
|
||||
bestCastType = checkType;
|
||||
else if ((checkType->IsArray()) || (checkType->IsSizedArray()))
|
||||
bestCastType = checkType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestCastType == NULL)
|
||||
break;
|
||||
auto castTypedValue = mModule->Cast(opToken, mResult, bestCastType, BfCastFlags_SilentFail);
|
||||
if (!castTypedValue)
|
||||
break;
|
||||
mResult = castTypedValue;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isValid)
|
||||
{
|
||||
mModule->Fail(StrFormat("A 'params' expression cannot be used on type '%s'", mModule->TypeToString(mResult.mType).c_str()), opToken);
|
||||
mModule->Fail(StrFormat("A 'params' expression cannot be used on type '%s'", mModule->TypeToString(origValue.mType).c_str()), opToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2862,7 +2862,7 @@ bool BfModule::CheckProtection(BfProtectionCheckFlags& flags, BfTypeInstance* me
|
|||
{
|
||||
allowPrivate |= IsInnerType(curCheckType->mTypeDef, memberOwner->mTypeDef);
|
||||
if (memberOwner->mTypeDef->IsGlobalsContainer())
|
||||
allowPrivate |= curCheckType->mTypeDef->mNamespace.StartsWith(memberOwner->mTypeDef->mNamespace);
|
||||
allowPrivate |= curCheckType->mTypeDef->mNamespace == memberOwner->mTypeDef->mNamespace;
|
||||
}
|
||||
if (allowPrivate)
|
||||
flags = (BfProtectionCheckFlags)(flags | BfProtectionCheckFlag_AllowPrivate | BfProtectionCheckFlag_CheckedPrivate);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
class MethodCalls
|
||||
|
@ -205,6 +207,16 @@ namespace Tests
|
|||
static int sIdx = 0;
|
||||
static int GetNext() => ++sIdx;
|
||||
|
||||
public static float ParamsTest(params Span<float> span)
|
||||
{
|
||||
return span[0];
|
||||
}
|
||||
|
||||
public static T ParamsTest2<T>(params Span<T> span)
|
||||
{
|
||||
return span[0];
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestBasics()
|
||||
{
|
||||
|
@ -273,6 +285,11 @@ namespace Tests
|
|||
Test.Assert(Named(p3:GetNext(), p2:GetNext(), p1:GetNext()) == 10321);
|
||||
Test.Assert(Named(p2:GetNext(), p1:GetNext(), p0:GetNext()) == 20654);
|
||||
Test.Assert(Named(p1:9) == 30193);
|
||||
|
||||
List<float> fList = scope .();
|
||||
fList.Add(1.2f);
|
||||
Test.Assert(ParamsTest(params fList) == 1.2f);
|
||||
Test.Assert(ParamsTest2(params fList) == 1.2f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue