From 7b9c994066412b6a270fe72090372cd2ba42ec13 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Thu, 13 Feb 2020 07:55:50 -0800 Subject: [PATCH] Fixed bugs related to generic delegate type references --- IDEHelper/Compiler/BfCompiler.h | 1 + IDEHelper/Compiler/BfContext.h | 1 + IDEHelper/Compiler/BfExprEvaluator.cpp | 88 ++++++++++---- IDEHelper/Compiler/BfExprEvaluator.h | 2 +- IDEHelper/Compiler/BfModule.cpp | 17 ++- IDEHelper/Compiler/BfModule.h | 10 +- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 126 ++++++++++++++++++++- IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 57 +++++----- 8 files changed, 240 insertions(+), 62 deletions(-) diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index 896426df..ae6c29f2 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -443,6 +443,7 @@ public: bool IsSkippingExtraResolveChecks(); int GetVTableMethodOffset(); BfType* CheckSymbolReferenceTypeRef(BfModule* module, BfTypeReference* typeRef); + void AddToRebuildTypeList(BfTypeInstance* typeInst, HashSet& rebuildTypeInstList); void AddDepsToRebuildTypeList(BfTypeInstance* typeInst, HashSet& rebuildTypeInstList); void CompileReified(); void PopulateReified(); diff --git a/IDEHelper/Compiler/BfContext.h b/IDEHelper/Compiler/BfContext.h index a4a51984..676b47f2 100644 --- a/IDEHelper/Compiler/BfContext.h +++ b/IDEHelper/Compiler/BfContext.h @@ -372,6 +372,7 @@ public: BfAllocPool mGenericTypeRefPool; BfAllocPool mConcreteInterfaceTypePool; BfAllocPool mConstExprValueTypePool; + BfAllocPool mDelegateTypePool; BfPrimitiveType* mPrimitiveTypes[BfTypeCode_Length]; BfPrimitiveType* mPrimitiveStructTypes[BfTypeCode_Length]; diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index b89ea446..78b184ed 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -210,13 +210,25 @@ bool BfMethodMatcher::IsMemberAccessible(BfTypeInstance* typeInst, BfTypeDef* de return true; } -bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue) +bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue, HashSet& checkedTypeSet) { if (argType == NULL) return false; if (argType->IsVar()) return false; + if (!wantType->IsUnspecializedType()) + return true; + + bool alreadyChecked = false; + auto _AddToCheckedSet = [](BfType* type, HashSet& checkedTypeSet, bool& alreadyChecked) + { + if (alreadyChecked) + return true; + alreadyChecked = true; + return checkedTypeSet.Add(type); + }; + if (wantType->IsGenericParam()) { auto wantGenericParam = (BfGenericParamType*)wantType; @@ -226,6 +238,13 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT { BF_ASSERT((argType == NULL) || (!argType->IsVar())); + if (argType != NULL) + { + // Disallow illegal types + if (argType->IsRef()) + return; + } + if (mCheckMethodGenericArguments[wantGenericParam->mGenericParamIdx] != argType) { if (methodGenericTypeConstraint != NULL) @@ -243,7 +262,7 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT if (argGenericType->mTypeDef == wantGenericType->mTypeDef) { for (int genericArgIdx = 0; genericArgIdx < (int)argGenericType->mTypeGenericArguments.size(); genericArgIdx++) - InferGenericArgument(methodInstance, argGenericType->mTypeGenericArguments[genericArgIdx], wantGenericType->mTypeGenericArguments[genericArgIdx], BfIRValue()); + InferGenericArgument(methodInstance, argGenericType->mTypeGenericArguments[genericArgIdx], wantGenericType->mTypeGenericArguments[genericArgIdx], BfIRValue(), checkedTypeSet); } } else if (checkArgType->IsSizedArray()) @@ -251,10 +270,10 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT auto sizedArrayType = (BfSizedArrayType*)checkArgType; if (wantGenericType->mTypeDef == mModule->mCompiler->mSizedArrayTypeDef) { - InferGenericArgument(methodInstance, sizedArrayType->mElementType, wantGenericType->mTypeGenericArguments[0], BfIRValue()); + InferGenericArgument(methodInstance, sizedArrayType->mElementType, wantGenericType->mTypeGenericArguments[0], BfIRValue(), checkedTypeSet); auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr); BfTypedValue arraySize = BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, (uint64)sizedArrayType->mElementCount), intType); - InferGenericArgument(methodInstance, mModule->CreateConstExprValueType(arraySize), wantGenericType->mTypeGenericArguments[1], BfIRValue()); + InferGenericArgument(methodInstance, mModule->CreateConstExprValueType(arraySize), wantGenericType->mTypeGenericArguments[1], BfIRValue(), checkedTypeSet); } } else if (checkArgType->IsPointer()) @@ -262,7 +281,7 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT auto pointerType = (BfPointerType*)checkArgType; if (wantGenericType->mTypeDef == mModule->mCompiler->mPointerTTypeDef) { - InferGenericArgument(methodInstance, pointerType->mElementType, wantGenericType->mTypeGenericArguments[0], BfIRValue()); + InferGenericArgument(methodInstance, pointerType->mElementType, wantGenericType->mTypeGenericArguments[0], BfIRValue(), checkedTypeSet); } } @@ -359,7 +378,7 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT return true; } - if (wantType->IsGenericTypeInstance()) + if ((wantType->IsGenericTypeInstance()) && (wantType->IsUnspecializedTypeVariation())) { auto wantGenericType = (BfGenericTypeInstance*)wantType; if (!argType->IsGenericTypeInstance()) @@ -367,9 +386,16 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT auto argGenericType = (BfGenericTypeInstance*)argType; if (argGenericType->mTypeDef != wantGenericType->mTypeDef) return true; - + for (int genericArgIdx = 0; genericArgIdx < (int)argGenericType->mTypeGenericArguments.size(); genericArgIdx++) - InferGenericArgument(methodInstance, argGenericType->mTypeGenericArguments[genericArgIdx], wantGenericType->mTypeGenericArguments[genericArgIdx], BfIRValue()); + { + BfType* wantGenericArgument = wantGenericType->mTypeGenericArguments[genericArgIdx]; + if (!wantGenericArgument->IsUnspecializedType()) + continue; + if (!_AddToCheckedSet(argType, checkedTypeSet, alreadyChecked)) + return true; + InferGenericArgument(methodInstance, argGenericType->mTypeGenericArguments[genericArgIdx], wantGenericArgument, BfIRValue(), checkedTypeSet); + } return true; } @@ -379,14 +405,14 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT if (!argType->IsRef()) { // Match to non-ref - InferGenericArgument(methodInstance, argType, wantRefType->mElementType, BfIRValue()); + InferGenericArgument(methodInstance, argType, wantRefType->mElementType, BfIRValue(), checkedTypeSet); return true; } auto argRefType = (BfRefType*)argType; //TODO: We removed this check so we still infer even if we have the wrong ref kind //if (wantRefType->mRefKind != argRefType->mRefKind) //return true; - InferGenericArgument(methodInstance, argRefType->mElementType, wantRefType->mElementType, BfIRValue()); + InferGenericArgument(methodInstance, argRefType->mElementType, wantRefType->mElementType, BfIRValue(), checkedTypeSet); return true; } @@ -396,7 +422,7 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT return true; auto wantPointerType = (BfPointerType*) wantType; auto argPointerType = (BfPointerType*) argType; - InferGenericArgument(methodInstance, argPointerType->mElementType, wantPointerType->mElementType, BfIRValue()); + InferGenericArgument(methodInstance, argPointerType->mElementType, wantPointerType->mElementType, BfIRValue(), checkedTypeSet); return true; } @@ -406,14 +432,14 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT if (argType->IsUnknownSizedArray()) { auto argArrayType = (BfUnknownSizedArrayType*)argType; - InferGenericArgument(methodInstance, argArrayType->mElementCountSource, wantArrayType->mElementCountSource, BfIRValue()); + InferGenericArgument(methodInstance, argArrayType->mElementCountSource, wantArrayType->mElementCountSource, BfIRValue(), checkedTypeSet); } else if (argType->IsSizedArray()) { auto argArrayType = (BfSizedArrayType*)argType; BfTypedValue sizeValue(mModule->GetConstValue(argArrayType->mElementCount), mModule->GetPrimitiveType(BfTypeCode_IntPtr)); auto sizedType = mModule->CreateConstExprValueType(sizeValue); - InferGenericArgument(methodInstance, sizedType, wantArrayType->mElementCountSource, BfIRValue()); + InferGenericArgument(methodInstance, sizedType, wantArrayType->mElementCountSource, BfIRValue(), checkedTypeSet); } } @@ -423,7 +449,27 @@ bool BfMethodMatcher::InferGenericArgument(BfMethodInstance* methodInstance, BfT { auto wantArrayType = (BfSizedArrayType*)wantType; auto argArrayType = (BfSizedArrayType*)argType; - InferGenericArgument(methodInstance, argArrayType->mElementType, wantArrayType->mElementType, BfIRValue()); + InferGenericArgument(methodInstance, argArrayType->mElementType, wantArrayType->mElementType, BfIRValue(), checkedTypeSet); + } + } + + if ((wantType->IsDelegate()) || (wantType->IsFunction())) + { + if (((argType->IsDelegate()) || (argType->IsFunction())) && + (wantType->IsDelegate() == argType->IsDelegate())) + { + if (!_AddToCheckedSet(argType, checkedTypeSet, alreadyChecked)) + return true; + + auto argInvokeMethod = mModule->GetRawMethodByName(argType->ToTypeInstance(), "Invoke"); + auto wantInvokeMethod = mModule->GetRawMethodByName(wantType->ToTypeInstance(), "Invoke"); + + if (argInvokeMethod->GetParamCount() == wantInvokeMethod->GetParamCount()) + { + InferGenericArgument(methodInstance, argInvokeMethod->mReturnType, wantInvokeMethod->mReturnType, BfIRValue(), checkedTypeSet); + for (int argIdx = 0; argIdx < (int)argInvokeMethod->GetParamCount(); argIdx++) + InferGenericArgument(methodInstance, argInvokeMethod->GetParamType(argIdx), wantInvokeMethod->GetParamType(argIdx), BfIRValue(), checkedTypeSet); + } } } @@ -810,7 +856,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp } BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, BfType* checkType, BfTypeVector* genericArgumentsSubstitute) -{ +{ BfTypedValue argTypedValue = resolvedArg.mTypedValue; if ((resolvedArg.mArgFlags & BfArgFlag_DelegateBindAttempt) != 0) { @@ -831,8 +877,7 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B argTypedValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), methodRefType); } else - argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue); - //argTypedValue = BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), checkType); + argTypedValue = BfTypedValue(BfTypedValueKind_UntypedValue); } } else if ((resolvedArg.mArgFlags & BfArgFlag_LambdaBindAttempt) != 0) @@ -911,7 +956,7 @@ BfTypedValue BfMethodMatcher::ResolveArgTypedValue(BfResolvedArg& resolvedArg, B expectType = refType->mElementType; } - if (genericArgumentsSubstitute != NULL) + if ((genericArgumentsSubstitute != NULL) && (expectType->IsUnspecializedType())) expectType = mModule->ResolveGenericType(expectType, *genericArgumentsSubstitute, true); } @@ -1238,7 +1283,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* typeInstance, BfMethodDef* che checkType = genericParamInstance->mTypeConstraint; } - if ((checkType != NULL) && (genericArgumentsSubstitute != NULL) && (checkType->IsUnspecializedTypeVariation())) + if ((checkType != NULL) && (genericArgumentsSubstitute != NULL) && (checkType->IsUnspecializedType())) { checkType = mModule->ResolveGenericType(origCheckType, *genericArgumentsSubstitute); } @@ -1249,7 +1294,10 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* typeInstance, BfMethodDef* che if (!argTypedValue.IsUntypedValue()) { auto type = argTypedValue.mType; - if ((!argTypedValue) || (!InferGenericArgument(methodInstance, type, wantType, argTypedValue.mValue))) + if (!argTypedValue) + goto NoMatch; + HashSet checkedTypeSet; + if (!InferGenericArgument(methodInstance, type, wantType, argTypedValue.mValue, checkedTypeSet)) goto NoMatch; } } diff --git a/IDEHelper/Compiler/BfExprEvaluator.h b/IDEHelper/Compiler/BfExprEvaluator.h index 56e52f2a..70edc6a9 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.h +++ b/IDEHelper/Compiler/BfExprEvaluator.h @@ -155,7 +155,7 @@ public: public: BfTypedValue ResolveArgTypedValue(BfResolvedArg& resolvedArg, BfType* checkType, BfTypeVector* genericArgumentsSubstitute); - bool InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue); + bool InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue, HashSet& checkedTypeSet); bool InferFromGenericConstraints(BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs); void CompareMethods(BfMethodInstance* prevMethodInstance, BfTypeVector* prevGenericArgumentsSubstitute, BfMethodInstance* newMethodInstance, BfTypeVector* genericArgumentsSubstitute, diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index a766de23..cd074629 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -19346,12 +19346,19 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool if (defaultValue) { - BF_ASSERT(defaultValue.mValue.IsConst()); - while ((int)mCurMethodInstance->mDefaultValues.size() < paramDefIdx) - mCurMethodInstance->mDefaultValues.Add(BfIRValue()); + if (defaultValue.mType->IsVar()) + { + AssertErrorState(); + } + else + { + BF_ASSERT(defaultValue.mValue.IsConst()); + while ((int)mCurMethodInstance->mDefaultValues.size() < paramDefIdx) + mCurMethodInstance->mDefaultValues.Add(BfIRValue()); - CurrentAddToConstHolder(defaultValue.mValue); - mCurMethodInstance->mDefaultValues.Add(defaultValue.mValue); + CurrentAddToConstHolder(defaultValue.mValue); + mCurMethodInstance->mDefaultValues.Add(defaultValue.mValue); + } } } diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index d2cda888..5e2bbbed 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -878,7 +878,7 @@ public: BfIRBlock mIREntryBlock; Array > mLocals; HashSet > mLocalVarSet; - Array mLocalMethods; + Array mLocalMethods; Dictionary mLocalMethodMap; Dictionary mLocalMethodCache; // So any lambda 'capturing' and 'processing' stages use the same local method Array mDeferredLocalMethods; @@ -941,11 +941,11 @@ public: mLocals.Reserve(8); mLocalVarSet.mAlloc = &mBumpAlloc; mLocalVarSet.Reserve(8); - + mMethodInstance = NULL; mPrevMethodState = NULL; mConstResolveState = NULL; - mHotDataReferenceBuilder = NULL; + mHotDataReferenceBuilder = NULL; mHeadScope.mIsScopeHead = true; mCurScope = &mHeadScope; mTailScope = &mHeadScope; @@ -1620,8 +1620,8 @@ public: BfPointerType* CreatePointerType(BfTypeReference* typeRef); BfConstExprValueType* CreateConstExprValueType(const BfTypedValue& typedValue); BfBoxedType* CreateBoxedType(BfType* resolvedTypeRef); - BfTupleType* CreateTupleType(const BfTypeVector& fieldTypes, const Array& fieldNames); - BfTupleType* SantizeTupleType(BfTupleType* tupleType); + BfTupleType* CreateTupleType(const BfTypeVector& fieldTypes, const Array& fieldNames); + BfTupleType* SantizeTupleType(BfTupleType* tupleType); BfRefType* CreateRefType(BfType* resolvedTypeRef, BfRefType::RefKind refKind = BfRefType::RefKind_Ref); BfRetTypeType* CreateRetTypeType(BfType* resolvedTypeRef); BfConcreteInterfaceType* CreateConcreteInterfaceType(BfTypeInstance* interfaceType); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index f3833f18..f44c2c22 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -5243,7 +5243,7 @@ BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, const BfTypeVector& generic } BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType()); return resolvedType; - } + } BfGenericTypeInstance* genericInstType; if (typeDef->mTypeCode == BfTypeCode_TypeAlias) @@ -5431,7 +5431,7 @@ BfTypeDef* BfModule::ResolveGenericInstanceDef(BfGenericInstanceTypeRef* generic } BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVector& methodGenericArguments, bool allowFail) -{ +{ if (unspecializedType->IsGenericParam()) { auto genericParam = (BfGenericParamType*)unspecializedType; @@ -5446,6 +5446,9 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVect return unspecializedType; } + if (!unspecializedType->IsUnspecializedType()) + return unspecializedType; + if (unspecializedType->IsUnknownSizedArray()) { auto* arrayType = (BfUnknownSizedArrayType*)unspecializedType; @@ -5535,6 +5538,121 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, const BfTypeVect return CreateTupleType(genericArgs, names); } + if (unspecializedType->IsDelegate()) + { + BfDelegateType* unspecializedDelegateType = (BfDelegateType*)unspecializedType; + BfDelegateType* delegateType = mContext->mDelegateTypePool.Get(); + + bool failed = false; + + auto returnType = ResolveGenericType(unspecializedDelegateType->mReturnType, methodGenericArguments, allowFail); + if (returnType == NULL) + return NULL; + + auto baseDelegateType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance(); + + delegateType->mIsUnspecializedType = false; + delegateType->mIsUnspecializedTypeVariation = false; + if (delegateType->mTypeDef != NULL) + delete delegateType->mTypeDef; + delegateType->mParams.Clear(); + + BfTypeDef* typeDef = new BfTypeDef(); + + typeDef->mProject = baseDelegateType->mTypeDef->mProject; + typeDef->mSystem = mCompiler->mSystem; + typeDef->mName = mSystem->mEmptyAtom; + typeDef->mTypeCode = unspecializedDelegateType->mTypeDef->mTypeCode; + typeDef->mIsDelegate = unspecializedDelegateType->mTypeDef->mIsDelegate; + typeDef->mIsFunction = unspecializedDelegateType->mTypeDef->mIsFunction; + + BfMethodDef* methodDef = new BfMethodDef(); + methodDef->mDeclaringType = typeDef; + methodDef->mName = "Invoke"; + methodDef->mProtection = BfProtection_Public; + methodDef->mIdx = 0; + methodDef->mIsStatic = !typeDef->mIsDelegate; + + auto directTypeRef = BfAstNode::ZeroedAlloc(); + delegateType->mDirectAllocNodes.push_back(directTypeRef); + if (typeDef->mIsDelegate) + directTypeRef->Init(delegateType); + else + directTypeRef->Init(ResolveTypeDef(mCompiler->mFunctionTypeDef)); + typeDef->mBaseTypes.push_back(directTypeRef); + + directTypeRef = BfAstNode::ZeroedAlloc(); + delegateType->mDirectAllocNodes.push_back(directTypeRef); + directTypeRef->Init(returnType); + methodDef->mReturnTypeRef = directTypeRef; + delegateType->mReturnType = returnType; + + AddDependency(directTypeRef->mType, baseDelegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue); + + BfMethodDef* unspecializedInvokeMethodDef = unspecializedDelegateType->mTypeDef->GetMethodByName("Invoke"); + + int paramIdx = 0; + for (auto param : unspecializedDelegateType->mParams) + { + auto paramType = ResolveGenericType(param, methodGenericArguments, allowFail); + if (paramType == NULL) + { + failed = true; + break; + } + + BfParameterDef* unspecializedParamDef = unspecializedInvokeMethodDef->mParams[paramIdx]; + + if (paramType->IsUnspecializedType()) + delegateType->mIsUnspecializedType = true; + if (paramType->IsUnspecializedTypeVariation()) + delegateType->mIsUnspecializedTypeVariation = true; + if (!paramType->IsReified()) + delegateType->mIsReified = false; + if (paramType->IsGenericParam()) + { + delegateType->mIsUnspecializedTypeVariation = true; + } + + auto directTypeRef = BfAstNode::ZeroedAlloc(); + delegateType->mDirectAllocNodes.push_back(directTypeRef); + directTypeRef->Init(paramType); + + BfParameterDef* paramDef = new BfParameterDef(); + + paramDef->mTypeRef = directTypeRef; + paramDef->mName = unspecializedParamDef->mName; + methodDef->mParams.push_back(paramDef); + paramIdx++; + + delegateType->mParams.Add(paramType); + AddDependency(paramType, baseDelegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue); + } + + typeDef->mMethods.push_back(methodDef); + + // + + BfDefBuilder::AddMethod(typeDef, BfMethodType_Ctor, BfProtection_Public, false, ""); + if (typeDef->mIsDelegate) + BfDefBuilder::AddDynamicCastMethods(typeDef); + + delegateType->mContext = mContext; + delegateType->mTypeDef = typeDef; + + BfType* resolvedType = NULL; + if (!failed) + resolvedType = ResolveType(delegateType, BfPopulateType_Identity); + if (resolvedType != delegateType) + { + mContext->mDelegateTypePool.GiveBack(delegateType); + //mContext->mTypeDefTypeRefPool.GiveBack(typeRef); + } + BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType()); + return resolvedType; + + } + return unspecializedType; } @@ -5623,7 +5741,9 @@ BfGenericParamInstance* BfModule::GetGenericTypeParamInstance(int genericParamId BfGenericParamInstance* BfModule::GetGenericParamInstance(BfGenericParamType* type) { if (type->mGenericParamKind == BfGenericParamKind_Method) + { return mCurMethodInstance->mMethodInfoEx->mGenericParams[type->mGenericParamIdx]; + } return GetGenericTypeParamInstance(type->mGenericParamIdx); } @@ -7468,7 +7588,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula auto baseDelegateType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance(); BfDelegateType* delegateType = new BfDelegateType(); - + Val128 hashContext; BfTypeDef* typeDef = new BfTypeDef(); diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index db268e7d..ee630ddf 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -2754,6 +2754,34 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) return lhsClosure->mClosureHash == rhsClosure->mClosureHash; } + if (lhs->IsDelegateFromTypeRef() || lhs->IsFunctionFromTypeRef()) + { + if (!rhs->IsDelegateFromTypeRef() && !rhs->IsFunctionFromTypeRef()) + return false; + if (lhs->IsDelegate() != rhs->IsDelegate()) + return false; + BfDelegateType* lhsDelegateType = (BfDelegateType*)lhs; + BfDelegateType* rhsDelegateType = (BfDelegateType*)rhs; + if (lhsDelegateType->mTypeDef->mIsDelegate != rhsDelegateType->mTypeDef->mIsDelegate) + return false; + + auto lhsMethodDef = lhsDelegateType->mTypeDef->mMethods[0]; + auto rhsMethodDef = rhsDelegateType->mTypeDef->mMethods[0]; + + if (lhsDelegateType->mReturnType != rhsDelegateType->mReturnType) + return false; + if (lhsDelegateType->mParams.size() != rhsDelegateType->mParams.size()) + return false; + for (int paramIdx = 0; paramIdx < lhsDelegateType->mParams.size(); paramIdx++) + { + if (lhsDelegateType->mParams[paramIdx] != rhsDelegateType->mParams[paramIdx]) + return false; + if (lhsMethodDef->mParams[paramIdx]->mName != rhsMethodDef->mParams[paramIdx]->mName) + return false; + } + return true; + } + if (lhs->IsGenericTypeInstance()) { if (!rhs->IsGenericTypeInstance()) @@ -2874,34 +2902,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) return (lhsMethodRefType->mMethodRef == rhsMethodRefType->mMethodRef) && (lhsMethodRefType->mOwner == rhsMethodRefType->mOwner) && (lhsMethodRefType->mOwnerRevision == rhsMethodRefType->mOwnerRevision); - } - else if (lhs->IsDelegateFromTypeRef() || lhs->IsFunctionFromTypeRef()) - { - if (!rhs->IsDelegateFromTypeRef() && !rhs->IsFunctionFromTypeRef()) - return false; - if (lhs->IsDelegate() != rhs->IsDelegate()) - return false; - BfDelegateType* lhsDelegateType = (BfDelegateType*)lhs; - BfDelegateType* rhsDelegateType = (BfDelegateType*)rhs; - if (lhsDelegateType->mTypeDef->mIsDelegate != rhsDelegateType->mTypeDef->mIsDelegate) - return false; - - auto lhsMethodDef = lhsDelegateType->mTypeDef->mMethods[0]; - auto rhsMethodDef = rhsDelegateType->mTypeDef->mMethods[0]; - - if (lhsDelegateType->mReturnType != rhsDelegateType->mReturnType) - return false; - if (lhsDelegateType->mParams.size() != rhsDelegateType->mParams.size()) - return false; - for (int paramIdx = 0; paramIdx < lhsDelegateType->mParams.size(); paramIdx++) - { - if (lhsDelegateType->mParams[paramIdx] != rhsDelegateType->mParams[paramIdx]) - return false; - if (lhsMethodDef->mParams[paramIdx]->mName != rhsMethodDef->mParams[paramIdx]->mName) - return false; - } - return true; - } + } else if ((lhs->IsConstExprValue()) || (rhs->IsConstExprValue())) { if (!lhs->IsConstExprValue() || !rhs->IsConstExprValue())