1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Allow some warnings during specialization

This commit is contained in:
Brian Fiete 2021-11-01 13:46:24 -07:00
parent 487ef16efd
commit d593488591
5 changed files with 188 additions and 138 deletions

View file

@ -2844,6 +2844,102 @@ bool BfModule::IsSkippingExtraResolveChecks()
return mCompiler->IsSkippingExtraResolveChecks();
}
bool BfModule::AddErrorContext(StringImpl& errorString, BfAstNode* refNode, bool& isWhileSpecializing)
{
bool isWhileSpecializingMethod = false;
if ((mIsSpecialModule) && (mModuleName == "vdata"))
errorString += StrFormat("\n while generating vdata for project '%s'", mProject->mName.c_str());
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend))
errorString += StrFormat("\n while generating append size calculating method");
else if (refNode == NULL)
{
if (mCurTypeInstance != NULL)
errorString += StrFormat("\n while compiling '%s'", TypeToString(mCurTypeInstance, BfTypeNameFlags_None).c_str());
else if (mProject != NULL)
errorString += StrFormat("\n while compiling project '%s'", mProject->mName.c_str());
}
if (mCurTypeInstance != NULL)
{
auto _CheckMethodInstance = [&](BfMethodInstance* methodInstance)
{
// Propogate the fail all the way to the main method (assuming we're in a local method or lambda)
methodInstance->mHasFailed = true;
bool isSpecializedMethod = ((methodInstance != NULL) && (!methodInstance->mIsUnspecialized) && (methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mMethodGenericArguments.size() != 0));
if (isSpecializedMethod)
{
//auto unspecializedMethod = &mCurMethodInstance->mMethodInstanceGroup->mMethodSpecializationMap.begin()->second;
auto unspecializedMethod = methodInstance->mMethodInstanceGroup->mDefault;
if (unspecializedMethod == methodInstance)
{
// This is a local method inside a generic method
BF_ASSERT(methodInstance->mMethodDef->mIsLocalMethod);
}
else
{
if (unspecializedMethod->mHasFailed)
return false; // At least SOME error has already been reported
}
}
if (isSpecializedMethod)
{
errorString += StrFormat("\n while specializing method '%s'", MethodToString(methodInstance).c_str());
isWhileSpecializing = true;
isWhileSpecializingMethod = true;
}
else if ((methodInstance != NULL) && (methodInstance->mIsForeignMethodDef))
{
errorString += StrFormat("\n while implementing default interface method '%s'", MethodToString(methodInstance).c_str());
isWhileSpecializing = true;
isWhileSpecializingMethod = true;
}
else if ((mCurTypeInstance->IsGenericTypeInstance()) && (!mCurTypeInstance->IsUnspecializedType()))
{
errorString += StrFormat("\n while specializing type '%s'", TypeToString(mCurTypeInstance).c_str());
isWhileSpecializing = true;
}
return true;
};
bool hadMethodInstance = false;
if (mCurMethodState != NULL)
{
auto checkMethodState = mCurMethodState;
while (checkMethodState != NULL)
{
auto methodInstance = checkMethodState->mMethodInstance;
if (methodInstance == NULL)
{
checkMethodState = checkMethodState->mPrevMethodState;
continue;
}
hadMethodInstance = true;
if (!_CheckMethodInstance(methodInstance))
return false;
checkMethodState = checkMethodState->mPrevMethodState;
}
}
if ((!hadMethodInstance) && (mCurMethodInstance != NULL))
{
if (!_CheckMethodInstance(mCurMethodInstance))
return false;
}
}
if ((!isWhileSpecializing) && (mCurTypeInstance != NULL) && ((mCurTypeInstance->IsGenericTypeInstance()) && (!mCurTypeInstance->IsUnspecializedType())))
{
errorString += StrFormat("\n while specializing type '%s'", TypeToString(mCurTypeInstance).c_str());
isWhileSpecializing = true;
}
return true;
}
BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPersistent, bool deferError)
{
BP_ZONE("BfModule::Fail");
@ -2899,105 +2995,15 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
BfLogSysM("BfModule::Fail module %p type %p %s\n", this, mCurTypeInstance, error.c_str());
String errorString = error;
bool isWhileSpecializing = false;
bool isWhileSpecializingMethod = false;
if ((mIsSpecialModule) && (mModuleName == "vdata"))
errorString += StrFormat("\n while generating vdata for project '%s'", mProject->mName.c_str());
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend))
errorString += StrFormat("\n while generating append size calculating method");
else if (refNode == NULL)
{
if (mCurTypeInstance != NULL)
errorString += StrFormat("\n while compiling '%s'", TypeToString(mCurTypeInstance, BfTypeNameFlags_None).c_str());
else if (mProject != NULL)
errorString += StrFormat("\n while compiling project '%s'", mProject->mName.c_str());
}
if (mCurTypeInstance != NULL)
{
auto _CheckMethodInstance = [&](BfMethodInstance* methodInstance)
{
// Propogate the fail all the way to the main method (assuming we're in a local method or lambda)
methodInstance->mHasFailed = true;
bool isSpecializedMethod = ((methodInstance != NULL) && (!methodInstance->mIsUnspecialized) && (methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mMethodGenericArguments.size() != 0));
if (isSpecializedMethod)
{
//auto unspecializedMethod = &mCurMethodInstance->mMethodInstanceGroup->mMethodSpecializationMap.begin()->second;
auto unspecializedMethod = methodInstance->mMethodInstanceGroup->mDefault;
if (unspecializedMethod == methodInstance)
{
// This is a local method inside a generic method
BF_ASSERT(methodInstance->mMethodDef->mIsLocalMethod);
}
else
{
if (unspecializedMethod->mHasFailed)
return false; // At least SOME error has already been reported
}
}
if (isSpecializedMethod)
{
errorString += StrFormat("\n while specializing method '%s'", MethodToString(methodInstance).c_str());
isWhileSpecializing = true;
isWhileSpecializingMethod = true;
}
else if ((methodInstance != NULL) && (methodInstance->mIsForeignMethodDef))
{
errorString += StrFormat("\n while implementing default interface method '%s'", MethodToString(methodInstance).c_str());
isWhileSpecializing = true;
isWhileSpecializingMethod = true;
}
else if ((mCurTypeInstance->IsGenericTypeInstance()) && (!mCurTypeInstance->IsUnspecializedType()))
{
errorString += StrFormat("\n while specializing type '%s'", TypeToString(mCurTypeInstance).c_str());
isWhileSpecializing = true;
}
return true;
};
bool hadMethodInstance = false;
if (mCurMethodState != NULL)
{
auto checkMethodState = mCurMethodState;
while (checkMethodState != NULL)
{
auto methodInstance = checkMethodState->mMethodInstance;
if (methodInstance == NULL)
{
checkMethodState = checkMethodState->mPrevMethodState;
continue;
}
hadMethodInstance = true;
if (!_CheckMethodInstance(methodInstance))
return NULL;
checkMethodState = checkMethodState->mPrevMethodState;
}
}
if ((!hadMethodInstance) && (mCurMethodInstance != NULL))
{
if (!_CheckMethodInstance(mCurMethodInstance))
return NULL;
}
}
String errorString = error;
bool isWhileSpecializing = false;
if (!AddErrorContext(errorString, refNode, isWhileSpecializing))
return false;
BfError* bfError = NULL;
if (isWhileSpecializing)
deferError = true;
if ((!isWhileSpecializing) && (mCurTypeInstance != NULL) && ((mCurTypeInstance->IsGenericTypeInstance()) && (!mCurTypeInstance->IsUnspecializedType())))
{
errorString += StrFormat("\n while specializing type '%s'", TypeToString(mCurTypeInstance).c_str());
isWhileSpecializing = true;
}
if (!mHadBuildError)
mHadBuildError = true;
@ -3085,7 +3091,7 @@ BfError* BfModule::FailAfter(const StringImpl& error, BfAstNode* refNode)
return bfError;
}
BfError* BfModule::Warn(int warningNum, const StringImpl& warning, BfAstNode* refNode, bool isPersistent)
BfError* BfModule::Warn(int warningNum, const StringImpl& warning, BfAstNode* refNode, bool isPersistent, bool showInSpecialized)
{
if (mIgnoreErrors || mIgnoreWarnings)
return NULL;
@ -3113,21 +3119,33 @@ BfError* BfModule::Warn(int warningNum, const StringImpl& warning, BfAstNode* re
{
return NULL;
}
// Right now we're only warning on the unspecialized declarations, we may revisit this
if (mCurMethodInstance != NULL)
{
if (mCurMethodInstance->IsSpecializedGenericMethodOrType())
return NULL;
{
if (!showInSpecialized)
return NULL;
}
if (mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend)
return NULL; // No ctorCalcAppend warnings
}
if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsSpecializedType()))
return NULL;
{
if (!showInSpecialized)
return NULL;
}
if (refNode != NULL)
refNode = BfNodeToNonTemporary(refNode);
String warningString = warning;
bool isWhileSpecializing = false;
if (!AddErrorContext(warningString, refNode, isWhileSpecializing))
return false;
bool deferWarning = isWhileSpecializing;
if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL))
{
// We used to bubble up warnings into the mixin injection site, BUT
@ -3139,17 +3157,18 @@ BfError* BfModule::Warn(int warningNum, const StringImpl& warning, BfAstNode* re
{
BfError* bfError = mCompiler->mPassInstance->Warn(warningNum, "Emitted code had errors", mCurMethodState->mEmitRefNode);
if (bfError != NULL)
mCompiler->mPassInstance->MoreInfo(warning, refNode);
mCompiler->mPassInstance->MoreInfo(warningString, refNode);
return bfError;
}
BfError* bfError;
if (refNode != NULL)
bfError = mCompiler->mPassInstance->WarnAt(warningNum, warning, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength());
bfError = mCompiler->mPassInstance->WarnAt(warningNum, warningString, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength());
else
bfError = mCompiler->mPassInstance->Warn(warningNum, warning);
bfError = mCompiler->mPassInstance->Warn(warningNum, warningString);
if (bfError != NULL)
{
bfError->mIsWhileSpecializing = isWhileSpecializing;
bfError->mProject = mProject;
AddFailType(mCurTypeInstance);
@ -3229,7 +3248,7 @@ void BfModule::CheckErrorAttributes(BfTypeInstance* typeInstance, BfMethodInstan
if (isError)
error = Fail(err, targetSrc);
else
error = Warn(0, err, targetSrc);
error = Warn(0, err, targetSrc, false, true);
if (error != NULL)
_AddDeclarationMoreInfo();
}
@ -3262,7 +3281,7 @@ void BfModule::CheckErrorAttributes(BfTypeInstance* typeInstance, BfMethodInstan
if (str != NULL)
err += *str;
err += "'";
if (Warn(0, err, targetSrc) != NULL)
if (Warn(0, err, targetSrc, false, true) != NULL)
_AddDeclarationMoreInfo();
}
}
@ -7590,7 +7609,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
if (origCheckArgType->IsRef())
origCheckArgType = origCheckArgType->GetUnderlyingType();
bool argMayBeReferenceType = false;
bool argIsReferenceType = false;
int checkGenericParamFlags = 0;
if (checkArgType->IsGenericParam())
@ -7600,18 +7619,18 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
if (checkGenericParamInst->mTypeConstraint != NULL)
checkArgType = checkGenericParamInst->mTypeConstraint;
if ((checkGenericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr)) != 0)
{
argMayBeReferenceType = false;
}
else
{
argMayBeReferenceType = true;
}
// if ((checkGenericParamFlags & (BfGenericParamFlag_Struct | BfGenericParamFlag_StructPtr)) != 0)
// {
// argMayBeReferenceType = false;
// }
// else
// {
// argMayBeReferenceType = true;
// }
}
if (checkArgType->IsObjectOrInterface())
argMayBeReferenceType = true;
argIsReferenceType = true;
BfTypeInstance* typeConstraintInst = NULL;
if (genericParamInst->mTypeConstraint != NULL)
@ -7636,7 +7655,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
}
if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Class) &&
((checkGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_Var)) == 0) && (!argMayBeReferenceType))
((checkGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_Var)) == 0) && (!argIsReferenceType))
{
if ((!ignoreErrors) && (PreFail()))
*errorOut = Fail(StrFormat("The type '%s' must be a reference type in order to use it as parameter '%s' for '%s'",