1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48:20 +02:00

Fixes for type dependencies and tests for type deletion bug

This commit is contained in:
Brian Fiete 2020-06-04 11:47:55 -07:00
parent 198acef1c6
commit 03fbc9d468
16 changed files with 309 additions and 55 deletions

View file

@ -0,0 +1,5 @@
FileVersion = 1
[Project]
Name = "Bug"
StartupObject = "Bug.Program"

View file

@ -0,0 +1,6 @@
FileVersion = 1
Projects = {Bug = {Path = "."}}
[Workspace]
StartupProject = "Bug"

View 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", "")

View 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);
}
}
}

View file

@ -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);

View file

@ -4417,6 +4417,7 @@ namespace IDE
if (!mInitialized)
return;
#if !CLI
if (setFocus)
mLastActivePanel = panel;
RecordHistoryLocation();
ShowTab(panel, label, false, setFocus);
@ -4580,7 +4581,7 @@ namespace IDE
[IDECommand]
public void ShowOutput()
{
ShowPanel(mOutputPanel, "Output");
ShowPanel(mOutputPanel, "Output", false);
}
[IDECommand]

View file

@ -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)
{

View file

@ -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
@ -2078,6 +2080,11 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork)
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;
}
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 ?");

View file

@ -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)
{
@ -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

View file

@ -317,6 +317,7 @@ public:
BfConstraintState* mCurConstraintState;
bool mResolvingVarField;
int mMappedObjectRevision;
bool mAssertOnPopulateType;
BfSystem* mSystem;
BfCompiler* mCompiler;

View file

@ -1370,8 +1370,8 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
if (checkMethod->mMethodType == BfMethodType_Extension)
{
argIdx--;
paramOfs++;
}
paramIdx += paramOfs;
for ( ; argIdx < (int)mArguments.size(); argIdx++)
{
@ -1846,6 +1846,7 @@ 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,8 +7156,7 @@ 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;
@ -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);
}

View file

@ -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);

View file

@ -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,

View file

@ -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;
@ -6275,7 +6295,11 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
if (resolvedTypeRef == 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.
@ -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++)

View file

@ -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;
}

View file

@ -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,6 +2365,7 @@ public:
BfTypeReference* mRootTypeRef;
BfTypeDef* mRootTypeDef;
BfType* mResolvedType;
BfResolveTypeRefFlags mResolveFlags;
bool mFailed;
public:
@ -2358,6 +2376,7 @@ public:
mModule = NULL;
mResolvedType = NULL;
mFailed = false;
mResolveFlags = BfResolveTypeRefFlag_None;
}
BfType* ResolveTypeRef(BfTypeReference* typeReference);