diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index c6e912a2..636ea5f7 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -3308,8 +3308,31 @@ BfType* BfExprEvaluator::BindGenericType(BfAstNode* node, BfType* bindType) int64 nodeId = ((int64)parser->mDataId << 32) + node->GetSrcStart(); auto genericTypeBindings = mModule->mCurMethodState->GetRootMethodState()->mGenericTypeBindings; + auto methodInstance = mModule->mCurMethodInstance; - if ((mModule->mCurMethodInstance->mIsUnspecialized) && (!mModule->mCurMethodInstance->mIsUnspecializedVariation)) + if (mModule->mCurMethodState->mMixinState != NULL) + { + auto mixinMethodInstance = mModule->mCurMethodState->mMixinState->mMixinMethodInstance; + if (!mixinMethodInstance->mMethodDef->mGenericParams.IsEmpty()) + { + auto unspecMixinMethodInstance = mModule->GetUnspecializedMethodInstance(mixinMethodInstance, false); + + if (!unspecMixinMethodInstance->mHasBeenProcessed) + { + // Make sure the unspecialized method is processed so we can take its bindings + // Clear mCurMethodState so we don't think we're in a local method + SetAndRestoreValue prevMethodState_Unspec(mModule->mCurMethodState, NULL); + if (unspecMixinMethodInstance->mMethodProcessRequest == NULL) + unspecMixinMethodInstance->mDeclModule->mIncompleteMethodCount++; + mModule->mContext->ProcessMethod(unspecMixinMethodInstance); + } + + methodInstance = mixinMethodInstance; + genericTypeBindings = &unspecMixinMethodInstance->mMethodInfoEx->mGenericTypeBindings; + } + } + + if ((methodInstance->mIsUnspecialized) && (!methodInstance->mIsUnspecializedVariation)) { if (!bindType->IsGenericParam()) return bindType; diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index ecb1eda7..26f543de 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -5206,7 +5206,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy auto resolvedFieldType = fieldInstance->GetResolvedType(); if ((!typeInstance->IsBoxed()) && (fieldDef != NULL)) { - if ((fieldDef->mUsingProtection != BfProtection_Hidden) && (!resolvedFieldType->IsGenericParam()) && (!resolvedFieldType->IsObject())) + if ((fieldDef->mUsingProtection != BfProtection_Hidden) && (!resolvedFieldType->IsGenericParam()) && (!resolvedFieldType->IsObject()) && (!resolvedFieldType->IsStruct())) Warn(0, StrFormat("Field type '%s' is not applicable for 'using'", TypeToString(resolvedFieldType).c_str()), fieldDef->GetFieldDeclaration()->mConstSpecifier); if (fieldInstance->mIsEnumPayloadCase) @@ -9315,12 +9315,16 @@ BfGenericParamInstance* BfModule::GetGenericParamInstance(BfGenericParamType* ty { if (type->mGenericParamKind == BfGenericParamKind_Method) { - if ((mCurMethodInstance == NULL) || (mCurMethodInstance->mMethodInfoEx == NULL) || (type->mGenericParamIdx >= mCurMethodInstance->mMethodInfoEx->mGenericParams.mSize)) + auto curGenericMethodInstance = mCurMethodInstance; + if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL)) + curGenericMethodInstance = mCurMethodState->mMixinState->mMixinMethodInstance; + + if ((curGenericMethodInstance == NULL) || (curGenericMethodInstance->mMethodInfoEx == NULL) || (type->mGenericParamIdx >= curGenericMethodInstance->mMethodInfoEx->mGenericParams.mSize)) { FatalError("Invalid GetGenericParamInstance method generic param"); return NULL; } - return mCurMethodInstance->mMethodInfoEx->mGenericParams[type->mGenericParamIdx]; + return curGenericMethodInstance->mMethodInfoEx->mGenericParams[type->mGenericParamIdx]; } return GetGenericTypeParamInstance(type->mGenericParamIdx); diff --git a/IDEHelper/Tests/src/Mixins.bf b/IDEHelper/Tests/src/Mixins.bf index 33f31501..2f6ffda9 100644 --- a/IDEHelper/Tests/src/Mixins.bf +++ b/IDEHelper/Tests/src/Mixins.bf @@ -84,6 +84,19 @@ namespace Tests res.Value } + static mixin DisposeIt(T val) where T : IDisposable + { + val?.Dispose(); + } + + class DispClass : IDisposable + { + void IDisposable.Dispose() + { + + } + } + [Test] public static void TestBasics() { @@ -114,6 +127,9 @@ namespace Tests Dictionary> test = scope .() {(1,null)}; int val = CircularMixin!(test); Test.Assert(val == 211); + + DispClass dc = scope .(); + DisposeIt!(dc); } [Test]