mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 20:12: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
|
@ -1980,9 +1980,16 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
||||||
|
|
||||||
if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params)
|
if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params)
|
||||||
{
|
{
|
||||||
paramsParamIdx = paramIdx;
|
if ((mArguments[argIdx].mArgFlags & BfArgFlag_ParamsExpr) != 0)
|
||||||
if ((wantType->IsArray()) || (wantType->IsSizedArray()) || (wantType->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
|
{
|
||||||
wantType = wantType->GetUnderlyingType();
|
// 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))
|
if (!genericInferContext.InferGenericArgument(methodInstance, type, wantType, argTypedValue.mValue))
|
||||||
|
@ -22954,15 +22961,60 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
auto origValue = mResult;
|
||||||
auto isValid = false;
|
auto isValid = false;
|
||||||
auto genericTypeInst = mResult.mType->ToGenericTypeInstance();
|
|
||||||
if ((genericTypeInst != NULL) && (genericTypeInst->IsInstanceOf(mModule->mCompiler->mSpanTypeDef)))
|
for (int pass = 0; pass < 2; pass++)
|
||||||
isValid = true;
|
{
|
||||||
else if ((mResult.mType->IsArray()) || (mResult.mType->IsSizedArray()))
|
auto typeInst = mResult.mType->ToTypeInstance();
|
||||||
isValid = true;
|
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)
|
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);
|
allowPrivate |= IsInnerType(curCheckType->mTypeDef, memberOwner->mTypeDef);
|
||||||
if (memberOwner->mTypeDef->IsGlobalsContainer())
|
if (memberOwner->mTypeDef->IsGlobalsContainer())
|
||||||
allowPrivate |= curCheckType->mTypeDef->mNamespace.StartsWith(memberOwner->mTypeDef->mNamespace);
|
allowPrivate |= curCheckType->mTypeDef->mNamespace == memberOwner->mTypeDef->mNamespace;
|
||||||
}
|
}
|
||||||
if (allowPrivate)
|
if (allowPrivate)
|
||||||
flags = (BfProtectionCheckFlags)(flags | BfProtectionCheckFlag_AllowPrivate | BfProtectionCheckFlag_CheckedPrivate);
|
flags = (BfProtectionCheckFlags)(flags | BfProtectionCheckFlag_AllowPrivate | BfProtectionCheckFlag_CheckedPrivate);
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
namespace Tests
|
namespace Tests
|
||||||
{
|
{
|
||||||
class MethodCalls
|
class MethodCalls
|
||||||
|
@ -205,6 +207,16 @@ namespace Tests
|
||||||
static int sIdx = 0;
|
static int sIdx = 0;
|
||||||
static int GetNext() => ++sIdx;
|
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]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
@ -273,6 +285,11 @@ namespace Tests
|
||||||
Test.Assert(Named(p3:GetNext(), p2:GetNext(), p1:GetNext()) == 10321);
|
Test.Assert(Named(p3:GetNext(), p2:GetNext(), p1:GetNext()) == 10321);
|
||||||
Test.Assert(Named(p2:GetNext(), p1:GetNext(), p0:GetNext()) == 20654);
|
Test.Assert(Named(p2:GetNext(), p1:GetNext(), p0:GetNext()) == 20654);
|
||||||
Test.Assert(Named(p1:9) == 30193);
|
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