mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Added support for generic tuples
This commit is contained in:
parent
a186421ba8
commit
6fe9c78ada
13 changed files with 403 additions and 158 deletions
|
@ -893,7 +893,7 @@ void BfAutoComplete::AddEnumTypeMembers(BfTypeInstance* typeInst, const StringIm
|
||||||
bool hasPayload = false;
|
bool hasPayload = false;
|
||||||
if ((fieldInst.mIsEnumPayloadCase) && (fieldInst.mResolvedType->IsTuple()))
|
if ((fieldInst.mIsEnumPayloadCase) && (fieldInst.mResolvedType->IsTuple()))
|
||||||
{
|
{
|
||||||
auto payloadType = (BfTupleType*)fieldInst.mResolvedType;
|
auto payloadType = (BfTypeInstance*)fieldInst.mResolvedType;
|
||||||
if (!payloadType->mFieldInstances.empty())
|
if (!payloadType->mFieldInstances.empty())
|
||||||
hasPayload = true;
|
hasPayload = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2217,7 +2217,7 @@ void BfContext::GenerateModuleName_Type(BfType* type, String& name)
|
||||||
|
|
||||||
if (type->IsTuple())
|
if (type->IsTuple())
|
||||||
{
|
{
|
||||||
auto tupleType = (BfTupleType*)type;
|
auto tupleType = (BfTypeInstance*)type;
|
||||||
name += "TUPLE_";
|
name += "TUPLE_";
|
||||||
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -371,6 +371,7 @@ public:
|
||||||
BfAllocPool<BfUnknownSizedArrayType> mUnknownSizedArrayTypePool;
|
BfAllocPool<BfUnknownSizedArrayType> mUnknownSizedArrayTypePool;
|
||||||
BfAllocPool<BfBoxedType> mBoxedTypePool;
|
BfAllocPool<BfBoxedType> mBoxedTypePool;
|
||||||
BfAllocPool<BfTupleType> mTupleTypePool;
|
BfAllocPool<BfTupleType> mTupleTypePool;
|
||||||
|
BfAllocPool<BfGenericTupleType> mGenericTupleTypePool;
|
||||||
BfAllocPool<BfRefType> mRefTypePool;
|
BfAllocPool<BfRefType> mRefTypePool;
|
||||||
BfAllocPool<BfModifiedTypeType> mRetTypeTypePool;
|
BfAllocPool<BfModifiedTypeType> mRetTypeTypePool;
|
||||||
BfAllocPool<BfGenericTypeInstance> mGenericTypeInstancePool;
|
BfAllocPool<BfGenericTypeInstance> mGenericTypeInstancePool;
|
||||||
|
|
|
@ -6270,7 +6270,7 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst
|
||||||
}
|
}
|
||||||
|
|
||||||
BF_ASSERT(fieldInstance->mResolvedType->IsTuple());
|
BF_ASSERT(fieldInstance->mResolvedType->IsTuple());
|
||||||
auto tupleType = (BfTupleType*)fieldInstance->mResolvedType;
|
auto tupleType = (BfTypeInstance*)fieldInstance->mResolvedType;
|
||||||
mModule->mBfIRBuilder->PopulateType(tupleType);
|
mModule->mBfIRBuilder->PopulateType(tupleType);
|
||||||
|
|
||||||
BfIRValue fieldPtr;
|
BfIRValue fieldPtr;
|
||||||
|
@ -15290,14 +15290,14 @@ void BfExprEvaluator::PopulateDeferrredTupleAssignData(BfTupleExpression* tupleE
|
||||||
fieldNames.push_back(requestedName->mNameNode->ToString());
|
fieldNames.push_back(requestedName->mNameNode->ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTupleType* tupleType = mModule->CreateTupleType(fieldTypes, fieldNames);
|
BfTypeInstance* tupleType = mModule->CreateTupleType(fieldTypes, fieldNames);
|
||||||
deferredTupleAssignData.mTupleType = tupleType;
|
deferredTupleAssignData.mTupleType = tupleType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfExprEvaluator::AssignDeferrredTupleAssignData(BfAssignmentExpression* assignExpr, DeferredTupleAssignData& deferredTupleAssignData, BfTypedValue rightValue)
|
void BfExprEvaluator::AssignDeferrredTupleAssignData(BfAssignmentExpression* assignExpr, DeferredTupleAssignData& deferredTupleAssignData, BfTypedValue rightValue)
|
||||||
{
|
{
|
||||||
BF_ASSERT(rightValue.mType->IsTuple());
|
BF_ASSERT(rightValue.mType->IsTuple());
|
||||||
auto tupleType = (BfTupleType*)rightValue.mType;
|
auto tupleType = (BfTypeInstance*)rightValue.mType;
|
||||||
for (int valueIdx = 0; valueIdx < (int)deferredTupleAssignData.mChildren.size(); valueIdx++)
|
for (int valueIdx = 0; valueIdx < (int)deferredTupleAssignData.mChildren.size(); valueIdx++)
|
||||||
{
|
{
|
||||||
auto& child = deferredTupleAssignData.mChildren[valueIdx];
|
auto& child = deferredTupleAssignData.mChildren[valueIdx];
|
||||||
|
@ -15338,7 +15338,7 @@ void BfExprEvaluator::DoTupleAssignment(BfAssignmentExpression* assignExpr)
|
||||||
|
|
||||||
DeferredTupleAssignData deferredTupleAssignData;
|
DeferredTupleAssignData deferredTupleAssignData;
|
||||||
PopulateDeferrredTupleAssignData(tupleExpr, deferredTupleAssignData);
|
PopulateDeferrredTupleAssignData(tupleExpr, deferredTupleAssignData);
|
||||||
BfTupleType* tupleType = deferredTupleAssignData.mTupleType;
|
BfTypeInstance* tupleType = deferredTupleAssignData.mTupleType;
|
||||||
|
|
||||||
BfTypedValue rightValue;
|
BfTypedValue rightValue;
|
||||||
if (assignExpr->mRight != NULL)
|
if (assignExpr->mRight != NULL)
|
||||||
|
@ -16137,11 +16137,11 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken
|
||||||
|
|
||||||
void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr)
|
void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr)
|
||||||
{
|
{
|
||||||
BfTupleType* tupleType = NULL;
|
BfTypeInstance* tupleType = NULL;
|
||||||
bool hadFullMatch = false;
|
bool hadFullMatch = false;
|
||||||
if ((mExpectingType != NULL) && (mExpectingType->IsTuple()))
|
if ((mExpectingType != NULL) && (mExpectingType->IsTuple()))
|
||||||
{
|
{
|
||||||
tupleType = (BfTupleType*)mExpectingType;
|
tupleType = (BfTypeInstance*)mExpectingType;
|
||||||
hadFullMatch = tupleType->mFieldInstances.size() == tupleExpr->mValues.size();
|
hadFullMatch = tupleType->mFieldInstances.size() == tupleExpr->mValues.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18803,8 +18803,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
bool areEquivalentTuples = false;
|
bool areEquivalentTuples = false;
|
||||||
if ((leftValue.mType->IsTuple()) && (rightValue.mType->IsTuple()))
|
if ((leftValue.mType->IsTuple()) && (rightValue.mType->IsTuple()))
|
||||||
{
|
{
|
||||||
auto leftTupleType = (BfTupleType*)leftValue.mType;
|
auto leftTupleType = (BfTypeInstance*)leftValue.mType;
|
||||||
auto rightTupleType = (BfTupleType*)rightValue.mType;
|
auto rightTupleType = (BfTypeInstance*)rightValue.mType;
|
||||||
|
|
||||||
// We only do this for tuples, because we would allow an implicit struct
|
// We only do this for tuples, because we would allow an implicit struct
|
||||||
// truncation if we allow it for all structs, which would result in only
|
// truncation if we allow it for all structs, which would result in only
|
||||||
|
|
|
@ -265,7 +265,7 @@ struct DeferredTupleAssignData
|
||||||
};
|
};
|
||||||
|
|
||||||
Array<Entry> mChildren;
|
Array<Entry> mChildren;
|
||||||
BfTupleType* mTupleType;
|
BfTypeInstance* mTupleType;
|
||||||
|
|
||||||
~DeferredTupleAssignData();
|
~DeferredTupleAssignData();
|
||||||
};
|
};
|
||||||
|
|
|
@ -1922,22 +1922,26 @@ BfIRMDNode BfIRBuilder::CreateNamespaceScope(BfType* type, BfIRMDNode fileDIScop
|
||||||
|
|
||||||
String BfIRBuilder::GetDebugTypeName(BfTypeInstance* typeInstance, bool includeOuterTypeName)
|
String BfIRBuilder::GetDebugTypeName(BfTypeInstance* typeInstance, bool includeOuterTypeName)
|
||||||
{
|
{
|
||||||
|
BfTypeNameFlags typeNameFlags = BfTypeNameFlag_AddGlobalContainerName;
|
||||||
|
if (!typeInstance->IsUnspecializedTypeVariation())
|
||||||
|
typeNameFlags = (BfTypeNameFlags)(typeNameFlags | BfTypeNameFlag_ResolveGenericParamNames);
|
||||||
|
|
||||||
String typeName;
|
String typeName;
|
||||||
if (typeInstance->IsBoxed())
|
if (typeInstance->IsBoxed())
|
||||||
{
|
{
|
||||||
BfBoxedType* boxedType = (BfBoxedType*)typeInstance;
|
BfBoxedType* boxedType = (BfBoxedType*)typeInstance;
|
||||||
typeName = mModule->TypeToString(boxedType->mElementType, (BfTypeNameFlags)(BfTypeNameFlag_ResolveGenericParamNames | BfTypeNameFlag_AddGlobalContainerName));
|
typeName = mModule->TypeToString(boxedType->mElementType, (BfTypeNameFlags)(typeNameFlags));
|
||||||
if (boxedType->IsBoxedStructPtr())
|
if (boxedType->IsBoxedStructPtr())
|
||||||
typeName += "*";
|
typeName += "*";
|
||||||
typeName = "Box<" + typeName + ">";
|
typeName = "Box<" + typeName + ">";
|
||||||
}
|
}
|
||||||
else if (includeOuterTypeName)
|
else if (includeOuterTypeName)
|
||||||
{
|
{
|
||||||
typeName = mModule->TypeToString(typeInstance, (BfTypeNameFlags)(BfTypeNameFlag_ResolveGenericParamNames | BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_AddGlobalContainerName));
|
typeName = mModule->TypeToString(typeInstance, (BfTypeNameFlags)(typeNameFlags | BfTypeNameFlag_OmitNamespace));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
typeName = mModule->TypeToString(typeInstance, (BfTypeNameFlags)(BfTypeNameFlag_ResolveGenericParamNames | BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_AddGlobalContainerName | BfTypeNameFlag_OmitOuterType));
|
typeName = mModule->TypeToString(typeInstance, (BfTypeNameFlags)(typeNameFlags | BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_OmitOuterType));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < (int)typeName.length(); i++)
|
for (int i = 0; i < (int)typeName.length(); i++)
|
||||||
|
|
|
@ -280,7 +280,7 @@ void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name
|
||||||
|
|
||||||
if (typeInst->IsTuple())
|
if (typeInst->IsTuple())
|
||||||
{
|
{
|
||||||
auto tupleType = (BfTupleType*)typeInst;
|
auto tupleType = (BfTypeInstance*)typeInst;
|
||||||
name += "N7__TUPLEI";
|
name += "N7__TUPLEI";
|
||||||
mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for '__TUPLE'
|
mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for '__TUPLE'
|
||||||
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
||||||
|
@ -1131,7 +1131,7 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl&
|
||||||
|
|
||||||
if (newNameSub.mTypeInst->IsTuple())
|
if (newNameSub.mTypeInst->IsTuple())
|
||||||
{
|
{
|
||||||
auto tupleType = (BfTupleType*)newNameSub.mType;
|
auto tupleType = (BfTypeInstance*)newNameSub.mType;
|
||||||
name += "?$__TUPLE";
|
name += "?$__TUPLE";
|
||||||
SizedArray<BfType*, 8> typeVec;
|
SizedArray<BfType*, 8> typeVec;
|
||||||
for (auto& fieldInst : tupleType->mFieldInstances)
|
for (auto& fieldInst : tupleType->mFieldInstances)
|
||||||
|
|
|
@ -1623,8 +1623,8 @@ public:
|
||||||
BfPointerType* CreatePointerType(BfTypeReference* typeRef);
|
BfPointerType* CreatePointerType(BfTypeReference* typeRef);
|
||||||
BfConstExprValueType* CreateConstExprValueType(const BfTypedValue& typedValue);
|
BfConstExprValueType* CreateConstExprValueType(const BfTypedValue& typedValue);
|
||||||
BfBoxedType* CreateBoxedType(BfType* resolvedTypeRef);
|
BfBoxedType* CreateBoxedType(BfType* resolvedTypeRef);
|
||||||
BfTupleType* CreateTupleType(const BfTypeVector& fieldTypes, const Array<String>& fieldNames);
|
BfTypeInstance* CreateTupleType(const BfTypeVector& fieldTypes, const Array<String>& fieldNames);
|
||||||
BfTupleType* SantizeTupleType(BfTupleType* tupleType);
|
BfTypeInstance* SantizeTupleType(BfTypeInstance* tupleType);
|
||||||
BfRefType* CreateRefType(BfType* resolvedTypeRef, BfRefType::RefKind refKind = BfRefType::RefKind_Ref);
|
BfRefType* CreateRefType(BfType* resolvedTypeRef, BfRefType::RefKind refKind = BfRefType::RefKind_Ref);
|
||||||
BfModifiedTypeType* CreateModifiedTypeType(BfType* resolvedTypeRef, BfToken modifiedKind);
|
BfModifiedTypeType* CreateModifiedTypeType(BfType* resolvedTypeRef, BfToken modifiedKind);
|
||||||
BfConcreteInterfaceType* CreateConcreteInterfaceType(BfTypeInstance* interfaceType);
|
BfConcreteInterfaceType* CreateConcreteInterfaceType(BfTypeInstance* interfaceType);
|
||||||
|
|
|
@ -404,12 +404,12 @@ bool BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType)
|
||||||
|
|
||||||
if (resolvedTypeRef->IsTuple())
|
if (resolvedTypeRef->IsTuple())
|
||||||
{
|
{
|
||||||
auto tupleType = (BfTupleType*)resolvedTypeRef;
|
auto tupleType = (BfTypeInstance*)resolvedTypeRef;
|
||||||
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
||||||
{
|
{
|
||||||
auto fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx];
|
auto fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx];
|
||||||
if (fieldInstance->GetResolvedType()->IsUnspecializedType())
|
// if (fieldInstance->GetResolvedType()->IsUnspecializedType())
|
||||||
tupleType->mHasUnspecializedMembers = true;
|
// tupleType->mHasUnspecializedMembers = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -881,11 +881,6 @@ bool BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
|
||||||
else
|
else
|
||||||
resolvedTypeRef->mTypeId = mCompiler->mCurTypeId++;
|
resolvedTypeRef->mTypeId = mCompiler->mCurTypeId++;
|
||||||
|
|
||||||
if ((resolvedTypeRef->mTypeId == 2599) && (!mCompiler->mIsResolveOnly))
|
|
||||||
{
|
|
||||||
NOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (resolvedTypeRef->mTypeId >= (int)mContext->mTypes.size())
|
while (resolvedTypeRef->mTypeId >= (int)mContext->mTypes.size())
|
||||||
mContext->mTypes.Add(NULL);
|
mContext->mTypes.Add(NULL);
|
||||||
mContext->mTypes[resolvedTypeRef->mTypeId] = resolvedTypeRef;
|
mContext->mTypes[resolvedTypeRef->mTypeId] = resolvedTypeRef;
|
||||||
|
@ -5052,37 +5047,44 @@ BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef)
|
||||||
return (BfBoxedType*)resolvedBoxedType;
|
return (BfBoxedType*)resolvedBoxedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTupleType* BfModule::CreateTupleType(const BfTypeVector& fieldTypes, const Array<String>& fieldNames)
|
BfTypeInstance* BfModule::CreateTupleType(const BfTypeVector& fieldTypes, const Array<String>& fieldNames)
|
||||||
{
|
{
|
||||||
auto tupleType = mContext->mTupleTypePool.Get();
|
auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mValueTypeTypeDef);
|
||||||
|
|
||||||
|
BfTypeInstance* tupleType = NULL;
|
||||||
|
|
||||||
|
auto actualTupleType = mContext->mTupleTypePool.Get();
|
||||||
|
actualTupleType->Init(baseType->mTypeDef->mProject, baseType);
|
||||||
|
|
||||||
|
for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++)
|
||||||
|
{
|
||||||
|
String fieldName;
|
||||||
|
if (fieldIdx < (int)fieldNames.size())
|
||||||
|
fieldName = fieldNames[fieldIdx];
|
||||||
|
if (fieldName.empty())
|
||||||
|
fieldName = StrFormat("%d", fieldIdx);
|
||||||
|
BfFieldDef* fieldDef = actualTupleType->AddField(fieldName);
|
||||||
|
}
|
||||||
|
tupleType = actualTupleType;
|
||||||
|
|
||||||
tupleType->mContext = mContext;
|
tupleType->mContext = mContext;
|
||||||
tupleType->mFieldInstances.Resize(fieldTypes.size());
|
tupleType->mFieldInstances.Resize(fieldTypes.size());
|
||||||
|
|
||||||
auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mValueTypeTypeDef);
|
|
||||||
tupleType->Init(baseType->mTypeDef->mProject, baseType);
|
|
||||||
|
|
||||||
for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++)
|
for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++)
|
||||||
{
|
{
|
||||||
BfFieldInstance* fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx];
|
BfFieldInstance* fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx];
|
||||||
fieldInstance->mFieldIdx = fieldIdx;
|
fieldInstance->mFieldIdx = fieldIdx;
|
||||||
fieldInstance->SetResolvedType(fieldTypes[fieldIdx]);
|
fieldInstance->SetResolvedType(fieldTypes[fieldIdx]);
|
||||||
fieldInstance->mOwner = tupleType;
|
fieldInstance->mOwner = tupleType;
|
||||||
|
|
||||||
String fieldName;
|
|
||||||
if (fieldIdx < (int)fieldNames.size())
|
|
||||||
fieldName = fieldNames[fieldIdx];
|
|
||||||
if (fieldName.empty())
|
|
||||||
fieldName = StrFormat("%d", fieldIdx);
|
|
||||||
BfFieldDef* fieldDef = tupleType->AddField(fieldName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resolvedTupleType = ResolveType(tupleType);
|
auto resolvedTupleType = ResolveType(tupleType);
|
||||||
if (resolvedTupleType != tupleType)
|
if (resolvedTupleType != tupleType)
|
||||||
mContext->mTupleTypePool.GiveBack(tupleType);
|
mContext->mTupleTypePool.GiveBack((BfTupleType*)tupleType);
|
||||||
|
|
||||||
return (BfTupleType*)resolvedTupleType;
|
return (BfTupleType*)resolvedTupleType;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTupleType * BfModule::SantizeTupleType(BfTupleType* tupleType)
|
BfTypeInstance* BfModule::SantizeTupleType(BfTypeInstance* tupleType)
|
||||||
{
|
{
|
||||||
bool needsSanitize = false;
|
bool needsSanitize = false;
|
||||||
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
||||||
|
@ -5774,29 +5776,130 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
|
||||||
|
|
||||||
if (unspecializedType->IsTuple())
|
if (unspecializedType->IsTuple())
|
||||||
{
|
{
|
||||||
auto tupleType = (BfTupleType*)unspecializedType;
|
bool wantGeneric = false;
|
||||||
Array<String> names;
|
bool isUnspecialized = false;
|
||||||
|
|
||||||
BfTypeVector genericArgs;
|
auto unspecializedTupleType = (BfTypeInstance*)unspecializedType;
|
||||||
|
auto unspecializedGenericTupleType = unspecializedTupleType->ToGenericTypeInstance();
|
||||||
|
Array<String> fieldNames;
|
||||||
|
BfTypeVector fieldTypes;
|
||||||
bool hadChange = false;
|
bool hadChange = false;
|
||||||
|
|
||||||
for (auto& fieldInstance : tupleType->mFieldInstances)
|
for (auto& fieldInstance : unspecializedTupleType->mFieldInstances)
|
||||||
{
|
{
|
||||||
names.push_back(fieldInstance.GetFieldDef()->mName);
|
fieldNames.push_back(fieldInstance.GetFieldDef()->mName);
|
||||||
auto origGenericArg = fieldInstance.mResolvedType;
|
auto origGenericArg = fieldInstance.mResolvedType;
|
||||||
auto newGenericArg = ResolveGenericType(origGenericArg, typeGenericArguments, methodGenericArguments, allowFail);
|
auto newGenericArg = ResolveGenericType(origGenericArg, typeGenericArguments, methodGenericArguments, allowFail);
|
||||||
if (newGenericArg == NULL)
|
if (newGenericArg == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (newGenericArg->IsVar())
|
if (newGenericArg->IsVar())
|
||||||
return newGenericArg;
|
return newGenericArg;
|
||||||
|
|
||||||
|
if (newGenericArg->IsGenericParam())
|
||||||
|
wantGeneric = true;
|
||||||
|
if (newGenericArg->IsUnspecializedType())
|
||||||
|
isUnspecialized = true;
|
||||||
|
|
||||||
if (newGenericArg != origGenericArg)
|
if (newGenericArg != origGenericArg)
|
||||||
hadChange = true;
|
hadChange = true;
|
||||||
genericArgs.push_back(newGenericArg);
|
fieldTypes.push_back(newGenericArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hadChange)
|
if (!hadChange)
|
||||||
return unspecializedType;
|
return unspecializedType;
|
||||||
|
|
||||||
return CreateTupleType(genericArgs, names);
|
if (unspecializedGenericTupleType == NULL)
|
||||||
|
wantGeneric = false;
|
||||||
|
|
||||||
|
auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mValueTypeTypeDef);
|
||||||
|
|
||||||
|
BfTypeInstance* tupleType = NULL;
|
||||||
|
if (wantGeneric)
|
||||||
|
{
|
||||||
|
Array<BfType*> genericArgs;
|
||||||
|
for (int genericArgIdx = 0; genericArgIdx < (int)unspecializedGenericTupleType->mTypeGenericArguments.size(); genericArgIdx++)
|
||||||
|
{
|
||||||
|
BfType* resolvedArg = unspecializedGenericTupleType->mTypeGenericArguments[genericArgIdx];
|
||||||
|
if (resolvedArg->IsUnspecializedType())
|
||||||
|
{
|
||||||
|
resolvedArg = ResolveGenericType(resolvedArg, typeGenericArguments, methodGenericArguments, allowFail);
|
||||||
|
if (resolvedArg == NULL)
|
||||||
|
return NULL;
|
||||||
|
if (resolvedArg->IsVar())
|
||||||
|
return resolvedArg;
|
||||||
|
}
|
||||||
|
genericArgs.push_back(resolvedArg);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto actualTupleType = mContext->mGenericTupleTypePool.Get();
|
||||||
|
actualTupleType->mIsUnspecialized = false;
|
||||||
|
actualTupleType->mIsUnspecializedVariation = false;
|
||||||
|
actualTupleType->mTypeGenericArguments = genericArgs;
|
||||||
|
for (int genericArgIdx = 0; genericArgIdx < (int)unspecializedGenericTupleType->mTypeGenericArguments.size(); genericArgIdx++)
|
||||||
|
{
|
||||||
|
auto typeGenericArg = genericArgs[genericArgIdx];
|
||||||
|
if ((typeGenericArg->IsGenericParam()) || (typeGenericArg->IsUnspecializedType()))
|
||||||
|
actualTupleType->mIsUnspecialized = true;
|
||||||
|
actualTupleType->mGenericParams.push_back(unspecializedGenericTupleType->mGenericParams[genericArgIdx]->AddRef());
|
||||||
|
}
|
||||||
|
CheckUnspecializedGenericType(actualTupleType, BfPopulateType_Identity);
|
||||||
|
|
||||||
|
actualTupleType->Init(baseType->mTypeDef->mProject, baseType);
|
||||||
|
|
||||||
|
for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++)
|
||||||
|
{
|
||||||
|
String fieldName = fieldNames[fieldIdx];
|
||||||
|
BfFieldDef* fieldDef = actualTupleType->AddField(fieldName);
|
||||||
|
}
|
||||||
|
|
||||||
|
tupleType = actualTupleType;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto actualTupleType = new BfTupleType();
|
||||||
|
actualTupleType->mIsUnspecializedType = isUnspecialized;
|
||||||
|
actualTupleType->mIsUnspecializedTypeVariation = isUnspecialized;
|
||||||
|
|
||||||
|
actualTupleType->Init(baseType->mTypeDef->mProject, baseType);
|
||||||
|
|
||||||
|
for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++)
|
||||||
|
{
|
||||||
|
String fieldName = fieldNames[fieldIdx];
|
||||||
|
BfFieldDef* fieldDef = actualTupleType->AddField(fieldName);
|
||||||
|
}
|
||||||
|
|
||||||
|
tupleType = actualTupleType;
|
||||||
|
}
|
||||||
|
|
||||||
|
tupleType->mFieldInstances.Resize(fieldTypes.size());
|
||||||
|
for (int fieldIdx = 0; fieldIdx < (int)fieldTypes.size(); fieldIdx++)
|
||||||
|
{
|
||||||
|
BfFieldInstance* fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx];
|
||||||
|
fieldInstance->mFieldIdx = fieldIdx;
|
||||||
|
fieldInstance->SetResolvedType(fieldTypes[fieldIdx]);
|
||||||
|
fieldInstance->mOwner = tupleType;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool failed = false;
|
||||||
|
BfType* resolvedType = NULL;
|
||||||
|
if (!failed)
|
||||||
|
resolvedType = ResolveType(tupleType, BfPopulateType_Identity);
|
||||||
|
|
||||||
|
if (resolvedType != tupleType)
|
||||||
|
{
|
||||||
|
if (tupleType->IsGenericTypeInstance())
|
||||||
|
{
|
||||||
|
auto genericTupleType = (BfGenericTupleType*)tupleType;
|
||||||
|
for (auto genericParam : genericTupleType->mGenericParams)
|
||||||
|
genericParam->Release();
|
||||||
|
genericTupleType->mGenericParams.Clear();
|
||||||
|
mContext->mGenericTupleTypePool.GiveBack(genericTupleType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mContext->mTupleTypePool.GiveBack((BfTupleType*)tupleType);
|
||||||
|
}
|
||||||
|
BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
|
||||||
|
return resolvedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((unspecializedType->IsDelegateFromTypeRef()) || (unspecializedType->IsFunctionFromTypeRef()))
|
if ((unspecializedType->IsDelegateFromTypeRef()) || (unspecializedType->IsFunctionFromTypeRef()))
|
||||||
|
@ -5919,8 +6022,6 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
|
||||||
methodDef->mReturnTypeRef = directTypeRef;
|
methodDef->mReturnTypeRef = directTypeRef;
|
||||||
delegateInfo->mReturnType = returnType;
|
delegateInfo->mReturnType = returnType;
|
||||||
|
|
||||||
AddDependency(directTypeRef->mType, baseDelegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
|
|
||||||
|
|
||||||
BfMethodDef* unspecializedInvokeMethodDef = unspecializedDelegateType->mTypeDef->GetMethodByName("Invoke");
|
BfMethodDef* unspecializedInvokeMethodDef = unspecializedDelegateType->mTypeDef->GetMethodByName("Invoke");
|
||||||
|
|
||||||
int paramIdx = 0;
|
int paramIdx = 0;
|
||||||
|
@ -5945,7 +6046,6 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
|
||||||
paramIdx++;
|
paramIdx++;
|
||||||
|
|
||||||
delegateInfo->mParams.Add(paramType);
|
delegateInfo->mParams.Add(paramType);
|
||||||
AddDependency(paramType, baseDelegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typeDef->mMethods.push_back(methodDef);
|
typeDef->mMethods.push_back(methodDef);
|
||||||
|
@ -5962,7 +6062,13 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
|
||||||
BfType* resolvedType = NULL;
|
BfType* resolvedType = NULL;
|
||||||
if (!failed)
|
if (!failed)
|
||||||
resolvedType = ResolveType(delegateType, BfPopulateType_Identity);
|
resolvedType = ResolveType(delegateType, BfPopulateType_Identity);
|
||||||
if (resolvedType != delegateType)
|
if (resolvedType == delegateType)
|
||||||
|
{
|
||||||
|
AddDependency(directTypeRef->mType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
|
||||||
|
for (auto paramType : paramTypes)
|
||||||
|
AddDependency(paramType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (delegateType->IsGenericTypeInstance())
|
if (delegateType->IsGenericTypeInstance())
|
||||||
{
|
{
|
||||||
|
@ -5977,7 +6083,6 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty
|
||||||
}
|
}
|
||||||
BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
|
BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType());
|
||||||
return resolvedType;
|
return resolvedType;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unspecializedType->IsGenericTypeInstance())
|
if (unspecializedType->IsGenericTypeInstance())
|
||||||
|
@ -6034,8 +6139,16 @@ BfType* BfModule::ResolveType(BfType* lookupType, BfPopulateType populateType)
|
||||||
|
|
||||||
if (lookupType->IsTuple())
|
if (lookupType->IsTuple())
|
||||||
{
|
{
|
||||||
auto tupleType = (BfTupleType*)lookupType;
|
if (lookupType->IsGenericTypeInstance())
|
||||||
tupleType->Finish();
|
{
|
||||||
|
auto tupleType = (BfGenericTupleType*)lookupType;
|
||||||
|
tupleType->Finish();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto tupleType = (BfTupleType*)lookupType;
|
||||||
|
tupleType->Finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resolvedEntry->mValue = lookupType;
|
resolvedEntry->mValue = lookupType;
|
||||||
|
@ -6303,7 +6416,7 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
|
||||||
{
|
{
|
||||||
// Add the fields from the tuple as references since those inner fields types would have been explicitly stated, so we need
|
// Add the fields from the tuple as references since those inner fields types would have been explicitly stated, so we need
|
||||||
// to make sure to record the current type instance as a referring type. This mostly matters for symbol renaming.
|
// to make sure to record the current type instance as a referring type. This mostly matters for symbol renaming.
|
||||||
BfTupleType* payloadTupleType = (BfTupleType*)resolvedTypeRef;
|
BfTypeInstance* payloadTupleType = (BfTypeInstance*)resolvedTypeRef;
|
||||||
for (auto& payloadFieldInst : payloadTupleType->mFieldInstances)
|
for (auto& payloadFieldInst : payloadTupleType->mFieldInstances)
|
||||||
{
|
{
|
||||||
auto payloadFieldType = payloadFieldInst.mResolvedType;
|
auto payloadFieldType = payloadFieldInst.mResolvedType;
|
||||||
|
@ -7904,6 +8017,11 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
|
mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
|
||||||
return ResolveGenericType(type, &genericArgs, NULL);
|
return ResolveGenericType(type, &genericArgs, NULL);
|
||||||
}
|
}
|
||||||
|
else if ((type != NULL) && (type->IsTuple()))
|
||||||
|
{
|
||||||
|
mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
|
||||||
|
return ResolveGenericType(type, &genericArgs, NULL);
|
||||||
|
}
|
||||||
else if ((typeDef != NULL) && (typeDef->mTypeCode == BfTypeCode_TypeAlias))
|
else if ((typeDef != NULL) && (typeDef->mTypeCode == BfTypeCode_TypeAlias))
|
||||||
{
|
{
|
||||||
auto typeAliasType = new BfGenericTypeAliasType();
|
auto typeAliasType = new BfGenericTypeAliasType();
|
||||||
|
@ -7997,6 +8115,9 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
Array<BfType*> types;
|
Array<BfType*> types;
|
||||||
Array<String> names;
|
Array<String> names;
|
||||||
|
|
||||||
|
bool wantGeneric = false;
|
||||||
|
bool isUnspecialized = false;
|
||||||
|
|
||||||
for (int fieldIdx = 0; fieldIdx < (int)tupleTypeRef->mFieldTypes.size(); fieldIdx++)
|
for (int fieldIdx = 0; fieldIdx < (int)tupleTypeRef->mFieldTypes.size(); fieldIdx++)
|
||||||
{
|
{
|
||||||
BfTypeReference* typeRef = tupleTypeRef->mFieldTypes[fieldIdx];
|
BfTypeReference* typeRef = tupleTypeRef->mFieldTypes[fieldIdx];
|
||||||
|
@ -8017,31 +8138,67 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
else
|
else
|
||||||
fieldName = StrFormat("%d", fieldIdx);
|
fieldName = StrFormat("%d", fieldIdx);
|
||||||
|
|
||||||
|
if (type->IsGenericParam())
|
||||||
|
wantGeneric = true;
|
||||||
|
if (type->IsUnspecializedType())
|
||||||
|
isUnspecialized = true;
|
||||||
|
|
||||||
String typeName = TypeToString(type);
|
String typeName = TypeToString(type);
|
||||||
types.push_back(type);
|
types.push_back(type);
|
||||||
names.push_back(fieldName);
|
names.push_back(fieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mValueTypeTypeDef, BfPopulateType_Identity);
|
auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mValueTypeTypeDef, BfPopulateType_Identity);
|
||||||
BfTupleType* tupleType = new BfTupleType();
|
BfTypeInstance* tupleType = NULL;
|
||||||
//TODO: Add to correct project
|
if (wantGeneric)
|
||||||
tupleType->Init(baseType->mTypeDef->mProject, baseType);
|
{
|
||||||
|
BfGenericTupleType* actualTupleType = new BfGenericTupleType();
|
||||||
|
actualTupleType->Init(baseType->mTypeDef->mProject, baseType);
|
||||||
|
for (int fieldIdx = 0; fieldIdx < (int)types.size(); fieldIdx++)
|
||||||
|
{
|
||||||
|
BfFieldDef* fieldDef = actualTupleType->AddField(names[fieldIdx]);
|
||||||
|
fieldDef->mProtection = (names[fieldIdx][0] == '_') ? BfProtection_Private : BfProtection_Public;
|
||||||
|
}
|
||||||
|
actualTupleType->Finish();
|
||||||
|
|
||||||
|
if (mCurTypeInstance->IsGenericTypeInstance())
|
||||||
|
{
|
||||||
|
auto parentTypeInstance = (BfGenericTypeInstance*)mCurTypeInstance;
|
||||||
|
for (int i = 0; i < parentTypeInstance->mGenericParams.size(); i++)
|
||||||
|
{
|
||||||
|
actualTupleType->mGenericParams.push_back(parentTypeInstance->mGenericParams[i]->AddRef());
|
||||||
|
actualTupleType->mTypeGenericArguments.push_back(parentTypeInstance->mTypeGenericArguments[i]);
|
||||||
|
auto typeGenericArg = actualTupleType->mTypeGenericArguments[i];
|
||||||
|
actualTupleType->mIsUnspecialized |= typeGenericArg->IsGenericParam() || typeGenericArg->IsUnspecializedType();
|
||||||
|
}
|
||||||
|
CheckUnspecializedGenericType(actualTupleType, populateType);
|
||||||
|
}
|
||||||
|
tupleType = actualTupleType;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BfTupleType* actualTupleType = new BfTupleType();
|
||||||
|
actualTupleType->Init(baseType->mTypeDef->mProject, baseType);
|
||||||
|
for (int fieldIdx = 0; fieldIdx < (int)types.size(); fieldIdx++)
|
||||||
|
{
|
||||||
|
BfFieldDef* fieldDef = actualTupleType->AddField(names[fieldIdx]);
|
||||||
|
fieldDef->mProtection = (names[fieldIdx][0] == '_') ? BfProtection_Private : BfProtection_Public;
|
||||||
|
}
|
||||||
|
actualTupleType->Finish();
|
||||||
|
tupleType = actualTupleType;
|
||||||
|
actualTupleType->mIsUnspecializedType = isUnspecialized;
|
||||||
|
actualTupleType->mIsUnspecializedTypeVariation = isUnspecialized;
|
||||||
|
}
|
||||||
|
|
||||||
tupleType->mFieldInstances.Resize(types.size());
|
tupleType->mFieldInstances.Resize(types.size());
|
||||||
|
|
||||||
for (int fieldIdx = 0; fieldIdx < (int)types.size(); fieldIdx++)
|
for (int fieldIdx = 0; fieldIdx < (int)types.size(); fieldIdx++)
|
||||||
{
|
{
|
||||||
BfFieldDef* fieldDef = tupleType->AddField(names[fieldIdx]);
|
|
||||||
fieldDef->mProtection = (names[fieldIdx][0] == '_') ? BfProtection_Private : BfProtection_Public;
|
|
||||||
|
|
||||||
BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
|
BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
|
||||||
fieldInstance->mFieldIdx = fieldIdx;
|
fieldInstance->mFieldIdx = fieldIdx;
|
||||||
fieldInstance->SetResolvedType(types[fieldIdx]);
|
fieldInstance->SetResolvedType(types[fieldIdx]);
|
||||||
fieldInstance->mOwner = tupleType;
|
fieldInstance->mOwner = tupleType;
|
||||||
}
|
}
|
||||||
|
|
||||||
tupleType->Finish();
|
|
||||||
|
|
||||||
resolvedEntry->mValue = tupleType;
|
resolvedEntry->mValue = tupleType;
|
||||||
BF_ASSERT(BfResolvedTypeSet::Hash(tupleType, &lookupCtx) == resolvedEntry->mHash);
|
BF_ASSERT(BfResolvedTypeSet::Hash(tupleType, &lookupCtx) == resolvedEntry->mHash);
|
||||||
populateModule->InitType(tupleType, populateType);
|
populateModule->InitType(tupleType, populateType);
|
||||||
|
@ -8218,8 +8375,6 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
methodDef->mReturnTypeRef = directTypeRef;
|
methodDef->mReturnTypeRef = directTypeRef;
|
||||||
delegateInfo->mReturnType = returnType;
|
delegateInfo->mReturnType = returnType;
|
||||||
|
|
||||||
AddDependency(directTypeRef->mType, baseDelegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
|
|
||||||
|
|
||||||
auto hashVal = mContext->mResolvedTypes.Hash(typeRef, &lookupCtx);
|
auto hashVal = mContext->mResolvedTypes.Hash(typeRef, &lookupCtx);
|
||||||
|
|
||||||
for (int paramIdx = 0; paramIdx < (int)paramTypes.size(); paramIdx++)
|
for (int paramIdx = 0; paramIdx < (int)paramTypes.size(); paramIdx++)
|
||||||
|
@ -8248,7 +8403,6 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
methodDef->mParams.push_back(paramDef);
|
methodDef->mParams.push_back(paramDef);
|
||||||
|
|
||||||
delegateInfo->mParams.Add(paramType);
|
delegateInfo->mParams.Add(paramType);
|
||||||
AddDependency(paramType, baseDelegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typeDef->mMethods.push_back(methodDef);
|
typeDef->mMethods.push_back(methodDef);
|
||||||
|
@ -8264,6 +8418,10 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
populateModule->InitType(delegateType, populateType);
|
populateModule->InitType(delegateType, populateType);
|
||||||
resolvedEntry->mValue = delegateType;
|
resolvedEntry->mValue = delegateType;
|
||||||
|
|
||||||
|
AddDependency(directTypeRef->mType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
|
||||||
|
for (auto paramType : paramTypes)
|
||||||
|
AddDependency(paramType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue);
|
||||||
|
|
||||||
// #ifdef _DEBUG
|
// #ifdef _DEBUG
|
||||||
// if (BfResolvedTypeSet::Hash(delegateType, &lookupCtx) != resolvedEntry->mHash)
|
// if (BfResolvedTypeSet::Hash(delegateType, &lookupCtx) != resolvedEntry->mHash)
|
||||||
// {
|
// {
|
||||||
|
@ -9127,8 +9285,8 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
// Tuple -> Tuple
|
// Tuple -> Tuple
|
||||||
if ((typedVal.mType->IsTuple()) && (toType->IsTuple()))
|
if ((typedVal.mType->IsTuple()) && (toType->IsTuple()))
|
||||||
{
|
{
|
||||||
auto fromTupleType = (BfTupleType*)typedVal.mType;
|
auto fromTupleType = (BfTypeInstance*)typedVal.mType;
|
||||||
auto toTupleType = (BfTupleType*)toType;
|
auto toTupleType = (BfTypeInstance*)toType;
|
||||||
if (fromTupleType->mFieldInstances.size() == toTupleType->mFieldInstances.size())
|
if (fromTupleType->mFieldInstances.size() == toTupleType->mFieldInstances.size())
|
||||||
{
|
{
|
||||||
typedVal = LoadValue(typedVal);
|
typedVal = LoadValue(typedVal);
|
||||||
|
@ -9964,8 +10122,8 @@ BfTypedValue BfModule::Cast(BfAstNode* srcNode, const BfTypedValue& typedVal, Bf
|
||||||
//auto loadedVal = LoadValue(typedVal);
|
//auto loadedVal = LoadValue(typedVal);
|
||||||
PopulateType(toType);
|
PopulateType(toType);
|
||||||
|
|
||||||
auto fromTupleType = (BfTupleType*)typedVal.mType;
|
auto fromTupleType = (BfTypeInstance*)typedVal.mType;
|
||||||
auto toTupleType = (BfTupleType*)toType;
|
auto toTupleType = (BfTypeInstance*)toType;
|
||||||
if (fromTupleType == toTupleType)
|
if (fromTupleType == toTupleType)
|
||||||
return typedVal;
|
return typedVal;
|
||||||
|
|
||||||
|
@ -10572,7 +10730,7 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF
|
||||||
}
|
}
|
||||||
else if (resolvedType->IsTuple())
|
else if (resolvedType->IsTuple())
|
||||||
{
|
{
|
||||||
BfTupleType* tupleType = (BfTupleType*)resolvedType;
|
BfTypeInstance* tupleType = (BfTypeInstance*)resolvedType;
|
||||||
|
|
||||||
str += "(";
|
str += "(";
|
||||||
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
||||||
|
@ -10582,7 +10740,8 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF
|
||||||
|
|
||||||
BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
|
BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
|
||||||
BfFieldDef* fieldDef = fieldInstance->GetFieldDef();
|
BfFieldDef* fieldDef = fieldInstance->GetFieldDef();
|
||||||
DoTypeToString(str, fieldInstance->GetResolvedType(), (BfTypeNameFlags)(typeNameFlags & ~(BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_OmitOuterType)), genericMethodNameOverrides);
|
BfTypeNameFlags innerFlags = (BfTypeNameFlags)(typeNameFlags & ~(BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_OmitOuterType));
|
||||||
|
DoTypeToString(str, fieldInstance->GetResolvedType(), innerFlags, genericMethodNameOverrides);
|
||||||
|
|
||||||
char c = fieldDef->mName[0];
|
char c = fieldDef->mName[0];
|
||||||
if ((c < '0') || (c > '9'))
|
if ((c < '0') || (c > '9'))
|
||||||
|
|
|
@ -1479,7 +1479,7 @@ bool BfTypeInstance::GetResultInfo(BfType*& valueType, int& okTagId)
|
||||||
|
|
||||||
if ((fieldInstance.mIsEnumPayloadCase) && (fieldInstance.GetFieldDef()->mName == "Ok") && (fieldInstance.mResolvedType->IsTuple()))
|
if ((fieldInstance.mIsEnumPayloadCase) && (fieldInstance.GetFieldDef()->mName == "Ok") && (fieldInstance.mResolvedType->IsTuple()))
|
||||||
{
|
{
|
||||||
auto tupleType = (BfTupleType*)fieldInstance.mResolvedType;
|
auto tupleType = (BfTypeInstance*)fieldInstance.mResolvedType;
|
||||||
if (tupleType->mFieldInstances.size() == 1)
|
if (tupleType->mFieldInstances.size() == 1)
|
||||||
{
|
{
|
||||||
valueType = tupleType->mFieldInstances[0].mResolvedType;
|
valueType = tupleType->mFieldInstances[0].mResolvedType;
|
||||||
|
@ -1923,7 +1923,8 @@ BfTupleType::BfTupleType()
|
||||||
mCreatedTypeDef = false;
|
mCreatedTypeDef = false;
|
||||||
mSource = NULL;
|
mSource = NULL;
|
||||||
mTypeDef = NULL;
|
mTypeDef = NULL;
|
||||||
mHasUnspecializedMembers = false;
|
mIsUnspecializedType = false;
|
||||||
|
mIsUnspecializedTypeVariation = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTupleType::~BfTupleType()
|
BfTupleType::~BfTupleType()
|
||||||
|
@ -1971,8 +1972,62 @@ void BfTupleType::Finish()
|
||||||
BfDefBuilder bfDefBuilder(bfSystem);
|
BfDefBuilder bfDefBuilder(bfSystem);
|
||||||
bfDefBuilder.mCurTypeDef = mTypeDef;
|
bfDefBuilder.mCurTypeDef = mTypeDef;
|
||||||
bfDefBuilder.FinishTypeDef(true);
|
bfDefBuilder.FinishTypeDef(true);
|
||||||
|
}
|
||||||
|
|
||||||
mHasUnspecializedMembers = false;
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
BfGenericTupleType::BfGenericTupleType()
|
||||||
|
{
|
||||||
|
mCreatedTypeDef = false;
|
||||||
|
mSource = NULL;
|
||||||
|
mTypeDef = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BfGenericTupleType::~BfGenericTupleType()
|
||||||
|
{
|
||||||
|
if (mCreatedTypeDef)
|
||||||
|
delete mTypeDef;
|
||||||
|
delete mSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BfGenericTupleType::Init(BfProject* bfProject, BfTypeInstance* valueTypeInstance)
|
||||||
|
{
|
||||||
|
auto srcTypeDef = valueTypeInstance->mTypeDef;
|
||||||
|
auto system = valueTypeInstance->mModule->mSystem;
|
||||||
|
|
||||||
|
if (mTypeDef == NULL)
|
||||||
|
mTypeDef = new BfTypeDef();
|
||||||
|
for (auto field : mTypeDef->mFields)
|
||||||
|
delete field;
|
||||||
|
mTypeDef->mFields.Clear();
|
||||||
|
mTypeDef->mSystem = system;
|
||||||
|
mTypeDef->mProject = bfProject;
|
||||||
|
mTypeDef->mTypeCode = srcTypeDef->mTypeCode;
|
||||||
|
mTypeDef->mName = system->mEmptyAtom;
|
||||||
|
mTypeDef->mSystem = system;
|
||||||
|
|
||||||
|
mTypeDef->mHash = srcTypeDef->mHash;
|
||||||
|
mTypeDef->mSignatureHash = srcTypeDef->mSignatureHash;
|
||||||
|
mTypeDef->mTypeCode = BfTypeCode_Struct;
|
||||||
|
|
||||||
|
mCreatedTypeDef = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
BfFieldDef* BfGenericTupleType::AddField(const StringImpl& name)
|
||||||
|
{
|
||||||
|
return BfDefBuilder::AddField(mTypeDef, NULL, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BfGenericTupleType::Finish()
|
||||||
|
{
|
||||||
|
auto bfSystem = mTypeDef->mSystem;
|
||||||
|
mSource = new BfSource(bfSystem);
|
||||||
|
mTypeDef->mSource = mSource;
|
||||||
|
mTypeDef->mSource->mRefCount++;
|
||||||
|
|
||||||
|
BfDefBuilder bfDefBuilder(bfSystem);
|
||||||
|
bfDefBuilder.mCurTypeDef = mTypeDef;
|
||||||
|
bfDefBuilder.FinishTypeDef(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -2196,17 +2251,11 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
|
||||||
return false;
|
return false;
|
||||||
hashVal = ((hashVal ^ (int)closureType->mClosureHash.mLow) << 5) - hashVal;
|
hashVal = ((hashVal ^ (int)closureType->mClosureHash.mLow) << 5) - hashVal;
|
||||||
}
|
}
|
||||||
else if (type->IsGenericTypeInstance())
|
|
||||||
{
|
|
||||||
BfGenericTypeInstance* genericType = (BfGenericTypeInstance*)type;
|
|
||||||
for (auto genericArg : genericType->mTypeGenericArguments)
|
|
||||||
hashVal = ((hashVal ^ (Hash(genericArg, ctx))) << 5) - hashVal;
|
|
||||||
}
|
|
||||||
else if (type->IsTuple())
|
else if (type->IsTuple())
|
||||||
{
|
{
|
||||||
hashVal = HASH_VAL_TUPLE;
|
hashVal = HASH_VAL_TUPLE;
|
||||||
|
|
||||||
BfTupleType* tupleType = (BfTupleType*)type;
|
BfTypeInstance* tupleType = (BfTypeInstance*)type;
|
||||||
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
||||||
{
|
{
|
||||||
BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
|
BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
|
||||||
|
@ -2230,6 +2279,12 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
|
||||||
hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal;
|
hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (type->IsGenericTypeInstance())
|
||||||
|
{
|
||||||
|
BfGenericTypeInstance* genericType = (BfGenericTypeInstance*)type;
|
||||||
|
for (auto genericArg : genericType->mTypeGenericArguments)
|
||||||
|
hashVal = ((hashVal ^ (Hash(genericArg, ctx))) << 5) - hashVal;
|
||||||
|
}
|
||||||
return hashVal;
|
return hashVal;
|
||||||
}
|
}
|
||||||
else if (type->IsPrimitiveType())
|
else if (type->IsPrimitiveType())
|
||||||
|
@ -2832,30 +2887,13 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lhs->IsGenericTypeInstance())
|
|
||||||
{
|
|
||||||
if (!rhs->IsGenericTypeInstance())
|
|
||||||
return false;
|
|
||||||
BfGenericTypeInstance* lhsGenericType = (BfGenericTypeInstance*)lhs;
|
|
||||||
BfGenericTypeInstance* rhsGenericType = (BfGenericTypeInstance*)rhs;
|
|
||||||
if (lhsGenericType->mTypeGenericArguments.size() != rhsGenericType->mTypeGenericArguments.size())
|
|
||||||
return false;
|
|
||||||
if (lhsGenericType->mTypeDef != rhsGenericType->mTypeDef)
|
|
||||||
return false;
|
|
||||||
for (int i = 0; i < (int)lhsGenericType->mTypeGenericArguments.size(); i++)
|
|
||||||
{
|
|
||||||
if (!Equals(lhsGenericType->mTypeGenericArguments[i], rhsGenericType->mTypeGenericArguments[i], ctx))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lhs->IsTuple())
|
if (lhs->IsTuple())
|
||||||
{
|
{
|
||||||
if (!rhs->IsTuple())
|
if (!rhs->IsTuple())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
BfTupleType* lhsTupleType = (BfTupleType*)lhs;
|
BfTypeInstance* lhsTupleType = (BfTypeInstance*)lhs;
|
||||||
BfTupleType* rhsTupleType = (BfTupleType*)rhs;
|
BfTypeInstance* rhsTupleType = (BfTypeInstance*)rhs;
|
||||||
if (lhsTupleType->mFieldInstances.size() != rhsTupleType->mFieldInstances.size())
|
if (lhsTupleType->mFieldInstances.size() != rhsTupleType->mFieldInstances.size())
|
||||||
return false;
|
return false;
|
||||||
for (int fieldIdx = 0; fieldIdx < (int)lhsTupleType->mFieldInstances.size(); fieldIdx++)
|
for (int fieldIdx = 0; fieldIdx < (int)lhsTupleType->mFieldInstances.size(); fieldIdx++)
|
||||||
|
@ -2883,6 +2921,23 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lhs->IsGenericTypeInstance())
|
||||||
|
{
|
||||||
|
if (!rhs->IsGenericTypeInstance())
|
||||||
|
return false;
|
||||||
|
BfGenericTypeInstance* lhsGenericType = (BfGenericTypeInstance*)lhs;
|
||||||
|
BfGenericTypeInstance* rhsGenericType = (BfGenericTypeInstance*)rhs;
|
||||||
|
if (lhsGenericType->mTypeGenericArguments.size() != rhsGenericType->mTypeGenericArguments.size())
|
||||||
|
return false;
|
||||||
|
if (lhsGenericType->mTypeDef != rhsGenericType->mTypeDef)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < (int)lhsGenericType->mTypeGenericArguments.size(); i++)
|
||||||
|
{
|
||||||
|
if (!Equals(lhsGenericType->mTypeGenericArguments[i], rhsGenericType->mTypeGenericArguments[i], ctx))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return lhsInst->mTypeDef == rhsInst->mTypeDef;
|
return lhsInst->mTypeDef == rhsInst->mTypeDef;
|
||||||
}
|
}
|
||||||
else if (lhs->IsPrimitiveType())
|
else if (lhs->IsPrimitiveType())
|
||||||
|
@ -3138,7 +3193,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rhs->IsNamedTypeReference())
|
if ((rhs->IsNamedTypeReference()) || (rhs->IsA<BfGenericInstanceTypeRef>()))
|
||||||
{
|
{
|
||||||
if ((ctx->mRootTypeRef != rhs) || (ctx->mRootTypeDef == NULL))
|
if ((ctx->mRootTypeRef != rhs) || (ctx->mRootTypeDef == NULL))
|
||||||
{
|
{
|
||||||
|
@ -3214,26 +3269,13 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
|
||||||
{
|
{
|
||||||
BfTypeInstance* lhsInst = (BfTypeInstance*) lhs;
|
BfTypeInstance* lhsInst = (BfTypeInstance*) lhs;
|
||||||
|
|
||||||
if (lhs->IsGenericTypeInstance())
|
|
||||||
{
|
|
||||||
BfType* rhsType = NULL;
|
|
||||||
auto rhsTypeDef = ctx->ResolveToTypeDef(rhs, &rhsType);
|
|
||||||
if (rhsTypeDef == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (rhsType != NULL)
|
|
||||||
return lhs == rhsType;
|
|
||||||
|
|
||||||
BfGenericTypeInstance* lhsGenericType = (BfGenericTypeInstance*) lhs;
|
|
||||||
return GenericTypeEquals(lhsGenericType, &lhsGenericType->mTypeGenericArguments, rhs, rhsTypeDef, ctx);
|
|
||||||
}
|
|
||||||
if (lhs->IsTuple())
|
if (lhs->IsTuple())
|
||||||
{
|
{
|
||||||
if (!rhs->IsA<BfTupleTypeRef>())
|
if (!rhs->IsA<BfTupleTypeRef>())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
BfTupleTypeRef* rhsTupleTypeRef = (BfTupleTypeRef*)rhs;
|
BfTupleTypeRef* rhsTupleTypeRef = (BfTupleTypeRef*)rhs;
|
||||||
BfTupleType* lhsTupleType = (BfTupleType*)lhs;
|
BfTypeInstance* lhsTupleType = (BfTypeInstance*)lhs;
|
||||||
|
|
||||||
if (lhsTupleType->mFieldInstances.size() != rhsTupleTypeRef->mFieldTypes.size())
|
if (lhsTupleType->mFieldInstances.size() != rhsTupleTypeRef->mFieldTypes.size())
|
||||||
return false;
|
return false;
|
||||||
|
@ -3267,6 +3309,19 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (lhs->IsGenericTypeInstance())
|
||||||
|
{
|
||||||
|
BfType* rhsType = NULL;
|
||||||
|
auto rhsTypeDef = ctx->ResolveToTypeDef(rhs, &rhsType);
|
||||||
|
if (rhsTypeDef == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (rhsType != NULL)
|
||||||
|
return lhs == rhsType;
|
||||||
|
|
||||||
|
BfGenericTypeInstance* lhsGenericType = (BfGenericTypeInstance*) lhs;
|
||||||
|
return GenericTypeEquals(lhsGenericType, &lhsGenericType->mTypeGenericArguments, rhs, rhsTypeDef, ctx);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (rhs->IsA<BfElementedTypeRef>())
|
if (rhs->IsA<BfElementedTypeRef>())
|
||||||
|
|
|
@ -2056,29 +2056,16 @@ public:
|
||||||
virtual bool IsFunctionFromTypeRef() override { return !mTypeDef->mIsDelegate; }
|
virtual bool IsFunctionFromTypeRef() override { return !mTypeDef->mIsDelegate; }
|
||||||
|
|
||||||
virtual BfDelegateInfo* GetDelegateInfo() override { return &mDelegateInfo; }
|
virtual BfDelegateInfo* GetDelegateInfo() override { return &mDelegateInfo; }
|
||||||
//virtual bool IsReified() override { return mIsReified; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*class BfFunctionType : public BfTypeInstance
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BfType* mReturnType;
|
|
||||||
Array<BfType*> mParamTypes;
|
|
||||||
Array<String> mParamNames;
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual bool IsOnDemand() override { return true; }
|
|
||||||
virtual bool IsFunction() override { return true; }
|
|
||||||
virtual bool IsFunctionFromTypeRef() override { return true; }
|
|
||||||
};*/
|
|
||||||
|
|
||||||
class BfTupleType : public BfTypeInstance
|
class BfTupleType : public BfTypeInstance
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool mCreatedTypeDef;
|
bool mCreatedTypeDef;
|
||||||
String mNameAdd;
|
String mNameAdd;
|
||||||
BfSource* mSource;
|
BfSource* mSource;
|
||||||
bool mHasUnspecializedMembers;
|
bool mIsUnspecializedType;
|
||||||
|
bool mIsUnspecializedTypeVariation;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BfTupleType();
|
BfTupleType();
|
||||||
|
@ -2091,8 +2078,27 @@ public:
|
||||||
virtual bool IsOnDemand() override { return true; }
|
virtual bool IsOnDemand() override { return true; }
|
||||||
virtual bool IsTuple() override { return true; }
|
virtual bool IsTuple() override { return true; }
|
||||||
|
|
||||||
virtual bool IsUnspecializedType() override { return mHasUnspecializedMembers; }
|
virtual bool IsUnspecializedType() override { return mIsUnspecializedType; }
|
||||||
virtual bool IsUnspecializedTypeVariation() override { return mHasUnspecializedMembers; }
|
virtual bool IsUnspecializedTypeVariation() override { return mIsUnspecializedTypeVariation; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class BfGenericTupleType : public BfGenericTypeInstance
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool mCreatedTypeDef;
|
||||||
|
String mNameAdd;
|
||||||
|
BfSource* mSource;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BfGenericTupleType();
|
||||||
|
~BfGenericTupleType();
|
||||||
|
|
||||||
|
void Init(BfProject* bfProject, BfTypeInstance* valueTypeInstance);
|
||||||
|
BfFieldDef* AddField(const StringImpl& name);
|
||||||
|
void Finish();
|
||||||
|
|
||||||
|
virtual bool IsOnDemand() override { return true; }
|
||||||
|
virtual bool IsTuple() override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class BfConcreteInterfaceType : public BfType
|
class BfConcreteInterfaceType : public BfType
|
||||||
|
|
|
@ -1957,9 +1957,9 @@ void BfModule::CheckTupleVariableDeclaration(BfTupleExpression* tupleExpr, BfTyp
|
||||||
if (initType == NULL)
|
if (initType == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BfTupleType* initTupleType = NULL;
|
BfTypeInstance* initTupleType = NULL;
|
||||||
if ((initType != NULL) && (initType->IsTuple()))
|
if ((initType != NULL) && (initType->IsTuple()))
|
||||||
initTupleType = (BfTupleType*)initType;
|
initTupleType = (BfTypeInstance*)initType;
|
||||||
|
|
||||||
if (initTupleType != NULL)
|
if (initTupleType != NULL)
|
||||||
{
|
{
|
||||||
|
@ -1987,9 +1987,9 @@ void BfModule::CheckTupleVariableDeclaration(BfTupleExpression* tupleExpr, BfTyp
|
||||||
|
|
||||||
void BfModule::HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl, BfTupleExpression* tupleExpr, BfTypedValue initTupleValue, bool isReadOnly, bool isConst, bool forceAddr, BfIRBlock* declBlock)
|
void BfModule::HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl, BfTupleExpression* tupleExpr, BfTypedValue initTupleValue, bool isReadOnly, bool isConst, bool forceAddr, BfIRBlock* declBlock)
|
||||||
{
|
{
|
||||||
BfTupleType* initTupleType = NULL;
|
BfTypeInstance* initTupleType = NULL;
|
||||||
if ((initTupleValue) && (initTupleValue.mType->IsTuple()))
|
if ((initTupleValue) && (initTupleValue.mType->IsTuple()))
|
||||||
initTupleType = (BfTupleType*)initTupleValue.mType;
|
initTupleType = (BfTypeInstance*)initTupleValue.mType;
|
||||||
|
|
||||||
CheckTupleVariableDeclaration(tupleExpr, initTupleValue.mType);
|
CheckTupleVariableDeclaration(tupleExpr, initTupleValue.mType);
|
||||||
|
|
||||||
|
@ -2425,7 +2425,7 @@ BfTypedValue BfModule::TryCaseTupleMatch(BfTypedValue tupleVal, BfTupleExpressio
|
||||||
if (!tupleVal.mType->IsTuple())
|
if (!tupleVal.mType->IsTuple())
|
||||||
return BfTypedValue();
|
return BfTypedValue();
|
||||||
|
|
||||||
auto tupleType = (BfTupleType*)tupleVal.mType;
|
auto tupleType = (BfTypeInstance*)tupleVal.mType;
|
||||||
|
|
||||||
BfAstNode* tooFewRef = tupleExpr->mCloseParen;
|
BfAstNode* tooFewRef = tupleExpr->mCloseParen;
|
||||||
if ((tooFewRef == NULL) && (!tupleExpr->mCommas.IsEmpty()))
|
if ((tooFewRef == NULL) && (!tupleExpr->mCommas.IsEmpty()))
|
||||||
|
@ -2672,7 +2672,7 @@ BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVa
|
||||||
}
|
}
|
||||||
|
|
||||||
BF_ASSERT(fieldInstance->mResolvedType->IsTuple());
|
BF_ASSERT(fieldInstance->mResolvedType->IsTuple());
|
||||||
auto tupleType = (BfTupleType*)fieldInstance->mResolvedType;
|
auto tupleType = (BfTypeInstance*)fieldInstance->mResolvedType;
|
||||||
PopulateType(tupleType);
|
PopulateType(tupleType);
|
||||||
mBfIRBuilder->PopulateType(tupleType);
|
mBfIRBuilder->PopulateType(tupleType);
|
||||||
|
|
||||||
|
@ -6039,7 +6039,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
|
|
||||||
if (varType->IsTuple())
|
if (varType->IsTuple())
|
||||||
{
|
{
|
||||||
auto tupleType = (BfTupleType*)varType;
|
auto tupleType = (BfTypeInstance*)varType;
|
||||||
|
|
||||||
for (int idx = 0; idx < BF_MIN((int)tupleExpr->mValues.size(), (int)tupleType->mFieldInstances.size()); idx++)
|
for (int idx = 0; idx < BF_MIN((int)tupleExpr->mValues.size(), (int)tupleType->mFieldInstances.size()); idx++)
|
||||||
{
|
{
|
||||||
|
@ -6127,7 +6127,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
if (!tupleBinds.IsEmpty())
|
if (!tupleBinds.IsEmpty())
|
||||||
{
|
{
|
||||||
BF_ASSERT(varType->IsTuple());
|
BF_ASSERT(varType->IsTuple());
|
||||||
auto tupleType = (BfTupleType*)varType;
|
auto tupleType = (BfTypeInstance*)varType;
|
||||||
|
|
||||||
// Tuple binds
|
// Tuple binds
|
||||||
needsValCopy = false;
|
needsValCopy = false;
|
||||||
|
|
|
@ -16,9 +16,23 @@ namespace Tests
|
||||||
public typealias AliasA3 = delegate T();
|
public typealias AliasA3 = delegate T();
|
||||||
public typealias AliasA4<T2> = delegate T(T2 val);
|
public typealias AliasA4<T2> = delegate T(T2 val);
|
||||||
|
|
||||||
|
public typealias AliasA5 = (int, T);
|
||||||
|
public typealias AliasA6<T2> = (T, T2);
|
||||||
|
|
||||||
public delegate T Zag();
|
public delegate T Zag();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Test<T>()
|
||||||
|
{
|
||||||
|
T LocalA(int16 a)
|
||||||
|
{
|
||||||
|
return default(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassA<T>.AliasA6<float> t0 = (default(T), 1.2f);
|
||||||
|
ClassA<T>.AliasA4<int16> dlg0 = scope => LocalA;
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
@ -33,6 +47,12 @@ namespace Tests
|
||||||
|
|
||||||
delegate double(char8) dlg3 = default;
|
delegate double(char8) dlg3 = default;
|
||||||
ClassA<double>.AliasA4<char8> dlg4 = dlg3;
|
ClassA<double>.AliasA4<char8> dlg4 = dlg3;
|
||||||
|
|
||||||
|
var t0 = (123, 1.2f);
|
||||||
|
ClassA<float>.AliasA5 t1 = t0;
|
||||||
|
|
||||||
|
var t2 = (1.2f, 3.4);
|
||||||
|
ClassA<float>.AliasA6<double> v3 = t2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue