1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 04:22:20 +02:00

Fix generic binding in generic mixins

This commit is contained in:
Brian Fiete 2022-07-11 09:03:28 -04:00
parent 627b0381f8
commit 51eaa6276f
3 changed files with 47 additions and 4 deletions

View file

@ -3308,8 +3308,31 @@ BfType* BfExprEvaluator::BindGenericType(BfAstNode* node, BfType* bindType)
int64 nodeId = ((int64)parser->mDataId << 32) + node->GetSrcStart(); int64 nodeId = ((int64)parser->mDataId << 32) + node->GetSrcStart();
auto genericTypeBindings = mModule->mCurMethodState->GetRootMethodState()->mGenericTypeBindings; 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<BfMethodState*> 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()) if (!bindType->IsGenericParam())
return bindType; return bindType;

View file

@ -5206,7 +5206,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
auto resolvedFieldType = fieldInstance->GetResolvedType(); auto resolvedFieldType = fieldInstance->GetResolvedType();
if ((!typeInstance->IsBoxed()) && (fieldDef != NULL)) 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); Warn(0, StrFormat("Field type '%s' is not applicable for 'using'", TypeToString(resolvedFieldType).c_str()), fieldDef->GetFieldDeclaration()->mConstSpecifier);
if (fieldInstance->mIsEnumPayloadCase) if (fieldInstance->mIsEnumPayloadCase)
@ -9315,12 +9315,16 @@ BfGenericParamInstance* BfModule::GetGenericParamInstance(BfGenericParamType* ty
{ {
if (type->mGenericParamKind == BfGenericParamKind_Method) 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"); FatalError("Invalid GetGenericParamInstance method generic param");
return NULL; return NULL;
} }
return mCurMethodInstance->mMethodInfoEx->mGenericParams[type->mGenericParamIdx]; return curGenericMethodInstance->mMethodInfoEx->mGenericParams[type->mGenericParamIdx];
} }
return GetGenericTypeParamInstance(type->mGenericParamIdx); return GetGenericTypeParamInstance(type->mGenericParamIdx);

View file

@ -84,6 +84,19 @@ namespace Tests
res.Value res.Value
} }
static mixin DisposeIt<T>(T val) where T : IDisposable
{
val?.Dispose();
}
class DispClass : IDisposable
{
void IDisposable.Dispose()
{
}
}
[Test] [Test]
public static void TestBasics() public static void TestBasics()
{ {
@ -114,6 +127,9 @@ namespace Tests
Dictionary<int, Dictionary<int, int>> test = scope .() {(1,null)}; Dictionary<int, Dictionary<int, int>> test = scope .() {(1,null)};
int val = CircularMixin!(test); int val = CircularMixin!(test);
Test.Assert(val == 211); Test.Assert(val == 211);
DispClass dc = scope .();
DisposeIt!(dc);
} }
[Test] [Test]