Bläddra i källkod

Allow comptime extern constraint typerefs

Brian Fiete 3 år sedan
förälder
incheckning
12a3ba937a

+ 19 - 17
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -1547,7 +1547,7 @@ bool BfMethodMatcher::InferFromGenericConstraints(BfMethodInstance* methodInstan
 					exprEvaluator.PerformUnaryOperation(NULL, checkOpConstraint.mUnaryOp, NULL, BfUnaryOpFlag_IsConstraintCheck);
 				
 					if (exprEvaluator.mResult)
-						checkArgType = exprEvaluator.mResult.mType;					
+						checkArgType = exprEvaluator.mResult.mType;
 				}
 			}			
 		}
@@ -1557,21 +1557,9 @@ bool BfMethodMatcher::InferFromGenericConstraints(BfMethodInstance* methodInstan
 	{
 		for (auto comptypeConstraint : genericParamInst->mComptypeConstraint)
 		{
-			BfConstraintState constraintSet;
-			constraintSet.mPrevState = mModule->mContext->mCurConstraintState;
-			constraintSet.mGenericParamInstance = genericParamInst;
-			constraintSet.mMethodInstance = methodInstance;
-			constraintSet.mMethodGenericArgsOverride = methodGenericArgs;
-			
-			SetAndRestoreValue<BfConstraintState*> prevConstraintSet(mModule->mContext->mCurConstraintState, &constraintSet);
-			if (!mModule->CheckConstraintState(NULL))
-				return false;
-
-			SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mModule->mCurMethodInstance, methodInstance);
-			SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mModule->mCurTypeInstance, methodInstance->GetOwner());
-			SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
-
-			checkArgType = mModule->ResolveTypeRef(comptypeConstraint);
+			checkArgType = mModule->ResolveGenericMethodTypeRef(comptypeConstraint, methodInstance, genericParamInst, methodGenericArgs);
+			if (checkArgType == NULL)
+				return false;			
 		}
 	}
 
@@ -2138,7 +2126,21 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
 	{
 		auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[checkMethod->mGenericParams.size() + externConstraintIdx];
 		BF_ASSERT(genericParam->mExternType != NULL);
- 		if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), genericParam->mExternType, NULL, genericParam, genericArgumentsSubstitute, NULL))
+		auto externType = genericParam->mExternType;
+		BfTypeVector* externGenericArgumentsSubstitute = genericArgumentsSubstitute;
+
+		if (externType->IsVar())
+		{
+			auto& externConstraint = checkMethod->mExternalConstraints[externConstraintIdx];
+			if (externConstraint.mTypeRef != NULL)
+			{
+				externType = mModule->ResolveGenericMethodTypeRef(externConstraint.mTypeRef, methodInstance, genericParam, genericArgumentsSubstitute);
+				if (externType == NULL)
+					goto NoMatch;
+			}
+		}
+
+ 		if (!mModule->CheckGenericConstraints(BfGenericParamSource(methodInstance), externType, NULL, genericParam, externGenericArgumentsSubstitute, NULL))
  			goto NoMatch;
 	}
 

+ 2 - 0
IDEHelper/Compiler/BfModule.cpp

@@ -21956,6 +21956,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
 
 		for (auto genericParam : methodInstance->mMethodInfoEx->mGenericParams)
 		{
+			if (!genericParam->mExternType->IsGenericParam())
+				AddDependency(genericParam->mExternType, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint);
 			for (auto constraintTypeInst : genericParam->mInterfaceConstraints)
 				AddDependency(constraintTypeInst, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint);
 			if (genericParam->mTypeConstraint != NULL)

+ 1 - 0
IDEHelper/Compiler/BfModule.h

@@ -1708,6 +1708,7 @@ public:
 	bool InitGenericParams(BfType* resolvedTypeRef);
 	bool FinishGenericParams(BfType* resolvedTypeRef);
 	bool ValidateGenericConstraints(BfTypeReference* typeRef, BfTypeInstance* genericTypeInstance, bool ignoreErrors);
+	BfType* ResolveGenericMethodTypeRef(BfTypeReference* typeRef, BfMethodInstance* methodInstance, BfGenericParamInstance* genericParamInstance, BfTypeVector* methodGenericArgsOverride);
 	bool AreConstraintsSubset(BfGenericParamInstance* checkInner, BfGenericParamInstance* checkOuter);
 	bool CheckConstraintState(BfAstNode* refNode);
 	bool ShouldAllowMultipleDefinitions(BfTypeInstance* typeInst, BfTypeDef* firstDeclaringTypeDef, BfTypeDef* secondDeclaringTypeDef);

+ 26 - 0
IDEHelper/Compiler/BfModuleTypeUtils.cpp

@@ -109,6 +109,8 @@ BfGenericExtensionEntry* BfModule::BuildGenericExtensionInfo(BfTypeInstance* gen
 
 	for (auto genericParam : genericExEntry->mGenericParams)
 	{
+		if (!genericParam->mExternType->IsGenericParam())
+			AddDependency(genericParam->mExternType, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint);
 		for (auto constraintTypeInst : genericParam->mInterfaceConstraints)
 			AddDependency(constraintTypeInst, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint);
 		if (genericParam->mTypeConstraint != NULL)
@@ -301,6 +303,8 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef)
 
 	for (auto genericParam : genericTypeInst->mGenericTypeInfo->mGenericParams)
 	{
+		if (!genericParam->mExternType->IsGenericParam())
+			AddDependency(genericParam->mExternType, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint);
 		for (auto constraintTypeInst : genericParam->mInterfaceConstraints)
 			AddDependency(constraintTypeInst, mCurTypeInstance, BfDependencyMap::DependencyFlag_Constraint);
 		if (genericParam->mTypeConstraint != NULL)
@@ -377,6 +381,28 @@ bool BfModule::ValidateGenericConstraints(BfTypeReference* typeRef, BfTypeInstan
 	return true;
 }
 
+BfType* BfModule::ResolveGenericMethodTypeRef(BfTypeReference* typeRef, BfMethodInstance* methodInstance, BfGenericParamInstance* genericParamInstance, BfTypeVector* methodGenericArgsOverride)
+{
+	BfConstraintState constraintSet;
+	constraintSet.mPrevState = mContext->mCurConstraintState;
+	constraintSet.mGenericParamInstance = genericParamInstance;
+	constraintSet.mMethodInstance = methodInstance;
+	constraintSet.mMethodGenericArgsOverride = methodGenericArgsOverride;
+
+	SetAndRestoreValue<BfConstraintState*> prevConstraintSet(mContext->mCurConstraintState, &constraintSet);
+	if (!CheckConstraintState(NULL))
+		return NULL;
+
+	SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, methodInstance);
+	SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, methodInstance->GetOwner());
+	SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
+
+	BfType* type = ResolveTypeRef(typeRef);
+	if (type == NULL)
+		type = GetPrimitiveType(BfTypeCode_Var);
+	return type;
+}
+
 bool BfModule::AreConstraintsSubset(BfGenericParamInstance* checkInner, BfGenericParamInstance* checkOuter)
 {
 	if (checkOuter == NULL)

+ 6 - 1
IDEHelper/Compiler/BfSourceClassifier.cpp

@@ -572,7 +572,12 @@ void BfSourceClassifier::Visit(BfMethodDeclaration* methodDeclaration)
 			{
 				BfTypeReference* typeRef = genericConstraint->mTypeRef;
 				if (typeRef != NULL)
-					SetElementType(typeRef, BfSourceElementType_GenericParam);
+				{
+					if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(typeRef))
+						SetElementType(typeRef, BfSourceElementType_GenericParam);						
+					else
+						VisitChild(typeRef);
+				}
 			}
 		}
 	}