1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 04:22:20 +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

@ -173,6 +173,10 @@ namespace System
// or the memory would already be registered with the GC
}
public static mixin Mark<T>(T val)
{
}
public static mixin Mark<TSizedArray, T, Size>(TSizedArray val) where Size : const int where TSizedArray : SizedArray<T, Size>
{
#if BF_ENABLE_REALTIME_LEAK_CHECK

View file

@ -2844,65 +2844,9 @@ bool BfModule::IsSkippingExtraResolveChecks()
return mCompiler->IsSkippingExtraResolveChecks();
}
BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPersistent, bool deferError)
bool BfModule::AddErrorContext(StringImpl& errorString, BfAstNode* refNode, bool& isWhileSpecializing)
{
BP_ZONE("BfModule::Fail");
if (mIgnoreErrors)
{
mHadIgnoredError = true;
if (mAttributeState != NULL)
mAttributeState->mFlags = (BfAttributeState::Flags)(mAttributeState->mFlags | BfAttributeState::Flag_HadError);
return NULL;
}
if (!mReportErrors)
{
mCompiler->mPassInstance->SilentFail();
return NULL;
}
if (refNode != NULL)
refNode = BfNodeToNonTemporary(refNode);
//BF_ASSERT(refNode != NULL);
if (mIsComptimeModule)
{
if ((mCompiler->mCEMachine->mCurContext != NULL) && (mCompiler->mCEMachine->mCurContext->mCurTargetSrc != NULL))
{
BfError* bfError = mCompiler->mPassInstance->Fail("Comptime method generation had errors", mCompiler->mCEMachine->mCurContext->mCurTargetSrc);
if (bfError != NULL)
mCompiler->mPassInstance->MoreInfo(error, refNode);
return bfError;
}
mHadBuildError = true;
return NULL;
}
if (mCurMethodInstance != NULL)
mCurMethodInstance->mHasFailed = true;
if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsUnspecializedTypeVariation()))
return NULL;
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->IsOrInUnspecializedVariation()))
return NULL; // Ignore errors on unspecialized variations, they are always dups
if (!mHadBuildError)
mHadBuildError = true;
if (mParentModule != NULL)
mParentModule->mHadBuildError = true;
if (mCurTypeInstance != NULL)
AddFailType(mCurTypeInstance);
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))
@ -2975,7 +2919,7 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
hadMethodInstance = true;
if (!_CheckMethodInstance(methodInstance))
return NULL;
return false;
checkMethodState = checkMethodState->mPrevMethodState;
}
}
@ -2983,21 +2927,83 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
if ((!hadMethodInstance) && (mCurMethodInstance != NULL))
{
if (!_CheckMethodInstance(mCurMethodInstance))
return NULL;
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;
}
return true;
}
BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPersistent, bool deferError)
{
BP_ZONE("BfModule::Fail");
if (mIgnoreErrors)
{
mHadIgnoredError = true;
if (mAttributeState != NULL)
mAttributeState->mFlags = (BfAttributeState::Flags)(mAttributeState->mFlags | BfAttributeState::Flag_HadError);
return NULL;
}
if (!mReportErrors)
{
mCompiler->mPassInstance->SilentFail();
return NULL;
}
if (refNode != NULL)
refNode = BfNodeToNonTemporary(refNode);
//BF_ASSERT(refNode != NULL);
if (mIsComptimeModule)
{
if ((mCompiler->mCEMachine->mCurContext != NULL) && (mCompiler->mCEMachine->mCurContext->mCurTargetSrc != NULL))
{
BfError* bfError = mCompiler->mPassInstance->Fail("Comptime method generation had errors", mCompiler->mCEMachine->mCurContext->mCurTargetSrc);
if (bfError != NULL)
mCompiler->mPassInstance->MoreInfo(error, refNode);
return bfError;
}
mHadBuildError = true;
return NULL;
}
if (mCurMethodInstance != NULL)
mCurMethodInstance->mHasFailed = true;
if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsUnspecializedTypeVariation()))
return NULL;
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->IsOrInUnspecializedVariation()))
return NULL; // Ignore errors on unspecialized variations, they are always dups
if (!mHadBuildError)
mHadBuildError = true;
if (mParentModule != NULL)
mParentModule->mHadBuildError = true;
if (mCurTypeInstance != NULL)
AddFailType(mCurTypeInstance);
BfLogSysM("BfModule::Fail module %p type %p %s\n", this, mCurTypeInstance, error.c_str());
String errorString = error;
bool isWhileSpecializing = false;
if (!AddErrorContext(errorString, refNode, isWhileSpecializing))
return false;
BfError* bfError = NULL;
if (isWhileSpecializing)
deferError = 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;
@ -3118,16 +3124,28 @@ BfError* BfModule::Warn(int warningNum, const StringImpl& warning, BfAstNode* re
if (mCurMethodInstance != NULL)
{
if (mCurMethodInstance->IsSpecializedGenericMethodOrType())
{
if (!showInSpecialized)
return NULL;
}
if (mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend)
return NULL; // No ctorCalcAppend warnings
}
if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsSpecializedType()))
{
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'",

View file

@ -1517,10 +1517,11 @@ public:
void SetFail();
void VerifyOnDemandMethods();
bool IsSkippingExtraResolveChecks();
bool AddErrorContext(StringImpl& errorString, BfAstNode* refNode, bool& isWhileSpecializing);
BfError* Fail(const StringImpl& error, BfAstNode* refNode = NULL, bool isPersistent = false, bool deferError = false);
BfError* FailInternal(const StringImpl& error, BfAstNode* refNode = NULL);
BfError* FailAfter(const StringImpl& error, BfAstNode* refNode);
BfError* Warn(int warningNum, const StringImpl& warning, BfAstNode* refNode = NULL, bool isPersistent = false);
BfError* Warn(int warningNum, const StringImpl& warning, BfAstNode* refNode = NULL, bool isPersistent = false, bool showInSpecialized = false);
void CheckErrorAttributes(BfTypeInstance* typeInstance, BfMethodInstance* methodInstance, BfCustomAttributes* customAttributes, BfAstNode* targetSrc);
void CheckRangeError(BfType* type, BfAstNode* refNode);
bool CheckCircularDataError();

View file

@ -1589,7 +1589,7 @@ void BfPassInstance::SilentFail()
mFailedIdx++;
}
BfError* BfPassInstance::WarnAt(int warningNumber, const StringImpl& warning, BfSourceData* bfSource, int srcIdx, int srcLen)
BfError* BfPassInstance::WarnAt(int warningNumber, const StringImpl& warning, BfSourceData* bfSource, int srcIdx, int srcLen, bool isDeferred)
{
mLastWasAdded = false;
if ((int) mErrors.size() >= sMaxErrors)
@ -1599,7 +1599,7 @@ BfError* BfPassInstance::WarnAt(int warningNumber, const StringImpl& warning, Bf
if ((bfParser != NULL) && (warningNumber > 0) && (!bfParser->IsWarningEnabledAtSrcIndex(warningNumber, srcIdx)))
return NULL;
if (!WantsRangeRecorded(bfParser, srcIdx, srcLen, true))
if (!WantsRangeRecorded(bfParser, srcIdx, srcLen, true, isDeferred))
return NULL;
mWarnIdx++;
@ -1614,12 +1614,15 @@ BfError* BfPassInstance::WarnAt(int warningNumber, const StringImpl& warning, Bf
errorVal->mError = warning;
errorVal->mSrcStart = srcIdx;
errorVal->mSrcEnd = srcIdx + srcLen;
errorVal->mIsDeferred = isDeferred;
FixSrcStartAndEnd(bfSource, errorVal->mSrcStart, errorVal->mSrcEnd);
mErrorSet.Add(BfErrorEntry(errorVal));
mErrors.push_back(errorVal);
++mWarningCount;
mLastWasAdded = true;
if (!isDeferred)
{
mLastWasDisplayed = WantsRangeDisplayed(bfParser, srcIdx, srcLen, true);
if (mLastWasDisplayed)
{
@ -1630,6 +1633,7 @@ BfError* BfPassInstance::WarnAt(int warningNumber, const StringImpl& warning, Bf
errorStart += StrFormat(": BF%04d", warningNumber);
MessageAt(":warn", errorStart + ": " + warning, bfParser, srcIdx);
}
}
return errorVal;
}
@ -1645,7 +1649,7 @@ BfError* BfPassInstance::Warn(int warningNumber, const StringImpl& warning)
return NULL;
}
BfError* BfPassInstance::Warn(int warningNumber, const StringImpl& warning, BfAstNode* refNode)
BfError* BfPassInstance::Warn(int warningNumber, const StringImpl& warning, BfAstNode* refNode, bool isDeferred)
{
BP_ZONE("BfPassInstance::Warn");
@ -1666,7 +1670,7 @@ BfError* BfPassInstance::Warn(int warningNumber, const StringImpl& warning, BfAs
}
if (refNode != NULL)
return WarnAt(warningNumber, warning, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength());
return WarnAt(warningNumber, warning, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength(), isDeferred);
else
return Warn(warningNumber, warning);
}
@ -1798,15 +1802,39 @@ void BfPassInstance::TryFlushDeferredError()
// This can happen in the case of an internal compiler error, where we believe we've satisfied
// generic constraints but we generate an error on the specialization but not the unspecialized version
bool hasDisplayedError = false;
bool hasDisplayedWarning = false;
for (int pass = 0; pass < 2; pass++)
{
for (auto& error : mErrors)
{
if (!error->mIsWarning)
if (error->mIsWarning)
{
if (!error->mIsDeferred)
hasDisplayedWarning = true;
else if ((pass == 1) && (!hasDisplayedWarning))
{
String errorText = "WARNING ";
if (error->mWarningNumber > 0)
errorText += StrFormat(": BF%04d", error->mWarningNumber);
errorText += ": ";
errorText += error->mError;
MessageAt(":warning", errorText, error->mSource, error->mSrcStart, error->mSrcEnd - error->mSrcStart);
for (auto moreInfo : error->mMoreInfo)
{
if (moreInfo->mSource != NULL)
MessageAt(":warning", " > " + moreInfo->mInfo, moreInfo->mSource, moreInfo->mSrcStart, moreInfo->mSrcEnd - moreInfo->mSrcStart);
else
OutputLine(":warning " + moreInfo->mInfo);
}
}
}
else
{
if (!error->mIsDeferred)
hasDisplayedError = true;
else if (pass == 1)
else if ((pass == 1) && (!hasDisplayedError))
{
MessageAt(":error", "ERROR: " + error->mError, error->mSource, error->mSrcStart, error->mSrcEnd - error->mSrcStart);
@ -1820,9 +1848,6 @@ void BfPassInstance::TryFlushDeferredError()
}
}
}
if ((pass == 0) && (hasDisplayedError))
break;
}
}

View file

@ -1383,9 +1383,10 @@ public:
void MessageAt(const StringImpl& msgPrefix, const StringImpl& error, BfSourceData* bfSource, int srcIdx, int srcLen = 1, BfFailFlags flags = BfFailFlag_None);
void FixSrcStartAndEnd(BfSourceData* source, int& startIdx, int& endIdx);
BfError* WarnAt(int warningNumber, const StringImpl& warning, BfSourceData* bfSource, int srcIdx, int srcLen = 1);
BfError* WarnAt(int warningNumber, const StringImpl& warning, BfSourceData* bfSource, int srcIdx, int srcLen = 1, bool isDeferred = false);
BfError* Warn(int warningNumber, const StringImpl& warning);
BfError* Warn(int warningNumber, const StringImpl& warning, BfAstNode* refNode);
BfError* Warn(int warningNumber, const StringImpl& warning, BfAstNode* refNode, bool isDeferred = false);
BfError* DeferWarn(int warningNumber, const StringImpl& warning, BfAstNode* refNode);
BfError* WarnAfter(int warningNumber, const StringImpl& warning, BfAstNode* refNode);
BfError* WarnAfterAt(int warningNumber, const StringImpl& error, BfSourceData* bfSource, int srcIdx);