mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 20:12:21 +02:00
Added extern constraints to types
This commit is contained in:
parent
7724c6ae64
commit
c3bc2bc67c
10 changed files with 121 additions and 38 deletions
|
@ -4012,6 +4012,8 @@ void BfCompiler::ProcessAutocompleteTempType()
|
||||||
module->HandleTypeGenericParamRef(nameNode, tempTypeDef, genericParamIdx);
|
module->HandleTypeGenericParamRef(nameNode, tempTypeDef, genericParamIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: Do extern constraint stuff here
|
||||||
|
|
||||||
for (auto fieldDef : tempTypeDef->mFields)
|
for (auto fieldDef : tempTypeDef->mFields)
|
||||||
{
|
{
|
||||||
BP_ZONE("ProcessAutocompleteTempType.CheckField");
|
BP_ZONE("ProcessAutocompleteTempType.CheckField");
|
||||||
|
|
|
@ -1629,7 +1629,7 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
|
||||||
int outerGenericSize = 0;
|
int outerGenericSize = 0;
|
||||||
if (mCurTypeDef->mOuterType != NULL)
|
if (mCurTypeDef->mOuterType != NULL)
|
||||||
outerGenericSize = (int)mCurTypeDef->mOuterType->mGenericParamDefs.size();
|
outerGenericSize = (int)mCurTypeDef->mOuterType->mGenericParamDefs.size();
|
||||||
ParseGenericParams(typeDeclaration->mGenericParams, typeDeclaration->mGenericConstraintsDeclaration, mCurTypeDef->mGenericParamDefs, NULL, outerGenericSize);
|
ParseGenericParams(typeDeclaration->mGenericParams, typeDeclaration->mGenericConstraintsDeclaration, mCurTypeDef->mGenericParamDefs, &mCurTypeDef->mExternalConstraints, outerGenericSize);
|
||||||
|
|
||||||
BF_ASSERT(mCurTypeDef->mNameEx == NULL);
|
BF_ASSERT(mCurTypeDef->mNameEx == NULL);
|
||||||
|
|
||||||
|
|
|
@ -13034,7 +13034,7 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
|
||||||
BfTypeVector* typeGenericArguments = NULL;
|
BfTypeVector* typeGenericArguments = NULL;
|
||||||
if (owner->mGenericTypeInfo != NULL)
|
if (owner->mGenericTypeInfo != NULL)
|
||||||
typeGenericArguments = &owner->mGenericTypeInfo->mTypeGenericArguments;
|
typeGenericArguments = &owner->mGenericTypeInfo->mTypeGenericArguments;
|
||||||
genericArg = mModule->ResolveGenericType(genericArg, typeGenericArguments, checkMethodGenericArgs);
|
//genericArg = mModule->ResolveGenericType(genericArg, typeGenericArguments, checkMethodGenericArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (genericArg->IsVar())
|
if (genericArg->IsVar())
|
||||||
|
|
|
@ -3897,10 +3897,18 @@ void BfModule::FindSubTypes(BfTypeInstance* classType, SizedArrayImpl<int>* outV
|
||||||
{
|
{
|
||||||
bool needsExCheck = false;
|
bool needsExCheck = false;
|
||||||
if (ifaceInst.mDeclaringType->mProject != classType->mTypeDef->mProject)
|
if (ifaceInst.mDeclaringType->mProject != classType->mTypeDef->mProject)
|
||||||
|
{
|
||||||
|
PopulateType(ifaceInst.mInterfaceType, BfPopulateType_DataAndMethods);
|
||||||
|
if (ifaceInst.mInterfaceType->mVirtualMethodTableSize > 0)
|
||||||
{
|
{
|
||||||
exChecks->push_back(ifaceInst.mInterfaceType);
|
exChecks->push_back(ifaceInst.mInterfaceType);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We can only do an 'exCheck' if we're actually going to slot this interface
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outVals->push_back(ifaceInst.mInterfaceType->mTypeId);
|
outVals->push_back(ifaceInst.mInterfaceType->mTypeId);
|
||||||
|
@ -6878,8 +6886,9 @@ String BfModule::GenericParamSourceToString(const BfGenericParamSource & generic
|
||||||
{
|
{
|
||||||
if (genericParamSource.mMethodInstance != NULL)
|
if (genericParamSource.mMethodInstance != NULL)
|
||||||
{
|
{
|
||||||
auto methodInst = GetUnspecializedMethodInstance(genericParamSource.mMethodInstance);
|
auto methodInst = GetUnspecializedMethodInstance(genericParamSource.mMethodInstance, false);
|
||||||
return MethodToString(methodInst);
|
SetAndRestoreValue<BfMethodInstance*> prevMethodInst(methodInst, NULL);
|
||||||
|
return MethodToString(genericParamSource.mMethodInstance);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -9264,12 +9273,16 @@ BfMethodInstance* BfModule::GetRawMethodByName(BfTypeInstance* typeInstance, con
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfMethodInstance* BfModule::GetUnspecializedMethodInstance(BfMethodInstance* methodInstance)
|
BfMethodInstance* BfModule::GetUnspecializedMethodInstance(BfMethodInstance* methodInstance, bool useUnspecializedType)
|
||||||
{
|
{
|
||||||
if ((methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mMethodGenericArguments.size() != 0))
|
if ((methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mMethodGenericArguments.size() != 0))
|
||||||
methodInstance = methodInstance->mMethodInstanceGroup->mDefault;
|
methodInstance = methodInstance->mMethodInstanceGroup->mDefault;
|
||||||
|
|
||||||
auto owner = methodInstance->mMethodInstanceGroup->mOwner;
|
auto owner = methodInstance->mMethodInstanceGroup->mOwner;
|
||||||
|
|
||||||
|
if (!useUnspecializedType)
|
||||||
|
return GetRawMethodInstanceAtIdx(owner, methodInstance->mMethodDef->mIdx);
|
||||||
|
|
||||||
if (!owner->IsGenericTypeInstance())
|
if (!owner->IsGenericTypeInstance())
|
||||||
return methodInstance;
|
return methodInstance;
|
||||||
|
|
||||||
|
@ -19861,15 +19874,18 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (unspecializedTypeInstance == NULL)
|
|
||||||
unspecializedTypeInstance = GetUnspecializedTypeInstance(mCurTypeInstance);
|
|
||||||
|
|
||||||
auto externConstraintDef = genericParam->GetExternConstraintDef();
|
auto externConstraintDef = genericParam->GetExternConstraintDef();
|
||||||
// Resolve in the unspecialized type, then resolve the generic later. This fixes ambiguity where the type is specialized by a method generic arg
|
|
||||||
{
|
// if (unspecializedTypeInstance == NULL)
|
||||||
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, unspecializedTypeInstance);
|
// unspecializedTypeInstance = GetUnspecializedTypeInstance(mCurTypeInstance);
|
||||||
|
//
|
||||||
|
// // Resolve in the unspecialized type, then resolve the generic later. This fixes ambiguity where the type is specialized by a method generic arg
|
||||||
|
// {
|
||||||
|
// SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, unspecializedTypeInstance);
|
||||||
|
// genericParam->mExternType = ResolveTypeRef(externConstraintDef->mTypeRef);
|
||||||
|
// }
|
||||||
|
|
||||||
genericParam->mExternType = ResolveTypeRef(externConstraintDef->mTypeRef);
|
genericParam->mExternType = ResolveTypeRef(externConstraintDef->mTypeRef);
|
||||||
}
|
|
||||||
|
|
||||||
auto autoComplete = mCompiler->GetAutoComplete();
|
auto autoComplete = mCompiler->GetAutoComplete();
|
||||||
if (autoComplete != NULL)
|
if (autoComplete != NULL)
|
||||||
|
|
|
@ -1768,7 +1768,7 @@ public:
|
||||||
BfMethodInstance* GetRawMethodInstanceAtIdx(BfTypeInstance* typeInstance, int methodIdx, const char* assertName = NULL);
|
BfMethodInstance* GetRawMethodInstanceAtIdx(BfTypeInstance* typeInstance, int methodIdx, const char* assertName = NULL);
|
||||||
BfMethodInstance* GetRawMethodInstance(BfTypeInstance* typeInstance, BfMethodDef* methodDef);
|
BfMethodInstance* GetRawMethodInstance(BfTypeInstance* typeInstance, BfMethodDef* methodDef);
|
||||||
BfMethodInstance* GetRawMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, int paramCount = -1, bool checkBase = false, bool allowMixin = false);
|
BfMethodInstance* GetRawMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, int paramCount = -1, bool checkBase = false, bool allowMixin = false);
|
||||||
BfMethodInstance* GetUnspecializedMethodInstance(BfMethodInstance* methodInstance); // Unspecialized owner type and unspecialized method type
|
BfMethodInstance* GetUnspecializedMethodInstance(BfMethodInstance* methodInstance, bool useUnspecializedType = true); // Unspecialized owner type and unspecialized method type
|
||||||
int GetGenericParamAndReturnCount(BfMethodInstance* methodInstance);
|
int GetGenericParamAndReturnCount(BfMethodInstance* methodInstance);
|
||||||
BfModule* GetSpecializedMethodModule(const SizedArrayImpl<BfProject*>& projectList);
|
BfModule* GetSpecializedMethodModule(const SizedArrayImpl<BfProject*>& projectList);
|
||||||
BfModuleMethodInstance GetMethodInstanceAtIdx(BfTypeInstance* typeInstance, int methodIdx, const char* assertName = NULL, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None);
|
BfModuleMethodInstance GetMethodInstanceAtIdx(BfTypeInstance* typeInstance, int methodIdx, const char* assertName = NULL, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None);
|
||||||
|
|
|
@ -75,6 +75,12 @@ BfGenericExtensionEntry* BfModule::BuildGenericExtensionInfo(BfTypeInstance* gen
|
||||||
genericExEntry->mGenericParams.push_back(genericParamInstance);
|
genericExEntry->mGenericParams.push_back(genericParamInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int externConstraintIdx = 0; externConstraintIdx < (int)partialTypeDef->mExternalConstraints.size(); externConstraintIdx++)
|
||||||
|
{
|
||||||
|
auto genericParamInstance = new BfGenericTypeParamInstance(partialTypeDef, externConstraintIdx + (int)partialTypeDef->mGenericParamDefs.size());
|
||||||
|
genericExEntry->mGenericParams.push_back(genericParamInstance);
|
||||||
|
}
|
||||||
|
|
||||||
for (int paramIdx = startDefGenericParamIdx; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size(); paramIdx++)
|
for (int paramIdx = startDefGenericParamIdx; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size(); paramIdx++)
|
||||||
{
|
{
|
||||||
auto genericParamInstance = genericExEntry->mGenericParams[paramIdx];
|
auto genericParamInstance = genericExEntry->mGenericParams[paramIdx];
|
||||||
|
@ -124,6 +130,12 @@ bool BfModule::BuildGenericParams(BfType* resolvedTypeRef)
|
||||||
genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(genericParamInstance);
|
genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(genericParamInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int externConstraintIdx = 0; externConstraintIdx < (int)typeDef->mExternalConstraints.size(); externConstraintIdx++)
|
||||||
|
{
|
||||||
|
auto genericParamInstance = new BfGenericTypeParamInstance(typeDef, externConstraintIdx + (int)typeDef->mGenericParamDefs.size());
|
||||||
|
genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(genericParamInstance);
|
||||||
|
}
|
||||||
|
|
||||||
if (!typeDef->mPartials.empty())
|
if (!typeDef->mPartials.empty())
|
||||||
{
|
{
|
||||||
for (auto partialTypeDef : typeDef->mPartials)
|
for (auto partialTypeDef : typeDef->mPartials)
|
||||||
|
@ -172,6 +184,28 @@ bool BfModule::BuildGenericParams(BfType* resolvedTypeRef)
|
||||||
for (int paramIdx = startDefGenericParamIdx; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size(); paramIdx++)
|
for (int paramIdx = startDefGenericParamIdx; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size(); paramIdx++)
|
||||||
{
|
{
|
||||||
auto genericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx];
|
auto genericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx];
|
||||||
|
|
||||||
|
if (paramIdx < (int)typeDef->mGenericParamDefs.size())
|
||||||
|
{
|
||||||
|
genericParamInstance->mExternType = GetGenericParamType(BfGenericParamKind_Type, paramIdx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto externConstraintDef = genericParamInstance->GetExternConstraintDef();
|
||||||
|
genericParamInstance->mExternType = ResolveTypeRef(externConstraintDef->mTypeRef);
|
||||||
|
|
||||||
|
auto autoComplete = mCompiler->GetAutoComplete();
|
||||||
|
if (autoComplete != NULL)
|
||||||
|
autoComplete->CheckTypeRef(externConstraintDef->mTypeRef, false);
|
||||||
|
|
||||||
|
if (genericParamInstance->mExternType != NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
else
|
||||||
|
genericParamInstance->mExternType = GetPrimitiveType(BfTypeCode_Var);
|
||||||
|
}
|
||||||
|
|
||||||
ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType());
|
ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType());
|
||||||
auto genericParamDef = genericParamInstance->GetGenericParamDef();
|
auto genericParamDef = genericParamInstance->GetGenericParamDef();
|
||||||
if (genericParamDef != NULL)
|
if (genericParamDef != NULL)
|
||||||
|
@ -223,20 +257,30 @@ bool BfModule::ValidateGenericConstraints(BfTypeReference* typeRef, BfTypeInstan
|
||||||
}
|
}
|
||||||
|
|
||||||
auto typeDef = genericTypeInst->mTypeDef;
|
auto typeDef = genericTypeInst->mTypeDef;
|
||||||
for (int paramIdx = 0; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size(); paramIdx++)
|
//for (int paramIdx = 0; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size(); paramIdx++)
|
||||||
|
|
||||||
|
for (int paramIdx = 0; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size(); paramIdx++)
|
||||||
{
|
{
|
||||||
auto genericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx];
|
auto genericParamInstance = genericTypeInst->mGenericTypeInfo->mGenericParams[paramIdx];
|
||||||
// Why did we remove this line? This breaks determining compatibility of one unspecialized type to another unspecialized type, called from ResolveTypeResult
|
|
||||||
//if (!genericTypeInst->mIsUnspecialized)
|
BfType* genericArg;
|
||||||
|
if (paramIdx < (int)genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.size())
|
||||||
{
|
{
|
||||||
|
genericArg = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[paramIdx];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
genericArg = genericParamInstance->mExternType;
|
||||||
|
}
|
||||||
|
|
||||||
BfError* error = NULL;
|
BfError* error = NULL;
|
||||||
if (!CheckGenericConstraints(BfGenericParamSource(genericTypeInst), genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[paramIdx], typeRef, genericParamInstance, NULL, &error))
|
if (!CheckGenericConstraints(BfGenericParamSource(genericTypeInst), genericArg, typeRef, genericParamInstance, NULL, &error))
|
||||||
{
|
{
|
||||||
genericTypeInst->mGenericTypeInfo->mHadValidateErrors = true;
|
genericTypeInst->mGenericTypeInfo->mHadValidateErrors = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10394,11 +10438,11 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
((explicitCast) && (opConstraint.mCastToken == BfToken_Explicit)))
|
((explicitCast) && (opConstraint.mCastToken == BfToken_Explicit)))
|
||||||
{
|
{
|
||||||
// If we can convert OUR fromVal to the constraint's fromVal then we may match
|
// If we can convert OUR fromVal to the constraint's fromVal then we may match
|
||||||
if (CanCast(typedVal, opConstraint.mRightType))
|
if (CanCast(typedVal, opConstraint.mRightType, BfCastFlags_NoConversionOperator))
|
||||||
{
|
{
|
||||||
// .. and we can convert the constraint's toType to OUR toType then we're good
|
// .. and we can convert the constraint's toType to OUR toType then we're good
|
||||||
auto opToVal = genericParam->mExternType;
|
auto opToVal = genericParam->mExternType;
|
||||||
if (CanCast(BfTypedValue(BfIRValue::sValueless, opToVal), toType))
|
if (CanCast(BfTypedValue(BfIRValue::sValueless, opToVal), toType, BfCastFlags_NoConversionOperator))
|
||||||
return mBfIRBuilder->GetFakeVal();
|
return mBfIRBuilder->GetFakeVal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1091,7 +1091,7 @@ public:
|
||||||
{
|
{
|
||||||
if (mGenericIdx < (int)mTypeDef->mGenericParamDefs.size())
|
if (mGenericIdx < (int)mTypeDef->mGenericParamDefs.size())
|
||||||
return mTypeDef->mGenericParamDefs[mGenericIdx];
|
return mTypeDef->mGenericParamDefs[mGenericIdx];
|
||||||
return NULL;
|
return &mTypeDef->mExternalConstraints[mGenericIdx - (int)mTypeDef->mGenericParamDefs.size()];
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual BfGenericParamDef* GetGenericParamDef() override
|
virtual BfGenericParamDef* GetGenericParamDef() override
|
||||||
|
@ -1105,14 +1105,14 @@ public:
|
||||||
{
|
{
|
||||||
if (mGenericIdx < (int)mTypeDef->mGenericParamDefs.size())
|
if (mGenericIdx < (int)mTypeDef->mGenericParamDefs.size())
|
||||||
return NULL;
|
return NULL;
|
||||||
return NULL;
|
return &mTypeDef->mExternalConstraints[mGenericIdx - (int)mTypeDef->mGenericParamDefs.size()];
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual String GetName() override
|
virtual String GetName() override
|
||||||
{
|
{
|
||||||
if (mGenericIdx < (int)mTypeDef->mGenericParamDefs.size())
|
if (mGenericIdx < (int)mTypeDef->mGenericParamDefs.size())
|
||||||
return mTypeDef->mGenericParamDefs[mGenericIdx]->mName;
|
return mTypeDef->mGenericParamDefs[mGenericIdx]->mName;
|
||||||
return "???";
|
return mTypeDef->mExternalConstraints[mGenericIdx - (int)mTypeDef->mGenericParamDefs.size()].mTypeRef->ToString();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2662,6 +2662,7 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef)
|
||||||
typeDef->mGenericParamDefs.Clear();
|
typeDef->mGenericParamDefs.Clear();
|
||||||
|
|
||||||
typeDef->mGenericParamDefs = nextTypeDef->mGenericParamDefs;
|
typeDef->mGenericParamDefs = nextTypeDef->mGenericParamDefs;
|
||||||
|
typeDef->mExternalConstraints = nextTypeDef->mExternalConstraints;
|
||||||
nextTypeDef->mGenericParamDefs.Clear();
|
nextTypeDef->mGenericParamDefs.Clear();
|
||||||
|
|
||||||
typeDef->mBaseTypes = nextTypeDef->mBaseTypes;
|
typeDef->mBaseTypes = nextTypeDef->mBaseTypes;
|
||||||
|
@ -2739,6 +2740,7 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co
|
||||||
*newGeneric = *generic;
|
*newGeneric = *generic;
|
||||||
typeDef->mGenericParamDefs.push_back(newGeneric);
|
typeDef->mGenericParamDefs.push_back(newGeneric);
|
||||||
}
|
}
|
||||||
|
typeDef->mExternalConstraints = partialTypeDef->mExternalConstraints;
|
||||||
|
|
||||||
typeDef->mBaseTypes = partialTypeDef->mBaseTypes;
|
typeDef->mBaseTypes = partialTypeDef->mBaseTypes;
|
||||||
|
|
||||||
|
@ -2756,6 +2758,9 @@ void BfSystem::AddToCompositePartial(BfPassInstance* passInstance, BfTypeDef* co
|
||||||
typeDef->mTypeCode = partialTypeDef->mTypeCode;
|
typeDef->mTypeCode = partialTypeDef->mTypeCode;
|
||||||
typeDef->mTypeDeclaration = partialTypeDef->mTypeDeclaration;
|
typeDef->mTypeDeclaration = partialTypeDef->mTypeDeclaration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& externConstraint : partialTypeDef->mExternalConstraints)
|
||||||
|
typeDef->mExternalConstraints.Add(externConstraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge attributes together
|
// Merge attributes together
|
||||||
|
|
|
@ -880,6 +880,7 @@ public:
|
||||||
Array<BfOperatorDef*> mOperators;
|
Array<BfOperatorDef*> mOperators;
|
||||||
BfMethodDef* mDtorDef;
|
BfMethodDef* mDtorDef;
|
||||||
Array<BfGenericParamDef*> mGenericParamDefs;
|
Array<BfGenericParamDef*> mGenericParamDefs;
|
||||||
|
Array<BfExternalConstraintDef> mExternalConstraints;
|
||||||
Array<BfTypeReference*> mBaseTypes;
|
Array<BfTypeReference*> mBaseTypes;
|
||||||
Array<BfTypeDef*> mNestedTypes;
|
Array<BfTypeDef*> mNestedTypes;
|
||||||
Array<BfDirectStrTypeReference*> mDirectAllocNodes;
|
Array<BfDirectStrTypeReference*> mDirectAllocNodes;
|
||||||
|
|
|
@ -176,17 +176,28 @@ namespace Tests
|
||||||
return val + val2;
|
return val + val2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T Complex<T, T2>(T val, T2 val2)
|
public static T Complex<T, T2, T3>(T val, T2 val2, T3 val3)
|
||||||
where T : operator T + T2
|
|
||||||
where T : operator -T
|
where T : operator -T
|
||||||
where T : operator implicit T2
|
where T : operator implicit T2
|
||||||
|
where T : operator T + T2
|
||||||
|
where int32 : operator T + T3
|
||||||
{
|
{
|
||||||
T conv = val2;
|
T conv = val2;
|
||||||
T result = val + val2;
|
T result = val + val2;
|
||||||
result = -result;
|
result = -result;
|
||||||
|
int32 iRes = val + val3;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct StructOp3<T, T2> where float : operator T + T2
|
||||||
|
{
|
||||||
|
public float Use(T lhs, T2 rhs)
|
||||||
|
{
|
||||||
|
float f = lhs + rhs;
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
@ -212,7 +223,7 @@ namespace Tests
|
||||||
float val = Op((int32)100, (int16)23);
|
float val = Op((int32)100, (int16)23);
|
||||||
Test.Assert(val == 123);
|
Test.Assert(val == 123);
|
||||||
|
|
||||||
int32 i32res = Complex((int32)100, (int16)23);
|
int32 i32res = Complex((int32)100, (int16)23, (int8)4);
|
||||||
Test.Assert(i32res == -123);
|
Test.Assert(i32res == -123);
|
||||||
|
|
||||||
StructOp<StructA, StructB> sOp;
|
StructOp<StructA, StructB> sOp;
|
||||||
|
@ -231,6 +242,10 @@ namespace Tests
|
||||||
Test.Assert(rsc == rsc2);
|
Test.Assert(rsc == rsc2);
|
||||||
Test.Assert(rsc !== rsc2);
|
Test.Assert(rsc !== rsc2);
|
||||||
|
|
||||||
|
StructOp3<int16, int32> so3 = .();
|
||||||
|
float f = so3.Use(1, 2);
|
||||||
|
Test.Assert(f == 3);
|
||||||
|
|
||||||
/*let oai = OuterOp<float>.InnerOp<int>.Op(1.0f, 100);
|
/*let oai = OuterOp<float>.InnerOp<int>.Op(1.0f, 100);
|
||||||
Test.Assert(oai == 101.0f);
|
Test.Assert(oai == 101.0f);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue