mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Fixes for type dependencies and tests for type deletion bug
This commit is contained in:
parent
198acef1c6
commit
03fbc9d468
16 changed files with 309 additions and 55 deletions
5
IDE/Tests/BugW004/BeefProj.toml
Normal file
5
IDE/Tests/BugW004/BeefProj.toml
Normal file
|
@ -0,0 +1,5 @@
|
|||
FileVersion = 1
|
||||
|
||||
[Project]
|
||||
Name = "Bug"
|
||||
StartupObject = "Bug.Program"
|
6
IDE/Tests/BugW004/BeefSpace.toml
Normal file
6
IDE/Tests/BugW004/BeefSpace.toml
Normal file
|
@ -0,0 +1,6 @@
|
|||
FileVersion = 1
|
||||
Projects = {Bug = {Path = "."}}
|
||||
|
||||
[Workspace]
|
||||
StartupProject = "Bug"
|
||||
|
21
IDE/Tests/BugW004/scripts/Test.txt
Normal file
21
IDE/Tests/BugW004/scripts/Test.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
# This tests that types that fail generic tests don't create types referenced in methods
|
||||
# and also that they get deleted immediately when they are dereferenced.
|
||||
|
||||
ShowFile("src/Program.bf")
|
||||
|
||||
SetExpectError("Generic argument")
|
||||
Compile()
|
||||
ExpectError()
|
||||
|
||||
AssertTypeInfo(1, "System.Collections.Dictionary<System.Collections.Dictionary<int, float>.Enumerator, (int key, float value)>", "Found Reified ValidateErrors")
|
||||
AssertTypeInfo(1, "System.Collections.Dictionary<System.Collections.Dictionary<int, float>.Enumerator, (int key, float value)>.Entry", "Found Reified ValidateErrors")
|
||||
|
||||
ToggleCommentAt("Method3_BadCall")
|
||||
ToggleCommentAt("Method3_GoodCall")
|
||||
|
||||
Compile()
|
||||
|
||||
AssertTypeInfo(0, "System.Collections.Dictionary<System.Collections.Dictionary<int, float>.Enumerator, (int key, float value)>", "")
|
||||
AssertTypeInfo(0, "System.Collections.Dictionary<System.Collections.Dictionary<int, float>.Enumerator, (int key, float value)>.Entry", "")
|
||||
AssertTypeInfo(0, "System.Collections.Dictionary<System.Collections.Dictionary<int, float>.Enumerator, (int key, float value)>", "")
|
||||
AssertTypeInfo(0, "System.Collections.Dictionary<System.Collections.Dictionary<int, float>.Enumerator, (int key, float value)>.Entry", "")
|
49
IDE/Tests/BugW004/src/Program.bf
Normal file
49
IDE/Tests/BugW004/src/Program.bf
Normal file
|
@ -0,0 +1,49 @@
|
|||
#pragma warning disable 168
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Bug
|
||||
{
|
||||
class Program
|
||||
{
|
||||
class Dicto : Dictionary<int, float>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static bool Method1<T>(IEnumerator<T> param1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool Method2<TEnumerator, TElement>(TEnumerator param1) where TEnumerator : IEnumerator<TElement>
|
||||
{
|
||||
for (let val in param1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool Method3<K, V>(Dictionary<K, V> param1) where K : IHashable
|
||||
{
|
||||
Method1(param1.GetEnumerator());
|
||||
Method1((IEnumerator<(K key, V value)>)param1.GetEnumerator());
|
||||
//*Method3_BadCall
|
||||
return Method3<Dictionary<K, V>.Enumerator, (K key, V value)>(param1.GetEnumerator());
|
||||
/*@*/
|
||||
|
||||
/*Method3_GoodCall
|
||||
return Method2<Dictionary<K, V>.Enumerator, (K key, V value)>(param1.GetEnumerator());
|
||||
*/
|
||||
}
|
||||
|
||||
static void Main()
|
||||
{
|
||||
Dicto dicto = scope .();
|
||||
Method3(dicto);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -99,6 +99,9 @@ namespace IDE.Compiler
|
|||
[CallingConvention(.Stdcall), CLink]
|
||||
static extern char8* BfCompiler_GetTypeDefInfo(void* bfCompiler, char8* typeDefName);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
static extern char8* BfCompiler_GetTypeInfo(void* bfCompiler, char8* typeName);
|
||||
|
||||
[CallingConvention(.Stdcall), CLink]
|
||||
static extern void BfCompiler_SetOptions(void* bfCompiler,
|
||||
void* hotProject, int32 hotIdx, char8* targetTriple, int32 toolsetType, int32 simdSetting, int32 allocStackCount, int32 maxWorkerThreads,
|
||||
|
@ -682,6 +685,11 @@ namespace IDE.Compiler
|
|||
outStr.Append(BfCompiler_GetTypeDefInfo(mNativeBfCompiler, typeDefName));
|
||||
}
|
||||
|
||||
public void GetTypeInfo(String typeDefName, String outStr)
|
||||
{
|
||||
outStr.Append(BfCompiler_GetTypeInfo(mNativeBfCompiler, typeDefName));
|
||||
}
|
||||
|
||||
public void ClearBuildCache()
|
||||
{
|
||||
BfCompiler_ClearBuildCache(mNativeBfCompiler);
|
||||
|
|
|
@ -4417,7 +4417,8 @@ namespace IDE
|
|||
if (!mInitialized)
|
||||
return;
|
||||
#if !CLI
|
||||
mLastActivePanel = panel;
|
||||
if (setFocus)
|
||||
mLastActivePanel = panel;
|
||||
RecordHistoryLocation();
|
||||
ShowTab(panel, label, false, setFocus);
|
||||
if (setFocus)
|
||||
|
@ -4580,7 +4581,7 @@ namespace IDE
|
|||
[IDECommand]
|
||||
public void ShowOutput()
|
||||
{
|
||||
ShowPanel(mOutputPanel, "Output");
|
||||
ShowPanel(mOutputPanel, "Output", false);
|
||||
}
|
||||
|
||||
[IDECommand]
|
||||
|
|
|
@ -1513,6 +1513,17 @@ namespace IDE
|
|||
}
|
||||
}
|
||||
|
||||
[IDECommand]
|
||||
public void AssertTypeInfo(int compilerId, String typeName, String wantTypeInfo)
|
||||
{
|
||||
String typeInfo = scope String();
|
||||
var compiler = (compilerId == 0) ? gApp.mBfResolveCompiler : gApp.mBfBuildCompiler;
|
||||
compiler.GetTypeInfo(typeName, typeInfo);
|
||||
|
||||
if (typeInfo != wantTypeInfo)
|
||||
mScriptManager.Fail("Assert failed: {0} == {1}", typeInfo, wantTypeInfo);
|
||||
}
|
||||
|
||||
[IDECommand]
|
||||
public void AddWatch(String evalStr)
|
||||
{
|
||||
|
|
|
@ -2052,6 +2052,8 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork)
|
|||
if ((mResolvePassData != NULL) && (mResolvePassData->mParser != NULL))
|
||||
madeFullPass = false;
|
||||
|
||||
SetAndRestoreValue<bool> prevAssertOnPopulateType(mContext->mAssertOnPopulateType, deleteUnusued && madeFullPass);
|
||||
|
||||
if ((deleteUnusued) && (madeFullPass))
|
||||
{
|
||||
// Work queues should be empty if we're not canceling
|
||||
|
@ -2077,7 +2079,12 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork)
|
|||
auto typeInst = type->ToTypeInstance();
|
||||
|
||||
if (depType != NULL)
|
||||
{
|
||||
{
|
||||
if ((depType->mTypeId == 2574) && (!mIsResolveOnly) && (deleteUnusued))
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
extern BfModule* gLastCreatedModule;
|
||||
|
||||
for (auto itr = depType->mDependencyMap.begin(); itr != depType->mDependencyMap.end(); ++itr)
|
||||
|
@ -2145,12 +2152,9 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork)
|
|||
|
||||
if ((depTypeInst != NULL) && (typeInst->mLastNonGenericUsedRevision != mRevision) && (isDependentUsage) &&
|
||||
((isDirectReference) || (dependentType->IsUnspecializedType()) || (depTypeInst->mLastNonGenericUsedRevision == mRevision)))
|
||||
{
|
||||
//if (deleteUnusued)
|
||||
{
|
||||
typeInst->mLastNonGenericUsedRevision = mRevision;
|
||||
foundNew = true;
|
||||
}
|
||||
{
|
||||
typeInst->mLastNonGenericUsedRevision = mRevision;
|
||||
foundNew = true;
|
||||
|
||||
if (!typeInst->HasBeenReferenced())
|
||||
{
|
||||
|
@ -8250,6 +8254,92 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetTypeDefInfo(BfCompiler* bfCompil
|
|||
return outString.c_str();
|
||||
}
|
||||
|
||||
BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetTypeInfo(BfCompiler* bfCompiler, const char* name)
|
||||
{
|
||||
String& outString = *gTLStrReturn.Get();
|
||||
outString = "";
|
||||
|
||||
String typeName = name;
|
||||
|
||||
auto system = bfCompiler->mSystem;
|
||||
AutoCrit autoCrit(system->mSystemLock);
|
||||
|
||||
String& autoCompleteResultString = *gTLStrReturn.Get();
|
||||
autoCompleteResultString.Clear();
|
||||
|
||||
BfPassInstance passInstance(bfCompiler->mSystem);
|
||||
|
||||
BfParser parser(bfCompiler->mSystem);
|
||||
parser.SetSource(typeName.c_str(), (int)typeName.length());
|
||||
parser.Parse(&passInstance);
|
||||
|
||||
BfReducer reducer;
|
||||
reducer.mAlloc = parser.mAlloc;
|
||||
reducer.mPassInstance = &passInstance;
|
||||
reducer.mAllowTypeWildcard = true;
|
||||
|
||||
if (parser.mRootNode->mChildArr.mSize == 0)
|
||||
return false;
|
||||
|
||||
bool attribWasClosed = false;
|
||||
bool isAttributeRef = false;
|
||||
auto firstNode = parser.mRootNode->mChildArr[0];
|
||||
auto endIdx = parser.mRootNode->mSrcEnd;
|
||||
reducer.mVisitorPos = BfReducer::BfVisitorPos(parser.mRootNode);
|
||||
if (auto tokenNode = BfNodeDynCast<BfTokenNode>(firstNode))
|
||||
{
|
||||
if (tokenNode->mToken == BfToken_LBracket)
|
||||
{
|
||||
if (auto lastToken = BfNodeDynCast<BfTokenNode>(parser.mRootNode->mChildArr.back()))
|
||||
{
|
||||
if (lastToken->mToken == BfToken_RBracket)
|
||||
{
|
||||
attribWasClosed = true;
|
||||
endIdx = lastToken->mSrcStart;
|
||||
}
|
||||
}
|
||||
|
||||
isAttributeRef = true;
|
||||
if (parser.mRootNode->mChildArr.mSize < 2)
|
||||
return false;
|
||||
firstNode = parser.mRootNode->mChildArr[1];
|
||||
reducer.mVisitorPos.MoveNext();
|
||||
}
|
||||
}
|
||||
|
||||
reducer.mVisitorPos.MoveNext();
|
||||
auto typeRef = reducer.CreateTypeRef(firstNode);
|
||||
if (typeRef == NULL)
|
||||
return "";
|
||||
|
||||
BfResolvePassData resolvePass;
|
||||
SetAndRestoreValue<bool> prevIgnoreError(bfCompiler->mContext->mScratchModule->mIgnoreErrors, true);
|
||||
SetAndRestoreValue<bool> prevIgnoreWarnings(bfCompiler->mContext->mScratchModule->mIgnoreWarnings, true);
|
||||
SetAndRestoreValue<BfResolvePassData*> prevResolvePass(bfCompiler->mResolvePassData, &resolvePass);
|
||||
|
||||
auto type = bfCompiler->mContext->mScratchModule->ResolveTypeRef(typeRef, BfPopulateType_Data, BfResolveTypeRefFlag_NoCreate);
|
||||
if (type != NULL)
|
||||
{
|
||||
outString += "Found";
|
||||
if (auto typeInst = type->ToTypeInstance())
|
||||
{
|
||||
if (typeInst->mIsReified)
|
||||
outString += " Reified";
|
||||
if (typeInst->mHasBeenInstantiated)
|
||||
outString += " Instantiated";
|
||||
if (typeInst->mTypeFailed)
|
||||
outString += " TypeFailed";
|
||||
if (auto genericTypeInst = typeInst->ToGenericTypeInstance())
|
||||
{
|
||||
if (genericTypeInst->mHadValidateErrors)
|
||||
outString += " ValidateErrors";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return outString.c_str();
|
||||
}
|
||||
|
||||
BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetOutputFileNames(BfCompiler* bfCompiler, BfProject* bfProject, bool* hadOutputChanges)
|
||||
{
|
||||
BF_FATAL("not used ?");
|
||||
|
|
|
@ -48,6 +48,7 @@ BfContext::BfContext(BfCompiler* compiler) :
|
|||
mCurTypeState = NULL;
|
||||
mCurConstraintState = NULL;
|
||||
mResolvingVarField = false;
|
||||
mAssertOnPopulateType = false;
|
||||
|
||||
for (int i = 0; i < BfTypeCode_Length; i++)
|
||||
{
|
||||
|
@ -762,6 +763,8 @@ BfType * BfContext::FindTypeById(int typeId)
|
|||
|
||||
void BfContext::AddTypeToWorkList(BfType* type)
|
||||
{
|
||||
BF_ASSERT(!mAssertOnPopulateType);
|
||||
|
||||
BF_ASSERT((type->mRebuildFlags & BfTypeRebuildFlag_InTempPool) == 0);
|
||||
if ((type->mRebuildFlags & BfTypeRebuildFlag_AddedToWorkList) == 0)
|
||||
{
|
||||
|
@ -1464,8 +1467,8 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type->mRebuildFlags = (BfTypeRebuildFlags)((type->mRebuildFlags | BfTypeRebuildFlag_Deleted) & ~BfTypeRebuildFlag_DeleteQueued);
|
||||
SaveDeletingType(type);
|
||||
|
||||
|
@ -1530,6 +1533,19 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds)
|
|||
if ((dependencyEntry.mFlags & ~(BfDependencyMap::DependencyFlag_UnspecializedType | BfDependencyMap::DependencyFlag_WeakReference)) == 0)
|
||||
continue; // Not a cause for rebuilding
|
||||
|
||||
if (dependentTypeInst->IsOnDemand())
|
||||
{
|
||||
// Force on-demand dependencies to rebuild themselves
|
||||
DeleteType(dependentType, deferDepRebuilds);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dType->IsBoxed())
|
||||
{
|
||||
// Allow these to just be implicitly used. This solves some issues with switching between ignoreWrites settings in resolveOnly compilation
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((deferDepRebuilds) && (dependentTypeInst != NULL))
|
||||
mFailTypes.Add(dependentTypeInst);
|
||||
else
|
||||
|
|
|
@ -317,6 +317,7 @@ public:
|
|||
BfConstraintState* mCurConstraintState;
|
||||
bool mResolvingVarField;
|
||||
int mMappedObjectRevision;
|
||||
bool mAssertOnPopulateType;
|
||||
|
||||
BfSystem* mSystem;
|
||||
BfCompiler* mCompiler;
|
||||
|
|
|
@ -1369,9 +1369,9 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
|||
|
||||
if (checkMethod->mMethodType == BfMethodType_Extension)
|
||||
{
|
||||
argIdx--;
|
||||
paramOfs++;
|
||||
argIdx--;
|
||||
}
|
||||
paramIdx += paramOfs;
|
||||
|
||||
for ( ; argIdx < (int)mArguments.size(); argIdx++)
|
||||
{
|
||||
|
@ -1845,7 +1845,8 @@ bool BfMethodMatcher::IsType(BfTypedValue& typedVal, BfType* type)
|
|||
|
||||
// This method checks all base classes before checking interfaces. Is that correct?
|
||||
bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue target, bool isFailurePass, bool forceOuterCheck)
|
||||
{
|
||||
{
|
||||
BfMethodDef* prevBesstMethodDef = mBestMethodDef;
|
||||
auto curTypeInst = typeInstance;
|
||||
auto curTypeDef = typeInstance->mTypeDef;
|
||||
|
||||
|
@ -2041,7 +2042,7 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe
|
|||
if (mAutoFlushAmbiguityErrors)
|
||||
FlushAmbiguityError();
|
||||
|
||||
return mBestMethodDef != NULL;
|
||||
return mBestMethodDef != prevBesstMethodDef;
|
||||
}
|
||||
|
||||
void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* origTarget, BfTypedValue* staticResult)
|
||||
|
@ -7155,9 +7156,8 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
|||
{
|
||||
auto checkTypeInst = mModule->mCurTypeInstance;
|
||||
methodMatcher.mMethodType = BfMethodType_Extension;
|
||||
methodMatcher.CheckType(checkTypeInst, BfTypedValue(), false, true);
|
||||
if (methodMatcher.mBestMethodDef != NULL)
|
||||
{
|
||||
if (methodMatcher.CheckType(checkTypeInst, BfTypedValue(), false, true))
|
||||
{
|
||||
isFailurePass = false;
|
||||
curTypeInst = methodMatcher.mBestMethodTypeInstance;
|
||||
methodDef = methodMatcher.mBestMethodDef;
|
||||
|
@ -7178,9 +7178,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
|||
if (globalContainer.mTypeInst == NULL)
|
||||
continue;
|
||||
methodMatcher.mMethodType = wantsExtensionCheck ? BfMethodType_Extension : BfMethodType_Normal;
|
||||
methodMatcher.CheckType(globalContainer.mTypeInst, BfTypedValue(), false);
|
||||
|
||||
if (methodMatcher.mBestMethodDef != NULL)
|
||||
if (methodMatcher.CheckType(globalContainer.mTypeInst, BfTypedValue(), false))
|
||||
{
|
||||
isFailurePass = false;
|
||||
curTypeInst = methodMatcher.mBestMethodTypeInstance;
|
||||
|
@ -7202,8 +7200,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
|||
for (auto typeInst : staticSearch->mStaticTypes)
|
||||
{
|
||||
methodMatcher.mMethodType = wantsExtensionCheck ? BfMethodType_Extension : BfMethodType_Normal;
|
||||
methodMatcher.CheckType(typeInst, BfTypedValue(), false);
|
||||
if (methodMatcher.mBestMethodDef != NULL)
|
||||
if (methodMatcher.CheckType(typeInst, BfTypedValue(), false))
|
||||
{
|
||||
isFailurePass = false;
|
||||
curTypeInst = methodMatcher.mBestMethodTypeInstance;
|
||||
|
@ -11995,7 +11992,11 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((!resolvedTypeRef->IsObjectOrInterface()) && (!resolvedTypeRef->IsGenericParam()))
|
||||
if (resolvedTypeRef->IsVar())
|
||||
{
|
||||
// Leave as a var
|
||||
}
|
||||
else if ((!resolvedTypeRef->IsObjectOrInterface()) && (!resolvedTypeRef->IsGenericParam()))
|
||||
{
|
||||
resultType = mModule->CreatePointerType(resolvedTypeRef);
|
||||
}
|
||||
|
|
|
@ -2991,6 +2991,16 @@ void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap
|
|||
if (usedType->IsSpecializedByAutoCompleteMethod())
|
||||
return;
|
||||
|
||||
// if (usedType->IsBoxed())
|
||||
// {
|
||||
// NOP;
|
||||
// auto underlyingType = usedType->GetUnderlyingType()->ToTypeInstance();
|
||||
// if ((underlyingType != NULL) && (underlyingType->IsInstanceOf(mCompiler->mSizedArrayTypeDef)))
|
||||
// {
|
||||
// BfLogSysM("AddDependency UsedType:%p UserType:%p Method:%p\n", usedType, userType, mCurMethodInstance);
|
||||
// }
|
||||
// }
|
||||
|
||||
BfType* origUsedType = usedType;
|
||||
bool isDataAccess = ((flags & (BfDependencyMap::DependencyFlag_ReadFields | BfDependencyMap::DependencyFlag_LocalUsage | BfDependencyMap::DependencyFlag_Allocates)) != 0);
|
||||
if (isDataAccess)
|
||||
|
@ -18581,6 +18591,7 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth
|
|||
|
||||
BF_ASSERT(methodInstance->mMethodInfoEx != NULL);
|
||||
methodState.mGenericTypeBindings = &methodInstance->mMethodInfoEx->mGenericTypeBindings;
|
||||
methodState.mMethodInstance = methodInstance;
|
||||
|
||||
NewScopeState();
|
||||
ProcessMethod_SetupParams(methodInstance, NULL, false, NULL);
|
||||
|
|
|
@ -1268,22 +1268,6 @@ public:
|
|||
String mName;
|
||||
};
|
||||
|
||||
enum BfResolveTypeRefFlags
|
||||
{
|
||||
BfResolveTypeRefFlag_None = 0,
|
||||
BfResolveTypeRefFlag_NoResolveGenericParam = 1,
|
||||
BfResolveTypeRefFlag_AllowRef = 2,
|
||||
BfResolveTypeRefFlag_AllowRefGeneric = 4,
|
||||
BfResolveTypeRefFlag_IgnoreLookupError = 8,
|
||||
BfResolveTypeRefFlag_AllowGenericTypeParamConstValue = 0x10,
|
||||
BfResolveTypeRefFlag_AllowGenericMethodParamConstValue = 0x20,
|
||||
BfResolveTypeRefFlag_AllowGenericParamConstValue = 0x10 | 0x20,
|
||||
BfResolveTypeRefFlag_AutoComplete = 0x40,
|
||||
BfResolveTypeRefFlag_FromIndirectSource = 0x80, // Such as a type alias or a generic parameter
|
||||
BfResolveTypeRefFlag_Attribute = 0x100,
|
||||
BfResolveTypeRefFlag_NoReify = 0x200
|
||||
};
|
||||
|
||||
enum BfSrcPosFlags
|
||||
{
|
||||
BfSrcPosFlag_None = 0,
|
||||
|
|
|
@ -881,6 +881,11 @@ bool BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
|
|||
else
|
||||
resolvedTypeRef->mTypeId = mCompiler->mCurTypeId++;
|
||||
|
||||
if ((resolvedTypeRef->mTypeId == 2599) && (!mCompiler->mIsResolveOnly))
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
while (resolvedTypeRef->mTypeId >= (int)mContext->mTypes.size())
|
||||
mContext->mTypes.Add(NULL);
|
||||
mContext->mTypes[resolvedTypeRef->mTypeId] = resolvedTypeRef;
|
||||
|
@ -3648,6 +3653,13 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
|||
}
|
||||
}
|
||||
|
||||
bool isFailedType = mCurTypeInstance->mTypeFailed;
|
||||
if (auto genericTypeInst = mCurTypeInstance->ToGenericTypeInstance())
|
||||
{
|
||||
if (genericTypeInst->mHadValidateErrors)
|
||||
isFailedType = true;
|
||||
}
|
||||
|
||||
// Generate all methods. Pass 1
|
||||
for (auto methodDef : typeDef->mMethods)
|
||||
{
|
||||
|
@ -3656,6 +3668,12 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
|||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
|
||||
continue;
|
||||
|
||||
if (isFailedType)
|
||||
{
|
||||
// We don't want method decls from failed generic types to clog up our type system
|
||||
continue;
|
||||
}
|
||||
|
||||
// This should still be set to the default value
|
||||
BF_ASSERT(methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet);
|
||||
|
||||
|
@ -4014,7 +4032,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
|||
mCompiler->mHotState->mHasNewInterfaceTypes = true;
|
||||
}
|
||||
|
||||
if ((!typeInstance->IsInterface()) && (!typeInstance->IsUnspecializedTypeVariation()) && (!isBoxed))
|
||||
if ((!typeInstance->IsInterface()) && (!typeInstance->IsUnspecializedTypeVariation()) && (!isBoxed) && (!isFailedType))
|
||||
{
|
||||
if (!typeInstance->mTypeDef->mIsAbstract)
|
||||
{
|
||||
|
@ -4542,6 +4560,8 @@ BfUnknownSizedArrayType* BfModule::CreateUnknownSizedArrayType(BfType* resolvedT
|
|||
|
||||
BfPointerType* BfModule::CreatePointerType(BfType* resolvedType)
|
||||
{
|
||||
BF_ASSERT(!resolvedType->IsVar());
|
||||
|
||||
auto pointerType = mContext->mPointerTypePool.Get();
|
||||
pointerType->mContext = mContext;
|
||||
pointerType->mElementType = resolvedType;
|
||||
|
@ -6273,16 +6293,20 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
|
|||
}
|
||||
|
||||
if (resolvedTypeRef == NULL)
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
if (resolvedTypeRef->IsTuple())
|
||||
if (mCurTypeInstance == NULL)
|
||||
{
|
||||
// No deps
|
||||
}
|
||||
else if (resolvedTypeRef->IsTuple())
|
||||
{
|
||||
// Add the fields from the tuple as references since those inner fields types would have been explicitly stated, so we need
|
||||
// to make sure to record the current type instance as a referring type. This mostly matters for symbol renaming.
|
||||
BfTupleType* payloadTupleType = (BfTupleType*)resolvedTypeRef;
|
||||
for (auto& payloadFieldInst : payloadTupleType->mFieldInstances)
|
||||
{
|
||||
auto payloadFieldType = payloadFieldInst.mResolvedType;
|
||||
auto payloadFieldType = payloadFieldInst.mResolvedType;
|
||||
AddDependency(payloadFieldType, mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeReference);
|
||||
}
|
||||
}
|
||||
|
@ -7408,7 +7432,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
if (leftType == NULL)
|
||||
{
|
||||
BfAutoParentNodeEntry autoParentNodeEntry(this, qualifiedTypeRef);
|
||||
leftType = ResolveTypeRef(qualifiedTypeRef->mLeft, BfPopulateType_Declaration, BfResolveTypeRefFlag_IgnoreLookupError); // We throw an error below if we can't find the type
|
||||
leftType = ResolveTypeRef(qualifiedTypeRef->mLeft, BfPopulateType_Identity, (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_IgnoreLookupError)); // We throw an error below if we can't find the type
|
||||
}
|
||||
|
||||
if (leftType == NULL)
|
||||
|
@ -7582,6 +7606,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
}
|
||||
|
||||
BfResolvedTypeSet::LookupContext lookupCtx;
|
||||
lookupCtx.mResolveFlags = (BfResolveTypeRefFlags)(resolveFlags & BfResolveTypeRefFlag_NoCreate);
|
||||
lookupCtx.mRootTypeRef = typeRef;
|
||||
lookupCtx.mRootTypeDef = typeDef;
|
||||
lookupCtx.mModule = this;
|
||||
|
@ -7599,6 +7624,12 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
return ResolveTypeResult(typeRef, resolvedEntry->mValue, populateType, resolveFlags);
|
||||
}
|
||||
|
||||
if ((resolveFlags & BfResolveTypeRefFlag_NoCreate) != 0)
|
||||
{
|
||||
mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
|
||||
return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
|
||||
}
|
||||
|
||||
BfModule* populateModule = this;
|
||||
if ((resolveFlags & BfResolveTypeRefFlag_NoReify) != 0)
|
||||
populateModule = mContext->mUnreifiedModule;
|
||||
|
@ -9724,7 +9755,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
}
|
||||
|
||||
// Check type generic constraints
|
||||
if ((mCurTypeInstance->IsGenericTypeInstance()) && (mCurTypeInstance->IsUnspecializedType()))
|
||||
if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsGenericTypeInstance()) && (mCurTypeInstance->IsUnspecializedType()))
|
||||
{
|
||||
auto genericTypeInst = (BfGenericTypeInstance*)mCurTypeInstance;
|
||||
for (int genericParamIdx = 0; genericParamIdx < genericTypeInst->mGenericParams.size(); genericParamIdx++)
|
||||
|
|
|
@ -2335,7 +2335,7 @@ int BfResolvedTypeSet::DirectHash(BfTypeReference* typeRef, LookupContext* ctx,
|
|||
{
|
||||
bool isHeadType = typeRef == ctx->mRootTypeRef;
|
||||
|
||||
BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None;
|
||||
BfResolveTypeRefFlags resolveFlags = ctx->mResolveFlags;
|
||||
if ((flags & BfHashFlag_AllowGenericParamConstValue) != 0)
|
||||
resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_AllowGenericParamConstValue);
|
||||
|
||||
|
@ -2410,7 +2410,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
BfTypeVector genericArgs;
|
||||
for (auto genericArgTypeRef : genericInstTypeRef->mGenericArguments)
|
||||
{
|
||||
auto argType = ctx->mModule->ResolveTypeRef(genericArgTypeRef, BfPopulateType_Identity);
|
||||
auto argType = ctx->mModule->ResolveTypeRef(genericArgTypeRef, BfPopulateType_Identity, ctx->mResolveFlags);
|
||||
if (argType != NULL)
|
||||
genericArgs.Add(argType);
|
||||
else
|
||||
|
@ -2602,7 +2602,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
}
|
||||
else
|
||||
{
|
||||
ctx->mModule->ResolveTypeRef(typeRef); // To throw an error...
|
||||
ctx->mModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, ctx->mResolveFlags); // To throw an error...
|
||||
ctx->mFailed = true;
|
||||
return 0;
|
||||
//return Hash(refType->mElementType, ctx);
|
||||
|
@ -2635,7 +2635,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
}
|
||||
return Hash(rightType, ctx);*/
|
||||
|
||||
auto resolvedType = ctx->mModule->ResolveTypeRef(typeRef, BfPopulateType_Identity);
|
||||
auto resolvedType = ctx->mModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, ctx->mResolveFlags);
|
||||
if (resolvedType == NULL)
|
||||
{
|
||||
ctx->mFailed = true;
|
||||
|
@ -2663,7 +2663,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
// Only use the HAS_RETTYPE for root-level rettype insertions
|
||||
if (ctx->mRootTypeRef != retTypeTypeRef)
|
||||
{
|
||||
auto type = ctx->mModule->ResolveTypeRef(retTypeTypeRef);
|
||||
auto type = ctx->mModule->ResolveTypeRef(retTypeTypeRef, BfPopulateType_Identity, ctx->mResolveFlags);
|
||||
return Hash(type, ctx, flags);
|
||||
}
|
||||
|
||||
|
@ -2750,7 +2750,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
}
|
||||
else if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(typeRef))
|
||||
{
|
||||
ctx->mModule->ResolveTypeRef(dotTypeRef);
|
||||
ctx->mModule->ResolveTypeRef(dotTypeRef, BfPopulateType_Identity, ctx->mResolveFlags);
|
||||
ctx->mFailed = true;
|
||||
return 0;
|
||||
}
|
||||
|
@ -3016,7 +3016,7 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfGenericTypeInstance* lhsGenericType,
|
|||
if (lhsGenericType->mTypeDef != ctx->mModule->mContext->mCompiler->mNullableTypeDef)
|
||||
return false;
|
||||
|
||||
auto rhsElemType = ctx->mModule->ResolveTypeRef(rhsNullableTypeRef->mElementType, BfPopulateType_Identity);
|
||||
auto rhsElemType = ctx->mModule->ResolveTypeRef(rhsNullableTypeRef->mElementType, BfPopulateType_Identity, ctx->mResolveFlags);
|
||||
return lhsGenericType->mTypeGenericArguments[0] == rhsElemType;
|
||||
}
|
||||
}
|
||||
|
@ -3046,7 +3046,7 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfGenericTypeInstance* lhsGenericType,
|
|||
|
||||
if (auto rhsQualifiedTypeRef = BfNodeDynCastExact<BfQualifiedTypeReference>(rhs))
|
||||
{
|
||||
auto rhsRightType = ctx->mModule->ResolveTypeRef(rhs, BfPopulateType_Identity);
|
||||
auto rhsRightType = ctx->mModule->ResolveTypeRef(rhs, BfPopulateType_Identity, ctx->mResolveFlags);
|
||||
return rhsRightType == lhsGenericType;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,23 @@ class BfTypeInstance;
|
|||
class BfContext;
|
||||
class BfCustomAttributes;
|
||||
|
||||
enum BfResolveTypeRefFlags
|
||||
{
|
||||
BfResolveTypeRefFlag_None = 0,
|
||||
BfResolveTypeRefFlag_NoResolveGenericParam = 1,
|
||||
BfResolveTypeRefFlag_AllowRef = 2,
|
||||
BfResolveTypeRefFlag_AllowRefGeneric = 4,
|
||||
BfResolveTypeRefFlag_IgnoreLookupError = 8,
|
||||
BfResolveTypeRefFlag_AllowGenericTypeParamConstValue = 0x10,
|
||||
BfResolveTypeRefFlag_AllowGenericMethodParamConstValue = 0x20,
|
||||
BfResolveTypeRefFlag_AllowGenericParamConstValue = 0x10 | 0x20,
|
||||
BfResolveTypeRefFlag_AutoComplete = 0x40,
|
||||
BfResolveTypeRefFlag_FromIndirectSource = 0x80, // Such as a type alias or a generic parameter
|
||||
BfResolveTypeRefFlag_Attribute = 0x100,
|
||||
BfResolveTypeRefFlag_NoReify = 0x200,
|
||||
BfResolveTypeRefFlag_NoCreate = 0x400
|
||||
};
|
||||
|
||||
enum BfTypeNameFlags : uint16
|
||||
{
|
||||
BfTypeNameFlags_None = 0,
|
||||
|
@ -2348,16 +2365,18 @@ public:
|
|||
BfTypeReference* mRootTypeRef;
|
||||
BfTypeDef* mRootTypeDef;
|
||||
BfType* mResolvedType;
|
||||
BfResolveTypeRefFlags mResolveFlags;
|
||||
bool mFailed;
|
||||
|
||||
public:
|
||||
LookupContext()
|
||||
{
|
||||
{
|
||||
mRootTypeRef = NULL;
|
||||
mRootTypeDef = NULL;
|
||||
mModule = NULL;
|
||||
mResolvedType = NULL;
|
||||
mFailed = false;
|
||||
mResolveFlags = BfResolveTypeRefFlag_None;
|
||||
}
|
||||
|
||||
BfType* ResolveTypeRef(BfTypeReference* typeReference);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue