mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 04:22:20 +02:00
Fixes to new conversion overload invoker
This commit is contained in:
parent
4fd0623451
commit
95a27d5e93
3 changed files with 50 additions and 6 deletions
|
@ -84,6 +84,15 @@ namespace System
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public static Nullable<T> operator implicit <TOther>(TOther value) where T : operator implicit TOther
|
||||||
|
{
|
||||||
|
Nullable<T> result;
|
||||||
|
result.mHasValue = true;
|
||||||
|
result.mValue = value;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
public static explicit operator T(Nullable<T> value)
|
public static explicit operator T(Nullable<T> value)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2076,7 +2076,11 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
||||||
if ((wantType->IsRef()) && (!argTypedValue.mType->IsRef()) &&
|
if ((wantType->IsRef()) && (!argTypedValue.mType->IsRef()) &&
|
||||||
((mAllowImplicitRef) || (wantType->IsIn())))
|
((mAllowImplicitRef) || (wantType->IsIn())))
|
||||||
wantType = wantType->GetUnderlyingType();
|
wantType = wantType->GetUnderlyingType();
|
||||||
if (!mModule->CanCast(argTypedValue, wantType, ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? BfCastFlags_NoConversionOperator : BfCastFlags_None))
|
|
||||||
|
BfCastFlags castFlags = ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? BfCastFlags_NoConversionOperator : BfCastFlags_None;
|
||||||
|
if ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp_Explicit) != 0)
|
||||||
|
castFlags = (BfCastFlags)(castFlags | BfCastFlags_Explicit);
|
||||||
|
if (!mModule->CanCast(argTypedValue, wantType, castFlags))
|
||||||
{
|
{
|
||||||
if ((mAllowImplicitWrap) && (argTypedValue.mType->IsWrappableType()) && (mModule->GetWrappedStructType(argTypedValue.mType) == wantType))
|
if ((mAllowImplicitWrap) && (argTypedValue.mType->IsWrappableType()) && (mModule->GetWrappedStructType(argTypedValue.mType) == wantType))
|
||||||
{
|
{
|
||||||
|
@ -2129,7 +2133,6 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
||||||
auto wantType = mCheckReturnType;
|
auto wantType = mCheckReturnType;
|
||||||
if ((genericArgumentsSubstitute != NULL) && (wantType->IsUnspecializedType()))
|
if ((genericArgumentsSubstitute != NULL) && (wantType->IsUnspecializedType()))
|
||||||
{
|
{
|
||||||
wantType = typeUnspecMethodInstance->GetParamType(paramIdx);
|
|
||||||
auto resolvedType = mModule->ResolveGenericType(wantType, typeGenericArguments, genericArgumentsSubstitute, false);
|
auto resolvedType = mModule->ResolveGenericType(wantType, typeGenericArguments, genericArgumentsSubstitute, false);
|
||||||
if (resolvedType == NULL)
|
if (resolvedType == NULL)
|
||||||
goto NoMatch;
|
goto NoMatch;
|
||||||
|
|
|
@ -12644,6 +12644,20 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
|
|
||||||
methodMatcher.FlushAmbiguityError();
|
methodMatcher.FlushAmbiguityError();
|
||||||
|
|
||||||
|
if (methodMatcher.mBestMethodDef != NULL)
|
||||||
|
{
|
||||||
|
if (mayBeBox)
|
||||||
|
{
|
||||||
|
if (!ignoreErrors)
|
||||||
|
{
|
||||||
|
if (Fail("Ambiguous cast, may be conversion operator or may be boxing request", srcNode) != NULL)
|
||||||
|
mCompiler->mPassInstance->MoreInfo("See conversion operator", methodMatcher.mBestMethodDef->GetRefNode());
|
||||||
|
}
|
||||||
|
else if (!silentFail)
|
||||||
|
SetFail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (methodMatcher.mBestMethodDef == NULL)
|
if (methodMatcher.mBestMethodDef == NULL)
|
||||||
{
|
{
|
||||||
// Check method generic constraints
|
// Check method generic constraints
|
||||||
|
@ -12709,6 +12723,24 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
BfExprEvaluator exprEvaluator(this);
|
BfExprEvaluator exprEvaluator(this);
|
||||||
exprEvaluator.mBfEvalExprFlags = BfEvalExprFlags_FromConversionOp;
|
exprEvaluator.mBfEvalExprFlags = BfEvalExprFlags_FromConversionOp;
|
||||||
|
|
||||||
|
auto methodDeclaration = BfNodeDynCast<BfMethodDeclaration>(methodMatcher.mBestMethodDef->mMethodDeclaration);
|
||||||
|
if ((methodDeclaration != NULL) && (methodDeclaration->mBody == NULL))
|
||||||
|
{
|
||||||
|
auto fromType = typedVal.mType;
|
||||||
|
|
||||||
|
// Handle the typedPrim<->underlying part implicitly
|
||||||
|
if (fromType->IsTypedPrimitive())
|
||||||
|
{
|
||||||
|
auto convTypedValue = BfTypedValue(typedVal.mValue, fromType->GetUnderlyingType());
|
||||||
|
return CastToValue(srcNode, convTypedValue, toType, (BfCastFlags)(castFlags & ~BfCastFlags_Explicit), NULL);
|
||||||
|
}
|
||||||
|
else if (toType->IsTypedPrimitive())
|
||||||
|
{
|
||||||
|
auto castedVal = CastToValue(srcNode, typedVal, toType->GetUnderlyingType(), (BfCastFlags)(castFlags & ~BfCastFlags_Explicit), NULL);
|
||||||
|
return castedVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto moduleMethodInstance = exprEvaluator.GetSelectedMethod(methodMatcher);
|
auto moduleMethodInstance = exprEvaluator.GetSelectedMethod(methodMatcher);
|
||||||
if (moduleMethodInstance.mMethodInstance != NULL)
|
if (moduleMethodInstance.mMethodInstance != NULL)
|
||||||
{
|
{
|
||||||
|
@ -12727,7 +12759,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
methodMatcher.mArguments[0].mTypedValue = Cast(srcNode, typedVal, wantType, BfCastFlags_Explicit);
|
methodMatcher.mArguments[0].mTypedValue = Cast(srcNode, typedVal, wantType, (BfCastFlags)(castFlags | BfCastFlags_Explicit));
|
||||||
if (paramType->IsRef())
|
if (paramType->IsRef())
|
||||||
{
|
{
|
||||||
typedVal = MakeAddressable(typedVal);
|
typedVal = MakeAddressable(typedVal);
|
||||||
|
@ -12749,7 +12781,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
result = LoadValue(result);
|
result = LoadValue(result);
|
||||||
|
|
||||||
if (result.mType != toType)
|
if (result.mType != toType)
|
||||||
return CastToValue(srcNode, result, toType, BfCastFlags_Explicit, resultFlags);
|
return CastToValue(srcNode, result, toType, (BfCastFlags)(castFlags | BfCastFlags_Explicit), resultFlags);
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
return result.mValue;
|
return result.mValue;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue