From 35505d905a7b13ab38d25d03d97fa83f5966394d Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Mon, 10 Aug 2020 17:02:48 -0700 Subject: [PATCH] More extern constraints work --- BeefLibs/corlib/src/Math.bf | 4 ++-- IDEHelper/Compiler/BfExprEvaluator.cpp | 17 +++++++++++------ IDEHelper/Compiler/BfModule.cpp | 4 +++- IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 5 +++++ IDEHelper/Compiler/BfResolvedTypeUtils.h | 1 + IDEHelper/Tests/src/ExtensionMethods.bf | 2 +- IDEHelper/Tests/src/Generics.bf | 11 +++++++++++ 7 files changed, 34 insertions(+), 10 deletions(-) diff --git a/BeefLibs/corlib/src/Math.bf b/BeefLibs/corlib/src/Math.bf index 0dda54c2..415c7564 100644 --- a/BeefLibs/corlib/src/Math.bf +++ b/BeefLibs/corlib/src/Math.bf @@ -443,7 +443,7 @@ namespace System return 0; } - /*public static int Sign(T value) where int : operator T <=> T, ICanBeNaN + public static int Sign(T value) where int : operator T <=> T where T : ICanBeNaN { if (value < default) return -1; @@ -453,7 +453,7 @@ namespace System return 0; Runtime.FatalError("Cannot be used on NaN"); - }*/ + } public static int32 DivRem(int32 a, int32 b, out int32 result) { diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index c0bd1c7d..84611fc8 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -209,15 +209,15 @@ void BfMethodMatcher::Init(/*SizedArrayImpl& arguments, */BfSized } bool BfMethodMatcher::IsMemberAccessible(BfTypeInstance* typeInst, BfTypeDef* declaringType) -{ +{ if (mActiveTypeDef == NULL) mActiveTypeDef = mModule->GetActiveTypeDef(); - if (!typeInst->IsTypeMemberIncluded(declaringType, mActiveTypeDef, mModule)) - return false; // This may not be completely correct - BUT if we don't have this then even Dictionary TKey's operator == won't be considered accessible if ((!mModule->IsInSpecializedSection()) && (mActiveTypeDef->mTypeDeclaration != NULL)) - { + { + if (!typeInst->IsTypeMemberIncluded(declaringType, mActiveTypeDef, mModule)) + return false; if (!typeInst->IsTypeMemberAccessible(declaringType, mActiveTypeDef)) return false; } @@ -931,8 +931,13 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp auto prevMethodGenericParam = prevMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx]; SET_BETTER_OR_WORSE(mModule->AreConstraintsSubset(prevMethodGenericParam, newMethodGenericParam), mModule->AreConstraintsSubset(newMethodGenericParam, prevMethodGenericParam)); } - } - + + if ((!isBetter) && (!isWorse)) + { + SET_BETTER_OR_WORSE(newMethodInstance->HasExternConstraints(), prevMethodInstance->HasExternConstraints()); + } + } + if ((isBetter) || (isWorse)) { RETURN_RESULTS; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 90ea91a3..e6763abe 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -12788,9 +12788,11 @@ bool BfModule::InDefinitionSection() bool BfModule::IsInSpecializedGeneric() { + if (mCurTypeInstance->IsSpecializedType()) + return true; if ((mCurMethodInstance == NULL) || (mCurMethodInstance->mIsUnspecialized)) return false; - return (mCurMethodInstance->GetNumGenericArguments() != 0) || (mCurTypeInstance->IsGenericTypeInstance()); + return (mCurMethodInstance->GetNumGenericArguments() != 0); } bool BfModule::IsInSpecializedSection() diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index 9d0a78e1..7c07743b 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -645,6 +645,11 @@ bool BfMethodInstance::IsSpecializedByAutoCompleteMethod() return false; } +bool BfMethodInstance::HasExternConstraints() +{ + return (mMethodInfoEx != NULL) && (mMethodInfoEx->mGenericParams.size() > mMethodInfoEx->mMethodGenericArguments.size()); +} + bool BfMethodInstance::HasParamsArray() { if (mParams.size() == 0) diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index 263d3bde..c2ab7da6 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -865,6 +865,7 @@ public: bool IsSpecializedGenericMethod(); bool IsSpecializedGenericMethodOrType(); bool IsSpecializedByAutoCompleteMethod(); + bool HasExternConstraints(); bool HasThis(); bool HasExplicitThis(); bool HasParamsArray(); diff --git a/IDEHelper/Tests/src/ExtensionMethods.bf b/IDEHelper/Tests/src/ExtensionMethods.bf index 8d37e89c..3c12484e 100644 --- a/IDEHelper/Tests/src/ExtensionMethods.bf +++ b/IDEHelper/Tests/src/ExtensionMethods.bf @@ -47,7 +47,7 @@ namespace Tests static { - public static T Total(this List list) where T : IOpAddable + public static T Total(this List list) where T : operator T + T { T total = default; for (let val in list) diff --git a/IDEHelper/Tests/src/Generics.bf b/IDEHelper/Tests/src/Generics.bf index e009e2b7..7a54a555 100644 --- a/IDEHelper/Tests/src/Generics.bf +++ b/IDEHelper/Tests/src/Generics.bf @@ -116,9 +116,20 @@ namespace Tests return 3; } + public struct Entry + { + public static int operator<=>(Entry lhs, Entry rhs) + { + return 0; + } + } + [Test] public static void TestBasics() { + List list = scope .(); + list.Sort(); + ClassA ca = scope .(); ClassB cb = scope .(); Test.Assert(LibA.LibA0.GetVal(ca) == 123);