Просмотр исходного кода

Better handling of extern generic constraints

Brian Fiete 8 месяцев назад
Родитель
Сommit
1e44392da8

+ 14 - 0
IDEHelper/Compiler/BfModule.cpp

@@ -8566,6 +8566,20 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
 	if (checkArgType->IsObjectOrInterface())
 		argIsReferenceType = true;
 
+	if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecialized) && (mCurMethodInstance->mMethodInfoEx != NULL))
+	{
+		for (int genericParamIdx = (int)mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size();
+			genericParamIdx < mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
+		{
+			auto genericParamInst = mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
+					
+ 			if (genericParamInst->mExternType == checkArgType)
+ 			{
+				checkGenericParamFlags |= genericParamInst->mGenericParamFlags; 				
+ 			}
+		}
+	}
+
 	BfTypeInstance* typeConstraintInst = NULL;
 	if (genericParamInst->mTypeConstraint != NULL)
 		typeConstraintInst = genericParamInst->mTypeConstraint->ToTypeInstance();

+ 1 - 1
IDEHelper/Compiler/BfModule.h

@@ -1959,7 +1959,7 @@ public:
 	BfGenericParamInstance* GetGenericTypeParamInstance(int paramIdx);
 	BfGenericParamInstance* GetGenericParamInstance(BfGenericParamType* type, bool checkMixinBind = false, BfFailHandleKind failHandleKind = BfFailHandleKind_Normal);
 	void GetActiveTypeGenericParamInstances(SizedArray<BfGenericParamInstance*, 4>& genericParamInstance);
-	BfGenericParamInstance* GetMergedGenericParamData(BfGenericParamType* type, BfGenericParamFlags& outFlags, BfType*& outTypeConstraint);
+	BfGenericParamInstance* GetMergedGenericParamData(BfType* type, BfGenericParamFlags& outFlags, BfType*& outTypeConstraint);
 	BfTypeInstance* GetBaseType(BfTypeInstance* typeInst);
 	void HandleTypeGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, int typeGenericParamIdx);
 	void HandleMethodGenericParamRef(BfAstNode* refNode, BfTypeDef* typeDef, BfMethodDef* methodDef, int typeGenericParamIdx);

+ 32 - 4
IDEHelper/Compiler/BfModuleTypeUtils.cpp

@@ -9621,11 +9621,39 @@ void BfModule::GetActiveTypeGenericParamInstances(SizedArray<BfGenericParamInsta
 		genericParamInstances.Add(entry);
 }
 
-BfGenericParamInstance* BfModule::GetMergedGenericParamData(BfGenericParamType* type, BfGenericParamFlags& outFlags, BfType*& outTypeConstraint)
+BfGenericParamInstance* BfModule::GetMergedGenericParamData(BfType* type, BfGenericParamFlags& outFlags, BfType*& outTypeConstraint)
 {
-	BfGenericParamInstance* genericParam = GetGenericParamInstance(type);
-	outFlags = genericParam->mGenericParamFlags;
-	outTypeConstraint = genericParam->mTypeConstraint;
+	BfGenericParamType* genericParamType = NULL;
+	if (type->IsGenericParam())
+		genericParamType = (BfGenericParamType*)type;
+
+	BfGenericParamInstance* genericParam = NULL;
+	if (genericParamType != NULL)
+	{
+		genericParam = GetGenericParamInstance(genericParamType);
+		outFlags = (BfGenericParamFlags)(outFlags | genericParam->mGenericParamFlags);
+		if (genericParam->mTypeConstraint != NULL)
+			outTypeConstraint = genericParam->mTypeConstraint;
+	}
+	else
+	{
+		outFlags = BfGenericParamFlag_None;
+		outTypeConstraint = NULL;
+
+		if ((mCurTypeInstance != NULL) && (mCurTypeInstance->mGenericTypeInfo != NULL))
+		{
+			for (int genericIdx = mCurTypeInstance->mTypeDef->mGenericParamDefs.mSize; genericIdx < mCurTypeInstance->mGenericTypeInfo->mGenericParams.mSize; genericIdx++)
+			{
+				auto genericParam = mCurTypeInstance->mGenericTypeInfo->mGenericParams[genericIdx];
+				if (genericParam->mExternType == type)
+				{
+					outFlags = (BfGenericParamFlags)(outFlags | genericParam->mGenericParamFlags);
+					if (genericParam->mTypeConstraint != NULL)
+						outTypeConstraint = genericParam->mTypeConstraint;
+				}
+			}
+		}
+	}
 
 	// Check method generic constraints
 	if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mIsUnspecialized) && (mCurMethodInstance->mMethodInfoEx != NULL))

+ 28 - 0
IDEHelper/Tests/src/Generics2.bf

@@ -1,3 +1,5 @@
+#pragma warning disable 168
+
 using System;
 using System.Collections;
 
@@ -21,6 +23,32 @@ namespace Tests
 			}
 		}
 
+		interface IZop
+		{
+			void Zop();
+		}
+
+		interface IZag
+		{
+			void Zag();
+		}
+
+		class ClassC<T> where T : IDisposable
+		{
+			public void MethodA(T val) where T : IZop, delete, new
+			{
+				val.Zop();
+				MethodB(val);
+				delete val;
+			}
+
+			public void MethodB(T val) where T : IZop, delete, new
+			{
+				alloctype(T) z = new T();
+				delete val;
+			}
+		}
+
 		struct TestFunc<T, Del>
 		{
 			private int mId;