diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 760f6c68..c2407a3e 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -7787,9 +7787,16 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS } } + if (checkArgType->IsPointer()) + { + auto ptrType = (BfPointerType*)checkArgType; + checkArgType = ptrType->mElementType; + } + if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_New) != 0) { bool canAlloc = false; + if (auto checkTypeInst = checkArgType->ToTypeInstance()) { if (checkTypeInst->IsObjectOrStruct()) @@ -7857,13 +7864,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS } if ((genericParamInst->mInterfaceConstraints.IsEmpty()) && (genericParamInst->mOperatorConstraints.IsEmpty()) && (genericParamInst->mTypeConstraint == NULL)) - return true; - - if (checkArgType->IsPointer()) - { - auto ptrType = (BfPointerType*)checkArgType; - checkArgType = ptrType->mElementType; - } + return true; if (genericParamInst->mTypeConstraint != NULL) { diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index a3bda91d..e9919b51 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -3925,6 +3925,10 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt) { if (genericParamInst->mGenericParamFlags & (BfGenericParamFlag_Delete | BfGenericParamFlag_Var)) return; + if (genericParamInst->mGenericParamFlags & BfGenericParamFlag_StructPtr) + return; + if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Struct) && (checkType->IsPointer())) + return; Fail(StrFormat("Must add 'where %s : delete' constraint to generic parameter to delete generic type '%s'", genericParamInst->GetGenericParamDef()->mName.c_str(), TypeToString(val.mType).c_str()), deleteStmt->mExpression); return; diff --git a/IDEHelper/Tests/src/Generics.bf b/IDEHelper/Tests/src/Generics.bf index 01d420b6..a5999428 100644 --- a/IDEHelper/Tests/src/Generics.bf +++ b/IDEHelper/Tests/src/Generics.bf @@ -23,6 +23,16 @@ namespace Tests { class Generics { + struct StructA : IDisposable + { + int mA = 123; + + public void Dispose() + { + + } + } + class ClassA : IDisposable, LibA.IVal { int LibA.IVal.Val @@ -172,7 +182,7 @@ namespace Tests delete val; } - public static void Alloc2() where T : new, delete, IDisposable, struct + public static void Alloc2() where T : new, IDisposable, struct { alloctype(T) val = new T(); T* val2 = val; @@ -180,6 +190,14 @@ namespace Tests delete val; } + public static void Alloc3() where T : new, IDisposable, struct* + { + T val2 = default; + if (val2 != null) + val2.Dispose(); + delete val2; + } + public class ClassE { public static Self Instance = new ClassE() ~ delete _; @@ -311,6 +329,9 @@ namespace Tests [Test] public static void TestBasics() { + Alloc2(); + Alloc3(); + MethodD(scope => MethodC); List list = scope .();