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

@ -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);
}
@ -13108,7 +13140,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
if ((memberRefExpression->mTarget == NULL) && (memberRefExpression->mMemberName == NULL))
{
if (mExpectingType != NULL)
{
{
if (mExpectingType->IsSizedArray())
{
if (mModule->mParentNodeEntry != NULL)
@ -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;