1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 20:12:21 +02:00

Fixed conv oper cancast ambiguity error, disallow conv out to interface

This commit is contained in:
Brian Fiete 2022-02-01 17:28:13 -05:00
parent 6c18ffd607
commit 1ee32434a5
3 changed files with 26 additions and 20 deletions

View file

@ -2205,7 +2205,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
} }
returnType = mModule->ResolveSelfType(returnType, typeInstance); returnType = mModule->ResolveSelfType(returnType, typeInstance);
BfCastFlags castFlags = ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? BfCastFlags_NoConversionOperator : BfCastFlags_None; BfCastFlags castFlags = ((mBfEvalExprFlags & BfEvalExprFlags_FromConversionOp) != 0) ? (BfCastFlags)(BfCastFlags_NoConversionOperator | BfCastFlags_NoInterfaceImpl) : 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(returnType), mCheckReturnType, castFlags)) if (!mModule->CanCast(mModule->GetFakeTypedValue(returnType), mCheckReturnType, castFlags))

View file

@ -95,13 +95,14 @@ enum BfCastFlags
BfCastFlags_SilentFail = 8, BfCastFlags_SilentFail = 8,
BfCastFlags_NoBox = 0x10, BfCastFlags_NoBox = 0x10,
BfCastFlags_NoBoxDtor = 0x20, BfCastFlags_NoBoxDtor = 0x20,
BfCastFlags_NoConversionOperator = 0x40, BfCastFlags_NoInterfaceImpl = 0x40,
BfCastFlags_FromCompiler = 0x80, // Not user specified BfCastFlags_NoConversionOperator = 0x80,
BfCastFlags_Force = 0x100, BfCastFlags_FromCompiler = 0x100, // Not user specified
BfCastFlags_PreferAddr = 0x200, BfCastFlags_Force = 0x200,
BfCastFlags_WarnOnBox = 0x400, BfCastFlags_PreferAddr = 0x400,
BfCastFlags_IsCastCheck = 0x800, BfCastFlags_WarnOnBox = 0x800,
BfCastFlags_IsConstraintCheck = 0x1000 BfCastFlags_IsCastCheck = 0x1000,
BfCastFlags_IsConstraintCheck = 0x2000,
}; };
enum BfCastResultFlags enum BfCastResultFlags

View file

@ -11987,7 +11987,11 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
{ {
bool allowCast = false; bool allowCast = false;
if (TypeIsSubTypeOf(fromTypeInstance, toTypeInstance)) if (((castFlags & BfCastFlags_NoInterfaceImpl) != 0) && (toTypeInstance->IsInterface()))
{
// Don't allow
}
else if (TypeIsSubTypeOf(fromTypeInstance, toTypeInstance))
allowCast = true; allowCast = true;
else if ((explicitCast) && else if ((explicitCast) &&
((toType->IsInterface()) || (TypeIsSubTypeOf(toTypeInstance, fromTypeInstance)))) ((toType->IsInterface()) || (TypeIsSubTypeOf(toTypeInstance, fromTypeInstance))))
@ -12887,27 +12891,28 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
if (doCall) if (doCall)
{ {
if (!silentFail)
methodMatcher.FlushAmbiguityError(); methodMatcher.FlushAmbiguityError();
auto wantType = paramType; auto wantType = paramType;
if (wantType->IsRef()) if (wantType->IsRef())
wantType = wantType->GetUnderlyingType(); wantType = wantType->GetUnderlyingType();
auto typedVal = methodMatcher.mArguments[0].mTypedValue; auto convTypedVal = methodMatcher.mArguments[0].mTypedValue;
if (wantType != typedVal.mType) if (wantType != convTypedVal.mType)
{ {
if ((typedVal.mType->IsWrappableType()) && (wantType == GetWrappedStructType(typedVal.mType))) if ((convTypedVal.mType->IsWrappableType()) && (wantType == GetWrappedStructType(convTypedVal.mType)))
{ {
typedVal = MakeAddressable(typedVal); convTypedVal = MakeAddressable(convTypedVal);
methodMatcher.mArguments[0].mTypedValue = BfTypedValue(mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapTypeInstPtr(wantType->ToTypeInstance())), methodMatcher.mArguments[0].mTypedValue = BfTypedValue(mBfIRBuilder->CreateBitCast(convTypedVal.mValue, mBfIRBuilder->MapTypeInstPtr(wantType->ToTypeInstance())),
paramType, paramType->IsRef() ? BfTypedValueKind_Value : BfTypedValueKind_Addr); paramType, paramType->IsRef() ? BfTypedValueKind_Value : BfTypedValueKind_Addr);
} }
else else
{ {
methodMatcher.mArguments[0].mTypedValue = Cast(srcNode, typedVal, wantType, (BfCastFlags)(castFlags | BfCastFlags_Explicit | BfCastFlags_NoConversionOperator)); methodMatcher.mArguments[0].mTypedValue = Cast(srcNode, convTypedVal, wantType, (BfCastFlags)(castFlags | BfCastFlags_Explicit | BfCastFlags_NoConversionOperator));
if (paramType->IsRef()) if (paramType->IsRef())
{ {
typedVal = MakeAddressable(typedVal); convTypedVal = MakeAddressable(convTypedVal);
typedVal.mKind = BfTypedValueKind_Addr; convTypedVal.mKind = BfTypedValueKind_Addr;
} }
} }
} }