diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index 35698a74..1fd4be56 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -1017,8 +1017,9 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild typeInst->mTypeWarned = false; typeInst->mIsSplattable = false; typeInst->mHasUnderlyingArray = false; - typeInst->mHasPackingHoles = false; + typeInst->mHasPackingHoles = false; typeInst->mWantsGCMarking = false; + typeInst->mHasDeclError = false; delete typeInst->mTypeInfoEx; typeInst->mTypeInfoEx = NULL; diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 2a166787..f63383d1 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -703,7 +703,7 @@ void BfModule::CheckMemberNames(BfTypeInstance* typeInst) if (!typeInst->IsTypeMemberIncluded(prop->mDeclaringType)) continue; - MemberRef memberRef; + MemberRef memberRef = { 0 }; memberRef.mMemberDef = prop; memberRef.mTypeInst = checkType; memberRef.mProtection = prop->mProtection; @@ -724,7 +724,7 @@ void BfModule::CheckMemberNames(BfTypeInstance* typeInst) if (!typeInst->IsTypeMemberIncluded(field->mDeclaringType)) continue; - MemberRef memberRef; + MemberRef memberRef = { 0 }; memberRef.mMemberDef = field; memberRef.mTypeInst = checkType; memberRef.mProtection = field->mProtection; @@ -805,6 +805,7 @@ void BfModule::CheckMemberNames(BfTypeInstance* typeInst) if (secondMemberRef->mNameNode != NULL) error = Fail(StrFormat("A %s named '%s' has already been declared.", secondMemberRef->mKindName.c_str(), memberRef.mName.c_str()), secondMemberRef->mNameNode, true); showPrevious = true; + typeInst->mHasDeclError = true; } if ((secondMemberRef->mNameNode != NULL) && (error != NULL)) mCompiler->mPassInstance->MoreInfo("Previous declaration", firstMemberRef->mNameNode); @@ -7156,6 +7157,30 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy { if ((typeInstance->mCustomAttributes != NULL) && (!typeRef->IsTemporary())) CheckErrorAttributes(typeInstance, NULL, typeInstance->mCustomAttributes, typeRef); + + if (typeInstance->IsTuple()) + { + if (typeInstance->mDefineState < BfTypeDefineState_Defined) + PopulateType(typeInstance); + if (typeInstance->mHasDeclError) + { + if (auto tupleTypeRef = BfNodeDynCast(typeRef)) + { + HashSet names; + for (auto nameIdentifier : tupleTypeRef->mFieldNames) + { + if (nameIdentifier == NULL) + continue; + StringT<64> fieldName; + nameIdentifier->ToString(fieldName); + if (!names.Add(fieldName)) + { + Fail(StrFormat("A field named '%s' has already been declared", fieldName.c_str()), nameIdentifier); + } + } + } + } + } } return resolvedTypeRef; diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index c2af26df..0463096b 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -1797,6 +1797,7 @@ public: bool mIsFinishingType; bool mHasPackingHoles; bool mWantsGCMarking; + bool mHasDeclError; public: BfTypeInstance() @@ -1847,6 +1848,7 @@ public: mIncludeAllMethods = false; mWantsGCMarking = false; mHasParameterizedBase = false; + mHasDeclError = false; mMergedFieldDataCount = 0; mConstHolder = NULL; }