From 6fe9c78adab7dbea94e06fc037601ad7d63ec5c9 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Thu, 4 Jun 2020 15:02:46 -0700 Subject: [PATCH] Added support for generic tuples --- IDEHelper/Compiler/BfAutoComplete.cpp | 2 +- IDEHelper/Compiler/BfContext.cpp | 2 +- IDEHelper/Compiler/BfContext.h | 1 + IDEHelper/Compiler/BfExprEvaluator.cpp | 16 +- IDEHelper/Compiler/BfExprEvaluator.h | 2 +- IDEHelper/Compiler/BfIRBuilder.cpp | 12 +- IDEHelper/Compiler/BfMangler.cpp | 4 +- IDEHelper/Compiler/BfModule.h | 4 +- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 279 ++++++++++++++++----- IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 157 ++++++++---- IDEHelper/Compiler/BfResolvedTypeUtils.h | 46 ++-- IDEHelper/Compiler/BfStmtEvaluator.cpp | 16 +- IDEHelper/Tests/src/Aliases.bf | 20 ++ 13 files changed, 403 insertions(+), 158 deletions(-) diff --git a/IDEHelper/Compiler/BfAutoComplete.cpp b/IDEHelper/Compiler/BfAutoComplete.cpp index c4304ee3..708ca99b 100644 --- a/IDEHelper/Compiler/BfAutoComplete.cpp +++ b/IDEHelper/Compiler/BfAutoComplete.cpp @@ -893,7 +893,7 @@ void BfAutoComplete::AddEnumTypeMembers(BfTypeInstance* typeInst, const StringIm bool hasPayload = false; if ((fieldInst.mIsEnumPayloadCase) && (fieldInst.mResolvedType->IsTuple())) { - auto payloadType = (BfTupleType*)fieldInst.mResolvedType; + auto payloadType = (BfTypeInstance*)fieldInst.mResolvedType; if (!payloadType->mFieldInstances.empty()) hasPayload = true; } diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index 1c1a184f..5076e203 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -2217,7 +2217,7 @@ void BfContext::GenerateModuleName_Type(BfType* type, String& name) if (type->IsTuple()) { - auto tupleType = (BfTupleType*)type; + auto tupleType = (BfTypeInstance*)type; name += "TUPLE_"; for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++) { diff --git a/IDEHelper/Compiler/BfContext.h b/IDEHelper/Compiler/BfContext.h index 7b9bc332..9ac05539 100644 --- a/IDEHelper/Compiler/BfContext.h +++ b/IDEHelper/Compiler/BfContext.h @@ -371,6 +371,7 @@ public: BfAllocPool mUnknownSizedArrayTypePool; BfAllocPool mBoxedTypePool; BfAllocPool mTupleTypePool; + BfAllocPool mGenericTupleTypePool; BfAllocPool mRefTypePool; BfAllocPool mRetTypeTypePool; BfAllocPool mGenericTypeInstancePool; diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index ceab1e28..6680fa96 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -6270,7 +6270,7 @@ BfTypedValue BfExprEvaluator::CheckEnumCreation(BfAstNode* targetSrc, BfTypeInst } BF_ASSERT(fieldInstance->mResolvedType->IsTuple()); - auto tupleType = (BfTupleType*)fieldInstance->mResolvedType; + auto tupleType = (BfTypeInstance*)fieldInstance->mResolvedType; mModule->mBfIRBuilder->PopulateType(tupleType); BfIRValue fieldPtr; @@ -15290,14 +15290,14 @@ void BfExprEvaluator::PopulateDeferrredTupleAssignData(BfTupleExpression* tupleE fieldNames.push_back(requestedName->mNameNode->ToString()); } - BfTupleType* tupleType = mModule->CreateTupleType(fieldTypes, fieldNames); + BfTypeInstance* tupleType = mModule->CreateTupleType(fieldTypes, fieldNames); deferredTupleAssignData.mTupleType = tupleType; } void BfExprEvaluator::AssignDeferrredTupleAssignData(BfAssignmentExpression* assignExpr, DeferredTupleAssignData& deferredTupleAssignData, BfTypedValue rightValue) { 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++) { auto& child = deferredTupleAssignData.mChildren[valueIdx]; @@ -15338,7 +15338,7 @@ void BfExprEvaluator::DoTupleAssignment(BfAssignmentExpression* assignExpr) DeferredTupleAssignData deferredTupleAssignData; PopulateDeferrredTupleAssignData(tupleExpr, deferredTupleAssignData); - BfTupleType* tupleType = deferredTupleAssignData.mTupleType; + BfTypeInstance* tupleType = deferredTupleAssignData.mTupleType; BfTypedValue rightValue; if (assignExpr->mRight != NULL) @@ -16137,11 +16137,11 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr) { - BfTupleType* tupleType = NULL; + BfTypeInstance* tupleType = NULL; bool hadFullMatch = false; if ((mExpectingType != NULL) && (mExpectingType->IsTuple())) { - tupleType = (BfTupleType*)mExpectingType; + tupleType = (BfTypeInstance*)mExpectingType; hadFullMatch = tupleType->mFieldInstances.size() == tupleExpr->mValues.size(); } @@ -18803,8 +18803,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod bool areEquivalentTuples = false; if ((leftValue.mType->IsTuple()) && (rightValue.mType->IsTuple())) { - auto leftTupleType = (BfTupleType*)leftValue.mType; - auto rightTupleType = (BfTupleType*)rightValue.mType; + auto leftTupleType = (BfTypeInstance*)leftValue.mType; + auto rightTupleType = (BfTypeInstance*)rightValue.mType; // 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 diff --git a/IDEHelper/Compiler/BfExprEvaluator.h b/IDEHelper/Compiler/BfExprEvaluator.h index c6d27a9f..fa78bcb3 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.h +++ b/IDEHelper/Compiler/BfExprEvaluator.h @@ -265,7 +265,7 @@ struct DeferredTupleAssignData }; Array mChildren; - BfTupleType* mTupleType; + BfTypeInstance* mTupleType; ~DeferredTupleAssignData(); }; diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index 1ec0c3a3..65f9bc9e 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -1922,22 +1922,26 @@ BfIRMDNode BfIRBuilder::CreateNamespaceScope(BfType* type, BfIRMDNode fileDIScop String BfIRBuilder::GetDebugTypeName(BfTypeInstance* typeInstance, bool includeOuterTypeName) { + BfTypeNameFlags typeNameFlags = BfTypeNameFlag_AddGlobalContainerName; + if (!typeInstance->IsUnspecializedTypeVariation()) + typeNameFlags = (BfTypeNameFlags)(typeNameFlags | BfTypeNameFlag_ResolveGenericParamNames); + String typeName; if (typeInstance->IsBoxed()) { BfBoxedType* boxedType = (BfBoxedType*)typeInstance; - typeName = mModule->TypeToString(boxedType->mElementType, (BfTypeNameFlags)(BfTypeNameFlag_ResolveGenericParamNames | BfTypeNameFlag_AddGlobalContainerName)); + typeName = mModule->TypeToString(boxedType->mElementType, (BfTypeNameFlags)(typeNameFlags)); if (boxedType->IsBoxedStructPtr()) typeName += "*"; typeName = "Box<" + typeName + ">"; } else if (includeOuterTypeName) - { - typeName = mModule->TypeToString(typeInstance, (BfTypeNameFlags)(BfTypeNameFlag_ResolveGenericParamNames | BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_AddGlobalContainerName)); + { + typeName = mModule->TypeToString(typeInstance, (BfTypeNameFlags)(typeNameFlags | BfTypeNameFlag_OmitNamespace)); } 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++) diff --git a/IDEHelper/Compiler/BfMangler.cpp b/IDEHelper/Compiler/BfMangler.cpp index 6039c789..3d1db843 100644 --- a/IDEHelper/Compiler/BfMangler.cpp +++ b/IDEHelper/Compiler/BfMangler.cpp @@ -280,7 +280,7 @@ void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name if (typeInst->IsTuple()) { - auto tupleType = (BfTupleType*)typeInst; + auto tupleType = (BfTypeInstance*)typeInst; name += "N7__TUPLEI"; mangleContext.mSubstituteList.push_back(NameSubstitute(BfGNUMangler::NameSubstitute::Kind_None, NULL)); // Insert entry for '__TUPLE' for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++) @@ -1131,7 +1131,7 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& if (newNameSub.mTypeInst->IsTuple()) { - auto tupleType = (BfTupleType*)newNameSub.mType; + auto tupleType = (BfTypeInstance*)newNameSub.mType; name += "?$__TUPLE"; SizedArray typeVec; for (auto& fieldInst : tupleType->mFieldInstances) diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 3a534889..d93279b0 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1623,8 +1623,8 @@ public: BfPointerType* CreatePointerType(BfTypeReference* typeRef); BfConstExprValueType* CreateConstExprValueType(const BfTypedValue& typedValue); BfBoxedType* CreateBoxedType(BfType* resolvedTypeRef); - BfTupleType* CreateTupleType(const BfTypeVector& fieldTypes, const Array& fieldNames); - BfTupleType* SantizeTupleType(BfTupleType* tupleType); + BfTypeInstance* CreateTupleType(const BfTypeVector& fieldTypes, const Array& fieldNames); + BfTypeInstance* SantizeTupleType(BfTypeInstance* tupleType); BfRefType* CreateRefType(BfType* resolvedTypeRef, BfRefType::RefKind refKind = BfRefType::RefKind_Ref); BfModifiedTypeType* CreateModifiedTypeType(BfType* resolvedTypeRef, BfToken modifiedKind); BfConcreteInterfaceType* CreateConcreteInterfaceType(BfTypeInstance* interfaceType); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 92d3a373..b6f09b08 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -404,12 +404,12 @@ bool BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType) if (resolvedTypeRef->IsTuple()) { - auto tupleType = (BfTupleType*)resolvedTypeRef; + auto tupleType = (BfTypeInstance*)resolvedTypeRef; for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++) { auto fieldInstance = (BfFieldInstance*)&tupleType->mFieldInstances[fieldIdx]; - if (fieldInstance->GetResolvedType()->IsUnspecializedType()) - tupleType->mHasUnspecializedMembers = true; +// if (fieldInstance->GetResolvedType()->IsUnspecializedType()) +// tupleType->mHasUnspecializedMembers = true; } } @@ -881,11 +881,6 @@ bool BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType else resolvedTypeRef->mTypeId = mCompiler->mCurTypeId++; - if ((resolvedTypeRef->mTypeId == 2599) && (!mCompiler->mIsResolveOnly)) - { - NOP; - } - while (resolvedTypeRef->mTypeId >= (int)mContext->mTypes.size()) mContext->mTypes.Add(NULL); mContext->mTypes[resolvedTypeRef->mTypeId] = resolvedTypeRef; @@ -5052,37 +5047,44 @@ BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef) return (BfBoxedType*)resolvedBoxedType; } -BfTupleType* BfModule::CreateTupleType(const BfTypeVector& fieldTypes, const Array& fieldNames) +BfTypeInstance* BfModule::CreateTupleType(const BfTypeVector& fieldTypes, const Array& fieldNames) { - auto tupleType = mContext->mTupleTypePool.Get(); - tupleType->mContext = mContext; - tupleType->mFieldInstances.Resize(fieldTypes.size()); - auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mValueTypeTypeDef); - tupleType->Init(baseType->mTypeDef->mProject, baseType); + + BfTypeInstance* tupleType = NULL; + + auto actualTupleType = mContext->mTupleTypePool.Get(); + actualTupleType->Init(baseType->mTypeDef->mProject, baseType); 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; - String fieldName; if (fieldIdx < (int)fieldNames.size()) fieldName = fieldNames[fieldIdx]; if (fieldName.empty()) fieldName = StrFormat("%d", fieldIdx); - BfFieldDef* fieldDef = tupleType->AddField(fieldName); + BfFieldDef* fieldDef = actualTupleType->AddField(fieldName); + } + tupleType = actualTupleType; + + tupleType->mContext = mContext; + 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; } auto resolvedTupleType = ResolveType(tupleType); - if (resolvedTupleType != tupleType) - mContext->mTupleTypePool.GiveBack(tupleType); + if (resolvedTupleType != tupleType) + mContext->mTupleTypePool.GiveBack((BfTupleType*)tupleType); + return (BfTupleType*)resolvedTupleType; } -BfTupleType * BfModule::SantizeTupleType(BfTupleType* tupleType) +BfTypeInstance* BfModule::SantizeTupleType(BfTypeInstance* tupleType) { bool needsSanitize = false; for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++) @@ -5774,29 +5776,130 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty if (unspecializedType->IsTuple()) { - auto tupleType = (BfTupleType*)unspecializedType; - Array names; + bool wantGeneric = false; + bool isUnspecialized = false; - BfTypeVector genericArgs; + auto unspecializedTupleType = (BfTypeInstance*)unspecializedType; + auto unspecializedGenericTupleType = unspecializedTupleType->ToGenericTypeInstance(); + Array fieldNames; + BfTypeVector fieldTypes; 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 newGenericArg = ResolveGenericType(origGenericArg, typeGenericArguments, methodGenericArguments, allowFail); if (newGenericArg == NULL) return NULL; if (newGenericArg->IsVar()) return newGenericArg; + + if (newGenericArg->IsGenericParam()) + wantGeneric = true; + if (newGenericArg->IsUnspecializedType()) + isUnspecialized = true; + if (newGenericArg != origGenericArg) hadChange = true; - genericArgs.push_back(newGenericArg); + fieldTypes.push_back(newGenericArg); } + if (!hadChange) return unspecializedType; + + if (unspecializedGenericTupleType == NULL) + wantGeneric = false; - return CreateTupleType(genericArgs, names); + auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mValueTypeTypeDef); + + BfTypeInstance* tupleType = NULL; + if (wantGeneric) + { + Array 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())) @@ -5917,9 +6020,7 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty delegateInfo->mDirectAllocNodes.push_back(directTypeRef); directTypeRef->Init(returnType); methodDef->mReturnTypeRef = directTypeRef; - delegateInfo->mReturnType = returnType; - - AddDependency(directTypeRef->mType, baseDelegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue); + delegateInfo->mReturnType = returnType; BfMethodDef* unspecializedInvokeMethodDef = unspecializedDelegateType->mTypeDef->GetMethodByName("Invoke"); @@ -5945,7 +6046,6 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty paramIdx++; delegateInfo->mParams.Add(paramType); - AddDependency(paramType, baseDelegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue); } typeDef->mMethods.push_back(methodDef); @@ -5962,7 +6062,13 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty BfType* resolvedType = NULL; if (!failed) 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()) { @@ -5977,7 +6083,6 @@ BfType* BfModule::ResolveGenericType(BfType* unspecializedType, BfTypeVector* ty } BF_ASSERT((resolvedType == NULL) || resolvedType->IsTypeInstance() || resolvedType->IsPrimitiveType()); return resolvedType; - } if (unspecializedType->IsGenericTypeInstance()) @@ -6034,8 +6139,16 @@ BfType* BfModule::ResolveType(BfType* lookupType, BfPopulateType populateType) if (lookupType->IsTuple()) { - auto tupleType = (BfTupleType*)lookupType; - tupleType->Finish(); + if (lookupType->IsGenericTypeInstance()) + { + auto tupleType = (BfGenericTupleType*)lookupType; + tupleType->Finish(); + } + else + { + auto tupleType = (BfTupleType*)lookupType; + tupleType->Finish(); + } } 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 // 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) { auto payloadFieldType = payloadFieldInst.mResolvedType; @@ -7904,6 +8017,11 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula mContext->mResolvedTypes.RemoveEntry(resolvedEntry); 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)) { auto typeAliasType = new BfGenericTypeAliasType(); @@ -7997,6 +8115,9 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula Array types; Array names; + bool wantGeneric = false; + bool isUnspecialized = false; + for (int fieldIdx = 0; fieldIdx < (int)tupleTypeRef->mFieldTypes.size(); fieldIdx++) { BfTypeReference* typeRef = tupleTypeRef->mFieldTypes[fieldIdx]; @@ -8017,31 +8138,67 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula else fieldName = StrFormat("%d", fieldIdx); + if (type->IsGenericParam()) + wantGeneric = true; + if (type->IsUnspecializedType()) + isUnspecialized = true; + String typeName = TypeToString(type); types.push_back(type); names.push_back(fieldName); } auto baseType = (BfTypeInstance*)ResolveTypeDef(mContext->mCompiler->mValueTypeTypeDef, BfPopulateType_Identity); - BfTupleType* tupleType = new BfTupleType(); - //TODO: Add to correct project - tupleType->Init(baseType->mTypeDef->mProject, baseType); + BfTypeInstance* tupleType = NULL; + if (wantGeneric) + { + 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()); - 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]; fieldInstance->mFieldIdx = fieldIdx; fieldInstance->SetResolvedType(types[fieldIdx]); fieldInstance->mOwner = tupleType; } - tupleType->Finish(); - resolvedEntry->mValue = tupleType; BF_ASSERT(BfResolvedTypeSet::Hash(tupleType, &lookupCtx) == resolvedEntry->mHash); populateModule->InitType(tupleType, populateType); @@ -8121,7 +8278,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula else if (auto delegateTypeRef = BfNodeDynCast(typeRef)) { bool wantGeneric = false; - bool isUnspecialized = false; + bool isUnspecialized = false; auto _CheckType = [&](BfType* type) { if (type->IsGenericParam()) @@ -8217,9 +8374,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula directTypeRef->Init(returnType); methodDef->mReturnTypeRef = directTypeRef; delegateInfo->mReturnType = returnType; - - AddDependency(directTypeRef->mType, baseDelegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue); - + auto hashVal = mContext->mResolvedTypes.Hash(typeRef, &lookupCtx); for (int paramIdx = 0; paramIdx < (int)paramTypes.size(); paramIdx++) @@ -8247,8 +8402,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula paramDef->mName = paramName; methodDef->mParams.push_back(paramDef); - delegateInfo->mParams.Add(paramType); - AddDependency(paramType, baseDelegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue); + delegateInfo->mParams.Add(paramType); } typeDef->mMethods.push_back(methodDef); @@ -8264,6 +8418,10 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula populateModule->InitType(delegateType, populateType); resolvedEntry->mValue = delegateType; + AddDependency(directTypeRef->mType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue); + for (auto paramType : paramTypes) + AddDependency(paramType, delegateType, BfDependencyMap::DependencyFlag_ParamOrReturnValue); + // #ifdef _DEBUG // if (BfResolvedTypeSet::Hash(delegateType, &lookupCtx) != resolvedEntry->mHash) // { @@ -9127,8 +9285,8 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp // Tuple -> Tuple if ((typedVal.mType->IsTuple()) && (toType->IsTuple())) { - auto fromTupleType = (BfTupleType*)typedVal.mType; - auto toTupleType = (BfTupleType*)toType; + auto fromTupleType = (BfTypeInstance*)typedVal.mType; + auto toTupleType = (BfTypeInstance*)toType; if (fromTupleType->mFieldInstances.size() == toTupleType->mFieldInstances.size()) { typedVal = LoadValue(typedVal); @@ -9964,8 +10122,8 @@ BfTypedValue BfModule::Cast(BfAstNode* srcNode, const BfTypedValue& typedVal, Bf //auto loadedVal = LoadValue(typedVal); PopulateType(toType); - auto fromTupleType = (BfTupleType*)typedVal.mType; - auto toTupleType = (BfTupleType*)toType; + auto fromTupleType = (BfTypeInstance*)typedVal.mType; + auto toTupleType = (BfTypeInstance*)toType; if (fromTupleType == toTupleType) return typedVal; @@ -10572,7 +10730,7 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF } else if (resolvedType->IsTuple()) { - BfTupleType* tupleType = (BfTupleType*)resolvedType; + BfTypeInstance* tupleType = (BfTypeInstance*)resolvedType; str += "("; 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]; 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]; if ((c < '0') || (c > '9')) diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index f0a97b9a..9763b5e2 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -1479,7 +1479,7 @@ bool BfTypeInstance::GetResultInfo(BfType*& valueType, int& okTagId) 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) { valueType = tupleType->mFieldInstances[0].mResolvedType; @@ -1922,8 +1922,9 @@ BfTupleType::BfTupleType() { mCreatedTypeDef = false; mSource = NULL; - mTypeDef = NULL; - mHasUnspecializedMembers = false; + mTypeDef = NULL; + mIsUnspecializedType = false; + mIsUnspecializedTypeVariation = false; } BfTupleType::~BfTupleType() @@ -1971,8 +1972,62 @@ void BfTupleType::Finish() BfDefBuilder bfDefBuilder(bfSystem); bfDefBuilder.mCurTypeDef = mTypeDef; 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); } ////////////////////////////////////////////////////////////////////////// @@ -2195,18 +2250,12 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef) if (closureType->mIsUnique) return false; 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()) { hashVal = HASH_VAL_TUPLE; - BfTupleType* tupleType = (BfTupleType*)type; + BfTypeInstance* tupleType = (BfTypeInstance*)type; for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++) { BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx]; @@ -2230,6 +2279,12 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef) 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; } else if (type->IsPrimitiveType()) @@ -2831,31 +2886,14 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) } 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 (!rhs->IsTuple()) return false; - BfTupleType* lhsTupleType = (BfTupleType*)lhs; - BfTupleType* rhsTupleType = (BfTupleType*)rhs; + BfTypeInstance* lhsTupleType = (BfTypeInstance*)lhs; + BfTypeInstance* rhsTupleType = (BfTypeInstance*)rhs; if (lhsTupleType->mFieldInstances.size() != rhsTupleType->mFieldInstances.size()) return false; 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; } + 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; } else if (lhs->IsPrimitiveType()) @@ -3138,7 +3193,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* } } - if (rhs->IsNamedTypeReference()) + if ((rhs->IsNamedTypeReference()) || (rhs->IsA())) { if ((ctx->mRootTypeRef != rhs) || (ctx->mRootTypeDef == NULL)) { @@ -3214,27 +3269,14 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* { 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 (!rhs->IsA()) return false; - BfTupleTypeRef* rhsTupleTypeRef = (BfTupleTypeRef*)rhs; - BfTupleType* lhsTupleType = (BfTupleType*)lhs; - + BfTupleTypeRef* rhsTupleTypeRef = (BfTupleTypeRef*)rhs; + BfTypeInstance* lhsTupleType = (BfTypeInstance*)lhs; + if (lhsTupleType->mFieldInstances.size() != rhsTupleTypeRef->mFieldTypes.size()) return false; @@ -3262,11 +3304,24 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* sprintf(nameStr, "%d", fieldIdx); if (fieldTypeDef->mName != nameStr) return false; - } + } } 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 { if (rhs->IsA()) diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index d5a6ac08..ea8d02ed 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -2055,33 +2055,20 @@ public: virtual bool IsFunction() override { return !mTypeDef->mIsDelegate; } virtual bool IsFunctionFromTypeRef() override { return !mTypeDef->mIsDelegate; } - virtual BfDelegateInfo* GetDelegateInfo() override { return &mDelegateInfo; } - //virtual bool IsReified() override { return mIsReified; } + virtual BfDelegateInfo* GetDelegateInfo() override { return &mDelegateInfo; } }; -/*class BfFunctionType : public BfTypeInstance -{ -public: - BfType* mReturnType; - Array mParamTypes; - Array mParamNames; - -public: - virtual bool IsOnDemand() override { return true; } - virtual bool IsFunction() override { return true; } - virtual bool IsFunctionFromTypeRef() override { return true; } -};*/ - class BfTupleType : public BfTypeInstance { public: bool mCreatedTypeDef; String mNameAdd; BfSource* mSource; - bool mHasUnspecializedMembers; - + bool mIsUnspecializedType; + bool mIsUnspecializedTypeVariation; + public: - BfTupleType(); + BfTupleType(); ~BfTupleType(); void Init(BfProject* bfProject, BfTypeInstance* valueTypeInstance); @@ -2091,8 +2078,27 @@ public: virtual bool IsOnDemand() override { return true; } virtual bool IsTuple() override { return true; } - virtual bool IsUnspecializedType() override { return mHasUnspecializedMembers; } - virtual bool IsUnspecializedTypeVariation() override { return mHasUnspecializedMembers; } + virtual bool IsUnspecializedType() override { return mIsUnspecializedType; } + 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 diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index efc22013..7a9190cb 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -1957,9 +1957,9 @@ void BfModule::CheckTupleVariableDeclaration(BfTupleExpression* tupleExpr, BfTyp if (initType == NULL) return; - BfTupleType* initTupleType = NULL; + BfTypeInstance* initTupleType = NULL; if ((initType != NULL) && (initType->IsTuple())) - initTupleType = (BfTupleType*)initType; + initTupleType = (BfTypeInstance*)initType; 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) { - BfTupleType* initTupleType = NULL; + BfTypeInstance* initTupleType = NULL; if ((initTupleValue) && (initTupleValue.mType->IsTuple())) - initTupleType = (BfTupleType*)initTupleValue.mType; + initTupleType = (BfTypeInstance*)initTupleValue.mType; CheckTupleVariableDeclaration(tupleExpr, initTupleValue.mType); @@ -2425,7 +2425,7 @@ BfTypedValue BfModule::TryCaseTupleMatch(BfTypedValue tupleVal, BfTupleExpressio if (!tupleVal.mType->IsTuple()) return BfTypedValue(); - auto tupleType = (BfTupleType*)tupleVal.mType; + auto tupleType = (BfTypeInstance*)tupleVal.mType; BfAstNode* tooFewRef = tupleExpr->mCloseParen; if ((tooFewRef == NULL) && (!tupleExpr->mCommas.IsEmpty())) @@ -2672,7 +2672,7 @@ BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVa } BF_ASSERT(fieldInstance->mResolvedType->IsTuple()); - auto tupleType = (BfTupleType*)fieldInstance->mResolvedType; + auto tupleType = (BfTypeInstance*)fieldInstance->mResolvedType; PopulateType(tupleType); mBfIRBuilder->PopulateType(tupleType); @@ -6039,7 +6039,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) 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++) { @@ -6127,7 +6127,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) if (!tupleBinds.IsEmpty()) { BF_ASSERT(varType->IsTuple()); - auto tupleType = (BfTupleType*)varType; + auto tupleType = (BfTypeInstance*)varType; // Tuple binds needsValCopy = false; diff --git a/IDEHelper/Tests/src/Aliases.bf b/IDEHelper/Tests/src/Aliases.bf index 336778ca..1c80bc17 100644 --- a/IDEHelper/Tests/src/Aliases.bf +++ b/IDEHelper/Tests/src/Aliases.bf @@ -16,9 +16,23 @@ namespace Tests public typealias AliasA3 = delegate T(); public typealias AliasA4 = delegate T(T2 val); + public typealias AliasA5 = (int, T); + public typealias AliasA6 = (T, T2); + public delegate T Zag(); } + public static void Test() + { + T LocalA(int16 a) + { + return default(T); + } + + ClassA.AliasA6 t0 = (default(T), 1.2f); + ClassA.AliasA4 dlg0 = scope => LocalA; + } + [Test] public static void TestBasics() { @@ -33,6 +47,12 @@ namespace Tests delegate double(char8) dlg3 = default; ClassA.AliasA4 dlg4 = dlg3; + + var t0 = (123, 1.2f); + ClassA.AliasA5 t1 = t0; + + var t2 = (1.2f, 3.4); + ClassA.AliasA6 v3 = t2; } } }