1
0
Fork 0
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:
Brian Fiete 2022-01-21 12:01:50 -05:00
parent 0de32f7b34
commit dd2ecfb316
4 changed files with 38 additions and 18 deletions

View file

@ -1941,13 +1941,13 @@ 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;
for (int pass = 0; true; pass++) for (int pass = 0; true; pass++)
@ -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;
} }
@ -2206,7 +2206,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
goto NoMatch; goto NoMatch;
if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), genericArg, NULL, genericParams[checkGenericIdx], genericArgumentsSubstitute, NULL)) if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), genericArg, NULL, genericParams[checkGenericIdx], genericArgumentsSubstitute, NULL))
goto NoMatch; goto NoMatch;
} }
} }

View file

@ -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()))

View file

@ -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);

View file

@ -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