mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Fixed generic operator overload method generic arg inference from toType
This commit is contained in:
parent
0de32f7b34
commit
dd2ecfb316
4 changed files with 38 additions and 18 deletions
|
@ -1941,12 +1941,12 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// while (true)
|
if ((mCheckReturnType != NULL) && (methodInstance->mReturnType->IsUnspecializedType()))
|
||||||
// {
|
{
|
||||||
//
|
genericInferContext.mCheckedTypeSet.Clear();
|
||||||
// }
|
if (!genericInferContext.InferGenericArgument(methodInstance, mCheckReturnType, methodInstance->mReturnType, BfIRValue()))
|
||||||
|
return ResultKind_Failed;
|
||||||
//
|
}
|
||||||
|
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
bool inferredAllGenericArguments = false;
|
bool inferredAllGenericArguments = false;
|
||||||
|
@ -2172,20 +2172,20 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
||||||
|
|
||||||
if (mCheckReturnType != NULL)
|
if (mCheckReturnType != NULL)
|
||||||
{
|
{
|
||||||
auto wantType = mCheckReturnType;
|
auto returnType = methodInstance->mReturnType;
|
||||||
if ((genericArgumentsSubstitute != NULL) && (wantType->IsUnspecializedType()))
|
if ((genericArgumentsSubstitute != NULL) && (returnType->IsUnspecializedType()))
|
||||||
{
|
{
|
||||||
auto resolvedType = mModule->ResolveGenericType(wantType, typeGenericArguments, genericArgumentsSubstitute, false);
|
auto resolvedType = mModule->ResolveGenericType(returnType, typeGenericArguments, genericArgumentsSubstitute, false);
|
||||||
if (resolvedType == NULL)
|
if (resolvedType == NULL)
|
||||||
goto NoMatch;
|
goto NoMatch;
|
||||||
wantType = resolvedType;
|
returnType = resolvedType;
|
||||||
}
|
}
|
||||||
wantType = mModule->ResolveSelfType(wantType, typeInstance);
|
returnType = mModule->ResolveSelfType(returnType, typeInstance);
|
||||||
|
|
||||||
BfCastFlags castFlags = ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? BfCastFlags_NoConversionOperator : BfCastFlags_None;
|
BfCastFlags castFlags = ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? BfCastFlags_NoConversionOperator : BfCastFlags_None;
|
||||||
if ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp_Explicit) != 0)
|
if ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp_Explicit) != 0)
|
||||||
castFlags = (BfCastFlags)(castFlags | BfCastFlags_Explicit);
|
castFlags = (BfCastFlags)(castFlags | BfCastFlags_Explicit);
|
||||||
if (!mModule->CanCast(mModule->GetFakeTypedValue(methodInstance->mReturnType), wantType, castFlags))
|
if (!mModule->CanCast(mModule->GetFakeTypedValue(returnType), mCheckReturnType, castFlags))
|
||||||
goto NoMatch;
|
goto NoMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19195,7 +19195,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
|
||||||
refNode = operatorDef->mOperatorDeclaration->mCommas[0];
|
refNode = operatorDef->mOperatorDeclaration->mCommas[0];
|
||||||
Fail("Conversion operators must declare one parameter", refNode);
|
Fail("Conversion operators must declare one parameter", refNode);
|
||||||
}
|
}
|
||||||
else
|
else if ((methodInstance->mIsUnspecialized) && (!methodInstance->mIsUnspecializedVariation))
|
||||||
{
|
{
|
||||||
auto checkParam0 = mCurMethodInstance->GetParamType(0);
|
auto checkParam0 = mCurMethodInstance->GetParamType(0);
|
||||||
if ((checkParam0->IsRef()) && (!checkParam0->IsOut()))
|
if ((checkParam0->IsRef()) && (!checkParam0->IsOut()))
|
||||||
|
|
|
@ -12805,7 +12805,11 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
if ((explicitCast) && (typedVal.mType->IsTypedPrimitive()))
|
if ((explicitCast) && (typedVal.mType->IsTypedPrimitive()))
|
||||||
{
|
{
|
||||||
auto underlyingType = typedVal.mType->GetUnderlyingType();
|
auto underlyingType = typedVal.mType->GetUnderlyingType();
|
||||||
if ((returnType != underlyingType) && (CanCast(GetFakeTypedValue(underlyingType), toType, (BfCastFlags)(castFlags | BfCastFlags_NoConversionOperator))))
|
if ((returnType == underlyingType) && (explicitCast))
|
||||||
|
{
|
||||||
|
doCall = false;
|
||||||
|
}
|
||||||
|
else if ((CanCast(GetFakeTypedValue(underlyingType), toType, (BfCastFlags)(castFlags | BfCastFlags_NoConversionOperator))))
|
||||||
{
|
{
|
||||||
float underlyingCanCast = CanCast(GetFakeTypedValue(underlyingType), toType, implicitCastFlags);
|
float underlyingCanCast = CanCast(GetFakeTypedValue(underlyingType), toType, implicitCastFlags);
|
||||||
float returnCanCast = CanCast(GetFakeTypedValue(returnType), toType, implicitCastFlags);
|
float returnCanCast = CanCast(GetFakeTypedValue(returnType), toType, implicitCastFlags);
|
||||||
|
@ -12834,8 +12838,11 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
if ((explicitCast) && (toType->IsTypedPrimitive()))
|
if ((explicitCast) && (toType->IsTypedPrimitive()))
|
||||||
{
|
{
|
||||||
auto underlyingType = toType->GetUnderlyingType();
|
auto underlyingType = toType->GetUnderlyingType();
|
||||||
if ((paramType != underlyingType) &&
|
if ((paramType == underlyingType) && (explicitCast))
|
||||||
(CanCast(typedVal, underlyingType, (BfCastFlags)(castFlags | BfCastFlags_NoConversionOperator))))
|
{
|
||||||
|
doCall = false;
|
||||||
|
}
|
||||||
|
else if (CanCast(typedVal, underlyingType, (BfCastFlags)(castFlags | BfCastFlags_NoConversionOperator)))
|
||||||
{
|
{
|
||||||
float underlyingCanCast = CanCast(typedVal, underlyingType, implicitCastFlags);
|
float underlyingCanCast = CanCast(typedVal, underlyingType, implicitCastFlags);
|
||||||
float paramCanCast = CanCast(typedVal, paramType, implicitCastFlags);
|
float paramCanCast = CanCast(typedVal, paramType, implicitCastFlags);
|
||||||
|
|
|
@ -336,6 +336,15 @@ namespace Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct StructK : uint64
|
||||||
|
{
|
||||||
|
public static T operator implicit<T>(Self self)
|
||||||
|
where T : operator explicit uint64
|
||||||
|
{
|
||||||
|
return (.)(uint64)self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*struct OuterOp<T>
|
/*struct OuterOp<T>
|
||||||
{
|
{
|
||||||
public struct InnerOp<T2>
|
public struct InnerOp<T2>
|
||||||
|
@ -644,6 +653,10 @@ namespace Tests
|
||||||
Test.Assert(sji8i.mVal == 56);
|
Test.Assert(sji8i.mVal == 56);
|
||||||
Test.Assert(sji8e.mVal == 45);
|
Test.Assert(sji8e.mVal == 45);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StructK sk = (.)123;
|
||||||
|
uint64 sku32 = sk;
|
||||||
|
Test.Assert(sku32 == 123);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IntStruct
|
struct IntStruct
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue