1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 04:22:20 +02:00

Fixed some issues with new/delete generic constraints

This commit is contained in:
Brian Fiete 2020-02-20 11:57:25 -08:00
parent a781f29c31
commit c2c2c24ac8
9 changed files with 99 additions and 26 deletions

View file

@ -273,7 +273,7 @@ namespace System.Collections.Generic
protected void Free(T* val)
{
delete val;
delete (void*)val;
}
/*protected T[] Alloc(int size)
{

View file

@ -458,7 +458,7 @@ namespace System
if (result == .Ok)
return .Ok(Span<T>(vals, inOutSize));
delete vals;
delete (void*)vals;
trySize = inOutSize;
}
}

View file

@ -260,7 +260,7 @@ namespace System.Collections.Generic
protected void Free(T* val)
{
delete val;
delete (void*)val;
}
/*protected T[] Alloc(int size)
{

View file

@ -407,7 +407,7 @@ namespace System
if (result == .Ok)
return .Ok(Span<T>(vals, inOutSize));
delete vals;
delete (void*)vals;
trySize = inOutSize;
}
}

View file

@ -6001,6 +6001,30 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst
return BfTypedValue();
}
bool BfExprEvaluator::CheckGenericCtor(BfGenericParamType* genericParamType, BfResolvedArgs& argValues, BfAstNode* targetSrc)
{
auto genericConstraint = mModule->GetGenericParamInstance(genericParamType);
bool success = true;
if ((genericConstraint->mGenericParamFlags & BfGenericParamFlag_New) == 0)
{
mModule->Fail(StrFormat("Must add 'where %s : new' constraint to generic parameter to instantiate type", genericConstraint->GetGenericParamDef()->mName.c_str()), targetSrc);
success = false;
}
if ((genericConstraint->mGenericParamFlags & BfGenericParamFlag_Struct) == 0)
{
mModule->Fail(StrFormat("Must add 'where %s : struct' constraint to generic parameter to instantiate type without allocator", genericConstraint->GetGenericParamDef()->mName.c_str()), targetSrc);
success = false;
}
if ((argValues.mArguments != NULL) && (argValues.mArguments->size() != 0))
{
mModule->Fail(StrFormat("Only default parameterless constructors can be called on generic argument '%s'", genericConstraint->GetGenericParamDef()->mName.c_str()), targetSrc);
success = false;
}
return success;
}
BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& methodName,
BfResolvedArgs& argValues, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments, BfCheckedKind checkedKind)
{
@ -6669,7 +6693,15 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
}
if (refType != NULL)
{
resolvedTypeInstance = refType->ToTypeInstance();
if (refType->IsGenericParam())
{
CheckGenericCtor((BfGenericParamType*)refType, argValues, targetSrc);
return mModule->GetDefaultTypedValue(refType);
}
}
}
}
@ -10873,7 +10905,7 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
{
//mModule->SetElementType(objCreateExpr->mTypeRef, BfSourceElementType_TypeRef);
if (mExpectingType->IsObject())
if ((mExpectingType->IsObject()) || (mExpectingType->IsGenericParam()))
{
unresolvedTypeRef = mExpectingType;
@ -11441,7 +11473,7 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
auto genericConstraint = mModule->GetGenericParamInstance((BfGenericParamType*)resolvedTypeRef);
if (genericConstraint->mTypeConstraint == NULL)
{
if ((genericConstraint->mGenericParamFlags & (BfGenericParamFlag_New | BfGenericParamFlag_Struct)) == 0)
if ((genericConstraint->mGenericParamFlags & BfGenericParamFlag_New) == 0)
{
mModule->Fail(StrFormat("Must add 'where %s : new' constraint to generic parameter to instantiate type", genericConstraint->GetGenericParamDef()->mName.c_str()), objCreateExpr->mTypeRef);
}
@ -13151,6 +13183,23 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
}
}
}
else if (mExpectingType->IsGenericParam())
{
if (mModule->mParentNodeEntry != NULL)
{
if (auto invocationExpr = BfNodeDynCast<BfInvocationExpression>(mModule->mParentNodeEntry->mNode))
{
BfResolvedArgs argValues(invocationExpr->mOpenParen, &invocationExpr->mArguments, &invocationExpr->mCommas, invocationExpr->mCloseParen);
BfResolveArgFlags resolveArgsFlags = BfResolveArgFlag_None;
ResolveArgValues(argValues, resolveArgsFlags);
CheckGenericCtor((BfGenericParamType*)mExpectingType, argValues, invocationExpr->mTarget);
mResult = mModule->GetDefaultTypedValue(mExpectingType);
return;
}
}
}
else
{
gaveUnqualifiedDotError = true;

View file

@ -337,6 +337,7 @@ public:
void MarkResultAssigned();
void MakeResultAsValue();
bool CheckModifyResult(BfTypedValue typeValue, BfAstNode* refNode, const char* modifyType, bool onlyNeedsMut = false);
bool CheckGenericCtor(BfGenericParamType* genericParamType, BfResolvedArgs& argValues, BfAstNode* targetSrc);
BfTypedValue LookupField(BfAstNode* targetSrc, BfTypedValue target, const StringImpl& fieldName, BfLookupFieldFlags flags = BfLookupFieldFlag_None);
void CheckObjectCreateTypeRef(BfType* expectingType, BfAstNode* afterNode);
void LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ignoreInitialError = false, bool* hadError = NULL);

View file

@ -6536,22 +6536,22 @@ BfTypedValue BfModule::TryLookupGenericConstVaue(BfIdentifierNode* identifierNod
return BfTypedValue(mBfIRBuilder->GetFakeVal(), genericTypeConstraint);
}
if ((genericParamDef->mGenericParamFlags & BfGenericParamFlag_Const) == 0)
Fail("Only const generic parameters can be used a value", identifierNode);
if ((genericTypeConstraint != NULL) && (expectingType != NULL))
if ((genericParamDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0)
{
if (!CanCast(BfTypedValue(mBfIRBuilder->GetFakeVal(), genericTypeConstraint), expectingType))
if ((genericTypeConstraint != NULL) && (expectingType != NULL))
{
Fail(StrFormat("Generic constraint '%s' is not convertible to 'int'", TypeToString(genericTypeConstraint).c_str()), identifierNode);
if (!CanCast(BfTypedValue(mBfIRBuilder->GetFakeVal(), genericTypeConstraint), expectingType))
{
Fail(StrFormat("Generic constraint '%s' is not convertible to 'int'", TypeToString(genericTypeConstraint).c_str()), identifierNode);
}
}
BfTypedValue result;
result.mType = genericParamResult;
result.mKind = BfTypedValueKind_GenericConstValue;
return result;
}
BfTypedValue result;
result.mType = genericParamResult;
result.mKind = BfTypedValueKind_GenericConstValue;
return result;
}
}
}

View file

@ -9064,6 +9064,8 @@ BfGenericConstraintsDeclaration* BfReducer::CreateGenericConstraintsDeclaration(
case BfToken_Struct:
case BfToken_Const:
case BfToken_Var:
case BfToken_New:
case BfToken_Delete:
addToConstraint = true;
break;
case BfToken_Operator:

View file

@ -3636,14 +3636,35 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
if (!val)
return;
auto checkType = val.mType;
BfGenericParamType* genericType = NULL;
if (val.mType->IsGenericParam())
genericType = (BfGenericParamType*)val.mType;
if ((val.mType->IsPointer()) && (val.mType->GetUnderlyingType()->IsGenericParam()))
genericType = (BfGenericParamType*)val.mType->GetUnderlyingType();
auto checkType = val.mType;
if (genericType != NULL)
{
auto genericParamInst = GetGenericParamInstance((BfGenericParamType*)checkType);
auto genericParamInst = GetGenericParamInstance(genericType);
if (genericParamInst->mTypeConstraint != NULL)
checkType = genericParamInst->mTypeConstraint;
if (genericParamInst->mGenericParamFlags & (BfGenericParamFlag_Delete | BfGenericParamFlag_Var))
bool canAlwaysDelete = checkType->IsDelegate() || checkType->IsFunction() || checkType->IsArray();
if (auto checkTypeInst = checkType->ToTypeInstance())
{
if ((checkTypeInst->mTypeDef == mCompiler->mDelegateTypeDef) ||
(checkTypeInst->mTypeDef == mCompiler->mFunctionTypeDef))
canAlwaysDelete = true;
}
if (!canAlwaysDelete)
{
if (genericParamInst->mGenericParamFlags & (BfGenericParamFlag_Delete | BfGenericParamFlag_Var))
return;
Fail(StrFormat("Must add 'where %s : delete' constraint to generic parameter to delete generic type '%s'",
genericParamInst->GetGenericParamDef()->mName.c_str(), TypeToString(val.mType).c_str()), deleteStmt->mExpression);
return;
}
}
if (checkType->IsVar())