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]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern char8* BfCompiler_GetTypeDefInfo(void* bfCompiler, char8* typeDefName);
|
static extern char8* BfCompiler_GetTypeDefInfo(void* bfCompiler, char8* typeDefName);
|
||||||
|
|
||||||
|
[CallingConvention(.Stdcall), CLink]
|
||||||
|
static extern char8* BfCompiler_GetTypeInfo(void* bfCompiler, char8* typeName);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern void BfCompiler_SetOptions(void* bfCompiler,
|
static extern void BfCompiler_SetOptions(void* bfCompiler,
|
||||||
void* hotProject, int32 hotIdx, char8* targetTriple, int32 toolsetType, int32 simdSetting, int32 allocStackCount, int32 maxWorkerThreads,
|
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));
|
outStr.Append(BfCompiler_GetTypeDefInfo(mNativeBfCompiler, typeDefName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void GetTypeInfo(String typeDefName, String outStr)
|
||||||
|
{
|
||||||
|
outStr.Append(BfCompiler_GetTypeInfo(mNativeBfCompiler, typeDefName));
|
||||||
|
}
|
||||||
|
|
||||||
public void ClearBuildCache()
|
public void ClearBuildCache()
|
||||||
{
|
{
|
||||||
BfCompiler_ClearBuildCache(mNativeBfCompiler);
|
BfCompiler_ClearBuildCache(mNativeBfCompiler);
|
||||||
|
|
|
@ -4417,7 +4417,8 @@ namespace IDE
|
||||||
if (!mInitialized)
|
if (!mInitialized)
|
||||||
return;
|
return;
|
||||||
#if !CLI
|
#if !CLI
|
||||||
mLastActivePanel = panel;
|
if (setFocus)
|
||||||
|
mLastActivePanel = panel;
|
||||||
RecordHistoryLocation();
|
RecordHistoryLocation();
|
||||||
ShowTab(panel, label, false, setFocus);
|
ShowTab(panel, label, false, setFocus);
|
||||||
if (setFocus)
|
if (setFocus)
|
||||||
|
@ -4580,7 +4581,7 @@ namespace IDE
|
||||||
[IDECommand]
|
[IDECommand]
|
||||||
public void ShowOutput()
|
public void ShowOutput()
|
||||||
{
|
{
|
||||||
ShowPanel(mOutputPanel, "Output");
|
ShowPanel(mOutputPanel, "Output", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
[IDECommand]
|
[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]
|
[IDECommand]
|
||||||
public void AddWatch(String evalStr)
|
public void AddWatch(String evalStr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2052,6 +2052,8 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork)
|
||||||
if ((mResolvePassData != NULL) && (mResolvePassData->mParser != NULL))
|
if ((mResolvePassData != NULL) && (mResolvePassData->mParser != NULL))
|
||||||
madeFullPass = false;
|
madeFullPass = false;
|
||||||
|
|
||||||
|
SetAndRestoreValue<bool> prevAssertOnPopulateType(mContext->mAssertOnPopulateType, deleteUnusued && madeFullPass);
|
||||||
|
|
||||||
if ((deleteUnusued) && (madeFullPass))
|
if ((deleteUnusued) && (madeFullPass))
|
||||||
{
|
{
|
||||||
// Work queues should be empty if we're not canceling
|
// 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();
|
auto typeInst = type->ToTypeInstance();
|
||||||
|
|
||||||
if (depType != NULL)
|
if (depType != NULL)
|
||||||
{
|
{
|
||||||
|
if ((depType->mTypeId == 2574) && (!mIsResolveOnly) && (deleteUnusued))
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
|
||||||
extern BfModule* gLastCreatedModule;
|
extern BfModule* gLastCreatedModule;
|
||||||
|
|
||||||
for (auto itr = depType->mDependencyMap.begin(); itr != depType->mDependencyMap.end(); ++itr)
|
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) &&
|
if ((depTypeInst != NULL) && (typeInst->mLastNonGenericUsedRevision != mRevision) && (isDependentUsage) &&
|
||||||
((isDirectReference) || (dependentType->IsUnspecializedType()) || (depTypeInst->mLastNonGenericUsedRevision == mRevision)))
|
((isDirectReference) || (dependentType->IsUnspecializedType()) || (depTypeInst->mLastNonGenericUsedRevision == mRevision)))
|
||||||
{
|
{
|
||||||
//if (deleteUnusued)
|
typeInst->mLastNonGenericUsedRevision = mRevision;
|
||||||
{
|
foundNew = true;
|
||||||
typeInst->mLastNonGenericUsedRevision = mRevision;
|
|
||||||
foundNew = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!typeInst->HasBeenReferenced())
|
if (!typeInst->HasBeenReferenced())
|
||||||
{
|
{
|
||||||
|
@ -8250,6 +8254,92 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetTypeDefInfo(BfCompiler* bfCompil
|
||||||
return outString.c_str();
|
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_EXPORT const char* BF_CALLTYPE BfCompiler_GetOutputFileNames(BfCompiler* bfCompiler, BfProject* bfProject, bool* hadOutputChanges)
|
||||||
{
|
{
|
||||||
BF_FATAL("not used ?");
|
BF_FATAL("not used ?");
|
||||||
|
|
|
@ -48,6 +48,7 @@ BfContext::BfContext(BfCompiler* compiler) :
|
||||||
mCurTypeState = NULL;
|
mCurTypeState = NULL;
|
||||||
mCurConstraintState = NULL;
|
mCurConstraintState = NULL;
|
||||||
mResolvingVarField = false;
|
mResolvingVarField = false;
|
||||||
|
mAssertOnPopulateType = false;
|
||||||
|
|
||||||
for (int i = 0; i < BfTypeCode_Length; i++)
|
for (int i = 0; i < BfTypeCode_Length; i++)
|
||||||
{
|
{
|
||||||
|
@ -762,6 +763,8 @@ BfType * BfContext::FindTypeById(int typeId)
|
||||||
|
|
||||||
void BfContext::AddTypeToWorkList(BfType* type)
|
void BfContext::AddTypeToWorkList(BfType* type)
|
||||||
{
|
{
|
||||||
|
BF_ASSERT(!mAssertOnPopulateType);
|
||||||
|
|
||||||
BF_ASSERT((type->mRebuildFlags & BfTypeRebuildFlag_InTempPool) == 0);
|
BF_ASSERT((type->mRebuildFlags & BfTypeRebuildFlag_InTempPool) == 0);
|
||||||
if ((type->mRebuildFlags & BfTypeRebuildFlag_AddedToWorkList) == 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);
|
type->mRebuildFlags = (BfTypeRebuildFlags)((type->mRebuildFlags | BfTypeRebuildFlag_Deleted) & ~BfTypeRebuildFlag_DeleteQueued);
|
||||||
SaveDeletingType(type);
|
SaveDeletingType(type);
|
||||||
|
|
||||||
|
@ -1530,6 +1533,19 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds)
|
||||||
if ((dependencyEntry.mFlags & ~(BfDependencyMap::DependencyFlag_UnspecializedType | BfDependencyMap::DependencyFlag_WeakReference)) == 0)
|
if ((dependencyEntry.mFlags & ~(BfDependencyMap::DependencyFlag_UnspecializedType | BfDependencyMap::DependencyFlag_WeakReference)) == 0)
|
||||||
continue; // Not a cause for rebuilding
|
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))
|
if ((deferDepRebuilds) && (dependentTypeInst != NULL))
|
||||||
mFailTypes.Add(dependentTypeInst);
|
mFailTypes.Add(dependentTypeInst);
|
||||||
else
|
else
|
||||||
|
|
|
@ -317,6 +317,7 @@ public:
|
||||||
BfConstraintState* mCurConstraintState;
|
BfConstraintState* mCurConstraintState;
|
||||||
bool mResolvingVarField;
|
bool mResolvingVarField;
|
||||||
int mMappedObjectRevision;
|
int mMappedObjectRevision;
|
||||||
|
bool mAssertOnPopulateType;
|
||||||
|
|
||||||
BfSystem* mSystem;
|
BfSystem* mSystem;
|
||||||
BfCompiler* mCompiler;
|
BfCompiler* mCompiler;
|
||||||
|
|
|
@ -1369,9 +1369,9 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
||||||
|
|
||||||
if (checkMethod->mMethodType == BfMethodType_Extension)
|
if (checkMethod->mMethodType == BfMethodType_Extension)
|
||||||
{
|
{
|
||||||
argIdx--;
|
argIdx--;
|
||||||
paramOfs++;
|
|
||||||
}
|
}
|
||||||
|
paramIdx += paramOfs;
|
||||||
|
|
||||||
for ( ; argIdx < (int)mArguments.size(); argIdx++)
|
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?
|
// This method checks all base classes before checking interfaces. Is that correct?
|
||||||
bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue target, bool isFailurePass, bool forceOuterCheck)
|
bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue target, bool isFailurePass, bool forceOuterCheck)
|
||||||
{
|
{
|
||||||
|
BfMethodDef* prevBesstMethodDef = mBestMethodDef;
|
||||||
auto curTypeInst = typeInstance;
|
auto curTypeInst = typeInstance;
|
||||||
auto curTypeDef = typeInstance->mTypeDef;
|
auto curTypeDef = typeInstance->mTypeDef;
|
||||||
|
|
||||||
|
@ -2041,7 +2042,7 @@ bool BfMethodMatcher::CheckType(BfTypeInstance* typeInstance, BfTypedValue targe
|
||||||
if (mAutoFlushAmbiguityErrors)
|
if (mAutoFlushAmbiguityErrors)
|
||||||
FlushAmbiguityError();
|
FlushAmbiguityError();
|
||||||
|
|
||||||
return mBestMethodDef != NULL;
|
return mBestMethodDef != prevBesstMethodDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* origTarget, BfTypedValue* staticResult)
|
void BfMethodMatcher::TryDevirtualizeCall(BfTypedValue target, BfTypedValue* origTarget, BfTypedValue* staticResult)
|
||||||
|
@ -7155,9 +7156,8 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
{
|
{
|
||||||
auto checkTypeInst = mModule->mCurTypeInstance;
|
auto checkTypeInst = mModule->mCurTypeInstance;
|
||||||
methodMatcher.mMethodType = BfMethodType_Extension;
|
methodMatcher.mMethodType = BfMethodType_Extension;
|
||||||
methodMatcher.CheckType(checkTypeInst, BfTypedValue(), false, true);
|
if (methodMatcher.CheckType(checkTypeInst, BfTypedValue(), false, true))
|
||||||
if (methodMatcher.mBestMethodDef != NULL)
|
{
|
||||||
{
|
|
||||||
isFailurePass = false;
|
isFailurePass = false;
|
||||||
curTypeInst = methodMatcher.mBestMethodTypeInstance;
|
curTypeInst = methodMatcher.mBestMethodTypeInstance;
|
||||||
methodDef = methodMatcher.mBestMethodDef;
|
methodDef = methodMatcher.mBestMethodDef;
|
||||||
|
@ -7178,9 +7178,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
if (globalContainer.mTypeInst == NULL)
|
if (globalContainer.mTypeInst == NULL)
|
||||||
continue;
|
continue;
|
||||||
methodMatcher.mMethodType = wantsExtensionCheck ? BfMethodType_Extension : BfMethodType_Normal;
|
methodMatcher.mMethodType = wantsExtensionCheck ? BfMethodType_Extension : BfMethodType_Normal;
|
||||||
methodMatcher.CheckType(globalContainer.mTypeInst, BfTypedValue(), false);
|
if (methodMatcher.CheckType(globalContainer.mTypeInst, BfTypedValue(), false))
|
||||||
|
|
||||||
if (methodMatcher.mBestMethodDef != NULL)
|
|
||||||
{
|
{
|
||||||
isFailurePass = false;
|
isFailurePass = false;
|
||||||
curTypeInst = methodMatcher.mBestMethodTypeInstance;
|
curTypeInst = methodMatcher.mBestMethodTypeInstance;
|
||||||
|
@ -7202,8 +7200,7 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
||||||
for (auto typeInst : staticSearch->mStaticTypes)
|
for (auto typeInst : staticSearch->mStaticTypes)
|
||||||
{
|
{
|
||||||
methodMatcher.mMethodType = wantsExtensionCheck ? BfMethodType_Extension : BfMethodType_Normal;
|
methodMatcher.mMethodType = wantsExtensionCheck ? BfMethodType_Extension : BfMethodType_Normal;
|
||||||
methodMatcher.CheckType(typeInst, BfTypedValue(), false);
|
if (methodMatcher.CheckType(typeInst, BfTypedValue(), false))
|
||||||
if (methodMatcher.mBestMethodDef != NULL)
|
|
||||||
{
|
{
|
||||||
isFailurePass = false;
|
isFailurePass = false;
|
||||||
curTypeInst = methodMatcher.mBestMethodTypeInstance;
|
curTypeInst = methodMatcher.mBestMethodTypeInstance;
|
||||||
|
@ -11995,7 +11992,11 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((!resolvedTypeRef->IsObjectOrInterface()) && (!resolvedTypeRef->IsGenericParam()))
|
if (resolvedTypeRef->IsVar())
|
||||||
|
{
|
||||||
|
// Leave as a var
|
||||||
|
}
|
||||||
|
else if ((!resolvedTypeRef->IsObjectOrInterface()) && (!resolvedTypeRef->IsGenericParam()))
|
||||||
{
|
{
|
||||||
resultType = mModule->CreatePointerType(resolvedTypeRef);
|
resultType = mModule->CreatePointerType(resolvedTypeRef);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2991,6 +2991,16 @@ void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap
|
||||||
if (usedType->IsSpecializedByAutoCompleteMethod())
|
if (usedType->IsSpecializedByAutoCompleteMethod())
|
||||||
return;
|
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;
|
BfType* origUsedType = usedType;
|
||||||
bool isDataAccess = ((flags & (BfDependencyMap::DependencyFlag_ReadFields | BfDependencyMap::DependencyFlag_LocalUsage | BfDependencyMap::DependencyFlag_Allocates)) != 0);
|
bool isDataAccess = ((flags & (BfDependencyMap::DependencyFlag_ReadFields | BfDependencyMap::DependencyFlag_LocalUsage | BfDependencyMap::DependencyFlag_Allocates)) != 0);
|
||||||
if (isDataAccess)
|
if (isDataAccess)
|
||||||
|
@ -18581,6 +18591,7 @@ BfModuleMethodInstance BfModule::GetLocalMethodInstance(BfLocalMethod* localMeth
|
||||||
|
|
||||||
BF_ASSERT(methodInstance->mMethodInfoEx != NULL);
|
BF_ASSERT(methodInstance->mMethodInfoEx != NULL);
|
||||||
methodState.mGenericTypeBindings = &methodInstance->mMethodInfoEx->mGenericTypeBindings;
|
methodState.mGenericTypeBindings = &methodInstance->mMethodInfoEx->mGenericTypeBindings;
|
||||||
|
methodState.mMethodInstance = methodInstance;
|
||||||
|
|
||||||
NewScopeState();
|
NewScopeState();
|
||||||
ProcessMethod_SetupParams(methodInstance, NULL, false, NULL);
|
ProcessMethod_SetupParams(methodInstance, NULL, false, NULL);
|
||||||
|
|
|
@ -1268,22 +1268,6 @@ public:
|
||||||
String mName;
|
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
|
enum BfSrcPosFlags
|
||||||
{
|
{
|
||||||
BfSrcPosFlag_None = 0,
|
BfSrcPosFlag_None = 0,
|
||||||
|
|
|
@ -881,6 +881,11 @@ bool BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
|
||||||
else
|
else
|
||||||
resolvedTypeRef->mTypeId = mCompiler->mCurTypeId++;
|
resolvedTypeRef->mTypeId = mCompiler->mCurTypeId++;
|
||||||
|
|
||||||
|
if ((resolvedTypeRef->mTypeId == 2599) && (!mCompiler->mIsResolveOnly))
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
|
||||||
while (resolvedTypeRef->mTypeId >= (int)mContext->mTypes.size())
|
while (resolvedTypeRef->mTypeId >= (int)mContext->mTypes.size())
|
||||||
mContext->mTypes.Add(NULL);
|
mContext->mTypes.Add(NULL);
|
||||||
mContext->mTypes[resolvedTypeRef->mTypeId] = resolvedTypeRef;
|
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
|
// Generate all methods. Pass 1
|
||||||
for (auto methodDef : typeDef->mMethods)
|
for (auto methodDef : typeDef->mMethods)
|
||||||
{
|
{
|
||||||
|
@ -3656,6 +3668,12 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
|
if (methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude)
|
||||||
continue;
|
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
|
// This should still be set to the default value
|
||||||
BF_ASSERT(methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet);
|
BF_ASSERT(methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_NotSet);
|
||||||
|
|
||||||
|
@ -4014,7 +4032,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
mCompiler->mHotState->mHasNewInterfaceTypes = true;
|
mCompiler->mHotState->mHasNewInterfaceTypes = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!typeInstance->IsInterface()) && (!typeInstance->IsUnspecializedTypeVariation()) && (!isBoxed))
|
if ((!typeInstance->IsInterface()) && (!typeInstance->IsUnspecializedTypeVariation()) && (!isBoxed) && (!isFailedType))
|
||||||
{
|
{
|
||||||
if (!typeInstance->mTypeDef->mIsAbstract)
|
if (!typeInstance->mTypeDef->mIsAbstract)
|
||||||
{
|
{
|
||||||
|
@ -4542,6 +4560,8 @@ BfUnknownSizedArrayType* BfModule::CreateUnknownSizedArrayType(BfType* resolvedT
|
||||||
|
|
||||||
BfPointerType* BfModule::CreatePointerType(BfType* resolvedType)
|
BfPointerType* BfModule::CreatePointerType(BfType* resolvedType)
|
||||||
{
|
{
|
||||||
|
BF_ASSERT(!resolvedType->IsVar());
|
||||||
|
|
||||||
auto pointerType = mContext->mPointerTypePool.Get();
|
auto pointerType = mContext->mPointerTypePool.Get();
|
||||||
pointerType->mContext = mContext;
|
pointerType->mContext = mContext;
|
||||||
pointerType->mElementType = resolvedType;
|
pointerType->mElementType = resolvedType;
|
||||||
|
@ -6273,16 +6293,20 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolvedTypeRef == NULL)
|
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
|
// 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.
|
// to make sure to record the current type instance as a referring type. This mostly matters for symbol renaming.
|
||||||
BfTupleType* payloadTupleType = (BfTupleType*)resolvedTypeRef;
|
BfTupleType* payloadTupleType = (BfTupleType*)resolvedTypeRef;
|
||||||
for (auto& payloadFieldInst : payloadTupleType->mFieldInstances)
|
for (auto& payloadFieldInst : payloadTupleType->mFieldInstances)
|
||||||
{
|
{
|
||||||
auto payloadFieldType = payloadFieldInst.mResolvedType;
|
auto payloadFieldType = payloadFieldInst.mResolvedType;
|
||||||
AddDependency(payloadFieldType, mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeReference);
|
AddDependency(payloadFieldType, mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeReference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7408,7 +7432,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
if (leftType == NULL)
|
if (leftType == NULL)
|
||||||
{
|
{
|
||||||
BfAutoParentNodeEntry autoParentNodeEntry(this, qualifiedTypeRef);
|
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)
|
if (leftType == NULL)
|
||||||
|
@ -7582,6 +7606,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
}
|
}
|
||||||
|
|
||||||
BfResolvedTypeSet::LookupContext lookupCtx;
|
BfResolvedTypeSet::LookupContext lookupCtx;
|
||||||
|
lookupCtx.mResolveFlags = (BfResolveTypeRefFlags)(resolveFlags & BfResolveTypeRefFlag_NoCreate);
|
||||||
lookupCtx.mRootTypeRef = typeRef;
|
lookupCtx.mRootTypeRef = typeRef;
|
||||||
lookupCtx.mRootTypeDef = typeDef;
|
lookupCtx.mRootTypeDef = typeDef;
|
||||||
lookupCtx.mModule = this;
|
lookupCtx.mModule = this;
|
||||||
|
@ -7599,6 +7624,12 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
return ResolveTypeResult(typeRef, resolvedEntry->mValue, populateType, resolveFlags);
|
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;
|
BfModule* populateModule = this;
|
||||||
if ((resolveFlags & BfResolveTypeRefFlag_NoReify) != 0)
|
if ((resolveFlags & BfResolveTypeRefFlag_NoReify) != 0)
|
||||||
populateModule = mContext->mUnreifiedModule;
|
populateModule = mContext->mUnreifiedModule;
|
||||||
|
@ -9724,7 +9755,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check type generic constraints
|
// Check type generic constraints
|
||||||
if ((mCurTypeInstance->IsGenericTypeInstance()) && (mCurTypeInstance->IsUnspecializedType()))
|
if ((mCurTypeInstance != NULL) && (mCurTypeInstance->IsGenericTypeInstance()) && (mCurTypeInstance->IsUnspecializedType()))
|
||||||
{
|
{
|
||||||
auto genericTypeInst = (BfGenericTypeInstance*)mCurTypeInstance;
|
auto genericTypeInst = (BfGenericTypeInstance*)mCurTypeInstance;
|
||||||
for (int genericParamIdx = 0; genericParamIdx < genericTypeInst->mGenericParams.size(); genericParamIdx++)
|
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;
|
bool isHeadType = typeRef == ctx->mRootTypeRef;
|
||||||
|
|
||||||
BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None;
|
BfResolveTypeRefFlags resolveFlags = ctx->mResolveFlags;
|
||||||
if ((flags & BfHashFlag_AllowGenericParamConstValue) != 0)
|
if ((flags & BfHashFlag_AllowGenericParamConstValue) != 0)
|
||||||
resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_AllowGenericParamConstValue);
|
resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_AllowGenericParamConstValue);
|
||||||
|
|
||||||
|
@ -2410,7 +2410,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
||||||
BfTypeVector genericArgs;
|
BfTypeVector genericArgs;
|
||||||
for (auto genericArgTypeRef : genericInstTypeRef->mGenericArguments)
|
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)
|
if (argType != NULL)
|
||||||
genericArgs.Add(argType);
|
genericArgs.Add(argType);
|
||||||
else
|
else
|
||||||
|
@ -2602,7 +2602,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ctx->mModule->ResolveTypeRef(typeRef); // To throw an error...
|
ctx->mModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, ctx->mResolveFlags); // To throw an error...
|
||||||
ctx->mFailed = true;
|
ctx->mFailed = true;
|
||||||
return 0;
|
return 0;
|
||||||
//return Hash(refType->mElementType, ctx);
|
//return Hash(refType->mElementType, ctx);
|
||||||
|
@ -2635,7 +2635,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
||||||
}
|
}
|
||||||
return Hash(rightType, ctx);*/
|
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)
|
if (resolvedType == NULL)
|
||||||
{
|
{
|
||||||
ctx->mFailed = true;
|
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
|
// Only use the HAS_RETTYPE for root-level rettype insertions
|
||||||
if (ctx->mRootTypeRef != retTypeTypeRef)
|
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);
|
return Hash(type, ctx, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2750,7 +2750,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
||||||
}
|
}
|
||||||
else if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(typeRef))
|
else if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(typeRef))
|
||||||
{
|
{
|
||||||
ctx->mModule->ResolveTypeRef(dotTypeRef);
|
ctx->mModule->ResolveTypeRef(dotTypeRef, BfPopulateType_Identity, ctx->mResolveFlags);
|
||||||
ctx->mFailed = true;
|
ctx->mFailed = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3016,7 +3016,7 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfGenericTypeInstance* lhsGenericType,
|
||||||
if (lhsGenericType->mTypeDef != ctx->mModule->mContext->mCompiler->mNullableTypeDef)
|
if (lhsGenericType->mTypeDef != ctx->mModule->mContext->mCompiler->mNullableTypeDef)
|
||||||
return false;
|
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;
|
return lhsGenericType->mTypeGenericArguments[0] == rhsElemType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3046,7 +3046,7 @@ bool BfResolvedTypeSet::GenericTypeEquals(BfGenericTypeInstance* lhsGenericType,
|
||||||
|
|
||||||
if (auto rhsQualifiedTypeRef = BfNodeDynCastExact<BfQualifiedTypeReference>(rhs))
|
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;
|
return rhsRightType == lhsGenericType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,23 @@ class BfTypeInstance;
|
||||||
class BfContext;
|
class BfContext;
|
||||||
class BfCustomAttributes;
|
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
|
enum BfTypeNameFlags : uint16
|
||||||
{
|
{
|
||||||
BfTypeNameFlags_None = 0,
|
BfTypeNameFlags_None = 0,
|
||||||
|
@ -2348,16 +2365,18 @@ public:
|
||||||
BfTypeReference* mRootTypeRef;
|
BfTypeReference* mRootTypeRef;
|
||||||
BfTypeDef* mRootTypeDef;
|
BfTypeDef* mRootTypeDef;
|
||||||
BfType* mResolvedType;
|
BfType* mResolvedType;
|
||||||
|
BfResolveTypeRefFlags mResolveFlags;
|
||||||
bool mFailed;
|
bool mFailed;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LookupContext()
|
LookupContext()
|
||||||
{
|
{
|
||||||
mRootTypeRef = NULL;
|
mRootTypeRef = NULL;
|
||||||
mRootTypeDef = NULL;
|
mRootTypeDef = NULL;
|
||||||
mModule = NULL;
|
mModule = NULL;
|
||||||
mResolvedType = NULL;
|
mResolvedType = NULL;
|
||||||
mFailed = false;
|
mFailed = false;
|
||||||
|
mResolveFlags = BfResolveTypeRefFlag_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfType* ResolveTypeRef(BfTypeReference* typeReference);
|
BfType* ResolveTypeRef(BfTypeReference* typeReference);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue