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:
parent
627b0381f8
commit
51eaa6276f
3 changed files with 47 additions and 4 deletions
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue