diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index b79f790e698d92f3d4a047b7f61508d47db11507..ff01562d862610670de68ba19ee4385594e75352 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -748,6 +748,7 @@ public: void ImportNamespaceObjectTypeAddReExportType(ir::ETSImportDeclaration *importDecl, checker::ETSObjectType *lastObjectType, ir::Identifier *ident); bool CheckValidEqualReferenceType(checker::Type *const leftType, checker::Type *const rightType); + bool CheckValidObjectOverlap(checker::Type *const leftType, checker::Type *const rightType); bool CheckVoidAnnotation(const ir::ETSPrimitiveType *typeAnnotation); void ETSObjectTypeDeclNode(ETSChecker *checker, ETSObjectType *const objectType); ir::CallExpression *CreateExtensionAccessorCall(ETSChecker *checker, ir::MemberExpression *expr, diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index b76c779b5ae596684a2d710a8dac3be1938a5747..4b79fe95c1f5bbb3424d226dfe0632b0c71cb1da 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -572,84 +572,11 @@ checker::Type *ETSChecker::CheckBinaryOperatorLogical(ir::Expression *left, ir:: return CreateETSUnionType({MaybeBoxExpression(left), MaybeBoxExpression(right)}); } -static bool ContainsNumbers(ETSChecker *checker, Type *tp) -{ - auto isSubtypeOfNumeric = [checker](Type *tp2) { - return checker->Relation()->IsSupertypeOf(checker->GetGlobalTypesHolder()->GlobalNumericBuiltinType(), tp2); - }; - if (isSubtypeOfNumeric(tp)) { - return true; - } - if (tp->IsETSUnionType()) { - for (auto *constituent : tp->AsETSUnionType()->ConstituentTypes()) { - if (isSubtypeOfNumeric(constituent)) { - return true; - } - } - } - - return false; -} - // CC-OFFNXT(huge_cyclomatic_complexity, huge_cca_cyclomatic_complexity[C++]) solid logic // NOTE: code inside this function follows the broken logic bool ETSChecker::CheckValidEqualReferenceType(checker::Type *const leftType, checker::Type *const rightType) { - auto isRelaxedType {[&](checker::Type *const type) -> bool { - return (type->IsETSObjectType() && type->AsETSObjectType()->IsGlobalETSObjectType()) || type->IsETSAnyType() || - type->IsETSNullType() || type->IsETSUndefinedType(); - }}; - - // Equality expression is always allowed for *magic types* - if (isRelaxedType(leftType) || isRelaxedType(rightType)) { - return true; - } - - // Any two types that can be numeric are comparable - if (ContainsNumbers(this, leftType) && ContainsNumbers(this, rightType)) { - return true; - } - - // Boolean and any type that can be numeric or char are not comparable - if ((FindOpArgsType(this, leftType, rightType, GetGlobalTypesHolder()->GlobalNumericBuiltinType()) || - FindOpArgsType(this, leftType, rightType, GetGlobalTypesHolder()->GlobalCharBuiltinType())) && - FindOpArgsType(this, leftType, rightType, GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType())) { - return false; - } - - // NOTE (mxlgv): Skip for unions. Required implementation of the specification section: - // 7.25.6 Reference Equality Based on Actual Type (Union Equality Operators) - if (leftType->IsETSUnionType()) { - return leftType->AsETSUnionType()->IsOverlapWith(Relation(), rightType); - } - if (rightType->IsETSUnionType()) { - return rightType->AsETSUnionType()->IsOverlapWith(Relation(), leftType); - } - - // NOTE (mxlgv): Skip for generic. Required implementation of the specification section: - // 7.25.6 Reference Equality Based on Actual Type (Type Parameter Equality Operators) - if (leftType->HasTypeFlag(TypeFlag::GENERIC) || rightType->HasTypeFlag(TypeFlag::GENERIC)) { - return true; - } - - // Equality expression can only be applied to String and String, and BigInt and BigInt - if (leftType->IsETSStringType() || rightType->IsETSStringType() || leftType->IsETSBigIntType() || - rightType->IsETSBigIntType()) { - auto *const nonConstLhs = GetNonConstantType(leftType); - auto *const nonConstRhs = GetNonConstantType(rightType); - if (!Relation()->IsIdenticalTo(nonConstLhs, nonConstRhs) && - !Relation()->IsIdenticalTo(nonConstRhs, nonConstLhs)) { - return false; - } - } - - if (FindOpArgsType(this, leftType, rightType, GetGlobalTypesHolder()->GlobalNumericBuiltinType()) && - (leftType->IsETSEnumType() || rightType->IsETSEnumType())) { - return true; - } - - // 7.24.5 Enumeration Relational Operators - return leftType->IsETSEnumType() == rightType->IsETSEnumType(); + return leftType->IsOverlapWith(Relation(), rightType) || rightType->IsOverlapWith(Relation(), leftType); } std::tuple ETSChecker::CheckBinaryOperatorStrictEqual(ir::Expression *left, diff --git a/ets2panda/checker/types/ets/etsAnyType.cpp b/ets2panda/checker/types/ets/etsAnyType.cpp index ea399276063cd735fb696ab45e416260bd38d9f9..edbea0d9355f1e8f56e4bb47508e4a6476c0d2da 100644 --- a/ets2panda/checker/types/ets/etsAnyType.cpp +++ b/ets2panda/checker/types/ets/etsAnyType.cpp @@ -109,4 +109,10 @@ Type *ETSAnyType::Instantiate(ArenaAllocator *allocator, [[maybe_unused]] TypeRe { return isRelaxedAny_ ? allocator->New(true) : allocator->New(); } + +bool ETSAnyType::IsOverlapWith([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *type) +{ + // Equality expression is always allowed for *magic types* + return true; +} } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsAnyType.h b/ets2panda/checker/types/ets/etsAnyType.h index 7d12b6a004e77c58e9e50f6f0b2b2a2691dd5668..b07260a616d47fd811fb43ea1bfc0a128028f3a5 100644 --- a/ets2panda/checker/types/ets/etsAnyType.h +++ b/ets2panda/checker/types/ets/etsAnyType.h @@ -35,6 +35,7 @@ public: void ToString(std::stringstream &ss, bool precise) const override; void ToAssemblerType(std::stringstream &ss) const override; void ToDebugInfoType([[maybe_unused]] std::stringstream &ss) const override; + bool IsOverlapWith(TypeRelation *relation, Type *type) override; TypeFacts GetTypeFacts() const override; diff --git a/ets2panda/checker/types/ets/etsBigIntType.cpp b/ets2panda/checker/types/ets/etsBigIntType.cpp index e5ad30da139d3cf1f2c6a31a87cf3ddc513352d4..ebde738ea7ef793a8e5aa0aefdb7e8a2613b37cf 100644 --- a/ets2panda/checker/types/ets/etsBigIntType.cpp +++ b/ets2panda/checker/types/ets/etsBigIntType.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -14,6 +14,7 @@ */ #include "etsBigIntType.h" +#include "checker/ETSchecker.h" namespace ark::es2panda::checker { void ETSBigIntType::Identical(TypeRelation *relation, Type *other) @@ -41,4 +42,16 @@ Type *ETSBigIntType::Instantiate([[maybe_unused]] ArenaAllocator *allocator, [[m { return this; } + +bool ETSBigIntType::IsOverlapWith(TypeRelation *relation, Type *type) +{ + // Equality expression can only be applied to BigInt and BigInt + if (!type->IsETSBigIntType()) { + return false; + } + auto *const checker = relation->GetChecker()->AsETSChecker(); + auto *const nonConstLhs = checker->GetNonConstantType(this); + auto *const nonConstRhs = checker->GetNonConstantType(type); + return relation->IsIdenticalTo(nonConstLhs, nonConstRhs) || relation->IsIdenticalTo(nonConstRhs, nonConstLhs); +} } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsBigIntType.h b/ets2panda/checker/types/ets/etsBigIntType.h index 8ed5f40ccb1f3ecdda34f88f5fdc60eee0483297..085f01732d424f3f684587abd7d381cd5cdf71a5 100644 --- a/ets2panda/checker/types/ets/etsBigIntType.h +++ b/ets2panda/checker/types/ets/etsBigIntType.h @@ -46,6 +46,7 @@ public: void Identical(TypeRelation *relation, Type *other) override; void AssignmentTarget(TypeRelation *relation, Type *source) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; + bool IsOverlapWith(TypeRelation *relation, Type *type) override; void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override { diff --git a/ets2panda/checker/types/ets/etsBooleanType.cpp b/ets2panda/checker/types/ets/etsBooleanType.cpp index f19823daa2f3ab0f1dc703ee184a7708609884c5..5905e695daeffaf17f33b00fe676e527c52d673e 100644 --- a/ets2panda/checker/types/ets/etsBooleanType.cpp +++ b/ets2panda/checker/types/ets/etsBooleanType.cpp @@ -67,4 +67,10 @@ Type *ETSBooleanType::Instantiate([[maybe_unused]] ArenaAllocator *allocator, [[ { return this; } + +bool ETSBooleanType::IsOverlapWith(TypeRelation *relation, Type *type) +{ + auto *const checker = relation->GetChecker()->AsETSChecker(); + return relation->IsSupertypeOf(checker->GetGlobalTypesHolder()->GlobalETSBooleanBuiltinType(), type); +} } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsBooleanType.h b/ets2panda/checker/types/ets/etsBooleanType.h index 2bc7ccaddca17d8268de62ba33e7fbaa7a3aa371..bc1a20fb6062834a5d43181b4380ea244ebb1f0c 100644 --- a/ets2panda/checker/types/ets/etsBooleanType.h +++ b/ets2panda/checker/types/ets/etsBooleanType.h @@ -30,6 +30,7 @@ public: bool AssignmentSource([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *target) override; void Cast(TypeRelation *relation, Type *target) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; + bool IsOverlapWith(TypeRelation *relation, Type *type) override; UType GetValue() const { diff --git a/ets2panda/checker/types/ets/etsEnumType.cpp b/ets2panda/checker/types/ets/etsEnumType.cpp index 233a403e0501e8a662fba2b7bd2ad9c056b0df62..3d251db2800945f594030679ed66ffb185a9b526 100644 --- a/ets2panda/checker/types/ets/etsEnumType.cpp +++ b/ets2panda/checker/types/ets/etsEnumType.cpp @@ -78,6 +78,16 @@ void ETSStringEnumType::CastTarget(TypeRelation *relation, Type *source) conversion::Forbidden(relation); } +bool ETSStringEnumType::IsOverlapWith(TypeRelation *relation, Type *type) +{ + auto *const checker = relation->GetChecker()->AsETSChecker(); + if (relation->IsSupertypeOf(checker->GetGlobalTypesHolder()->GlobalETSStringBuiltinType(), type) || + relation->IsSupertypeOf(checker->GetGlobalTypesHolder()->GlobalETSStringLiteralType(), type)) { + return true; + } + return type->IsETSStringEnumType(); +} + bool ETSIntEnumType::AssignmentSource(TypeRelation *relation, Type *target) { bool result = false; @@ -134,4 +144,13 @@ void ETSIntEnumType::CastTarget(TypeRelation *relation, Type *source) conversion::Forbidden(relation); } +bool ETSIntEnumType::IsOverlapWith(TypeRelation *relation, Type *type) +{ + auto *const checker = relation->GetChecker()->AsETSChecker(); + if (relation->IsSupertypeOf(checker->GetGlobalTypesHolder()->GlobalNumericBuiltinType(), type)) { + return true; + } + return type->IsETSIntEnumType(); +} + } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsEnumType.h b/ets2panda/checker/types/ets/etsEnumType.h index 3005b78053a406f8ef707e2410d7d7cc090593a4..681e2ab0fb4d07dc3db1c8ce1efbc0598a825f62 100644 --- a/ets2panda/checker/types/ets/etsEnumType.h +++ b/ets2panda/checker/types/ets/etsEnumType.h @@ -139,6 +139,7 @@ public: void AssignmentTarget(TypeRelation *relation, Type *source) override; void Cast(TypeRelation *relation, Type *target) override; void CastTarget(TypeRelation *relation, Type *source) override; + bool IsOverlapWith(TypeRelation *relation, Type *type) override; }; class ETSStringEnumType : public ETSEnumType { @@ -160,6 +161,7 @@ public: void AssignmentTarget(TypeRelation *relation, Type *source) override; void Cast(TypeRelation *relation, Type *target) override; void CastTarget(TypeRelation *relation, Type *source) override; + bool IsOverlapWith(TypeRelation *relation, Type *type) override; }; } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsFunctionType.cpp b/ets2panda/checker/types/ets/etsFunctionType.cpp index b3d97f28b776d6388b8bb59496739312d18ee137..f26939afb3c6cd2f3608f73fec936d659af826a6 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.cpp +++ b/ets2panda/checker/types/ets/etsFunctionType.cpp @@ -416,4 +416,25 @@ void ETSFunctionType::CheckVarianceRecursively(TypeRelation *relation, VarianceF } } +bool ETSFunctionType::IsOverlapWith([[maybe_unused]] TypeRelation *relation, Type *type) +{ + if (!type->IsETSFunctionType()) { + return false; + } + bool isOverlap = true; + auto *leftSig = CallSignaturesOfMethodOrArrow().front(); + auto *rightSig = type->AsETSFunctionType()->CallSignaturesOfMethodOrArrow().front(); + auto minArgCount = std::min(leftSig->MinArgCount(), rightSig->MinArgCount()); + for (size_t idx = 0; idx < minArgCount; idx++) { + auto *leftParamType = leftSig->Params().at(idx)->TsType(); + auto *rightParamType = rightSig->Params().at(idx)->TsType(); + isOverlap &= leftParamType->IsOverlapWith(relation, rightParamType) || + rightParamType->IsOverlapWith(relation, leftParamType); + } + + isOverlap &= leftSig->ReturnType()->IsOverlapWith(relation, rightSig->ReturnType()) || + rightSig->ReturnType()->IsOverlapWith(relation, leftSig->ReturnType()); + + return isOverlap; +} } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsFunctionType.h b/ets2panda/checker/types/ets/etsFunctionType.h index ffc9e8ea5987fe634c900543de8f21a8e019eb4c..7b85fdcb89b692b8f00c9d46cdf1d53921352627 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.h +++ b/ets2panda/checker/types/ets/etsFunctionType.h @@ -133,6 +133,7 @@ public: void CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) override; void Cast(TypeRelation *relation, Type *target) override; void CastTarget(TypeRelation *relation, Type *source) override; + bool IsOverlapWith(TypeRelation *relation, Type *type) override; void SetHelperSignature(Signature *signature) noexcept { diff --git a/ets2panda/checker/types/ets/etsNullishTypes.cpp b/ets2panda/checker/types/ets/etsNullishTypes.cpp index 6e102e16751ae3c4b039af93f2d5a8278a34a2de..8cd8f3761961ac1314b1363236b2b1d498b7967a 100644 --- a/ets2panda/checker/types/ets/etsNullishTypes.cpp +++ b/ets2panda/checker/types/ets/etsNullishTypes.cpp @@ -73,6 +73,12 @@ Type *ETSNullType::Instantiate([[maybe_unused]] ArenaAllocator *allocator, [[may return allocator->New(); } +bool ETSNullType::IsOverlapWith([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *type) +{ + // Equality expression is always allowed for *magic types* + return true; +} + void ETSUndefinedType::Identical(TypeRelation *relation, Type *other) { relation->Result(other->IsETSUndefinedType()); @@ -124,4 +130,10 @@ Type *ETSUndefinedType::Instantiate([[maybe_unused]] ArenaAllocator *allocator, return allocator->New(); } +bool ETSUndefinedType::IsOverlapWith([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *type) +{ + // Equality expression is always allowed for *magic types* + return true; +} + } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsNullishTypes.h b/ets2panda/checker/types/ets/etsNullishTypes.h index ff11033e5d4d7c2a2af967e67bd0cc3fea8ce87a..2f4593ab6b90f6888b567dee691bd2530fa029da 100644 --- a/ets2panda/checker/types/ets/etsNullishTypes.h +++ b/ets2panda/checker/types/ets/etsNullishTypes.h @@ -35,6 +35,7 @@ public: void ToString(std::stringstream &ss, bool precise) const override; void ToAssemblerType(std::stringstream &ss) const override; void ToDebugInfoType([[maybe_unused]] std::stringstream &ss) const override; + bool IsOverlapWith(TypeRelation *relation, Type *type) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; }; @@ -53,6 +54,7 @@ public: void ToString(std::stringstream &ss, bool precise) const override; void ToAssemblerType(std::stringstream &ss) const override; void ToDebugInfoType([[maybe_unused]] std::stringstream &ss) const override; + bool IsOverlapWith(TypeRelation *relation, Type *type) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; }; diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 177a0c679a909e84d1e36a2aff4228362d92df78..fe8bedbf014b139beab042fb3574e7182093d632 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -1651,4 +1651,47 @@ void ETSObjectType::InsertInstantiationMap(util::StringView key, ETSObjectType * .try_emplace(key, value); } +static bool ContainsNumeric(ETSChecker *checker, Type *left, Type *right) +{ + auto isSubtypeOfNumeric = [checker](Type *type) { + return checker->Relation()->IsSupertypeOf(checker->GetGlobalTypesHolder()->GlobalNumericBuiltinType(), type) || + checker->Relation()->IsSupertypeOf(checker->GetGlobalTypesHolder()->GlobalCharBuiltinType(), type); + }; + + return isSubtypeOfNumeric(left) && isSubtypeOfNumeric(right); +} + +bool ETSObjectType::IsOverlapWith(TypeRelation *relation, Type *type) +{ + // Equality expression is always allowed for *magic types* + if (IsGlobalETSObjectType() || (type->IsETSObjectType() && type->AsETSObjectType()->IsGlobalETSObjectType())) { + return true; + } + + if (!type->IsETSObjectType()) { + return false; + } + + // Any two types that can be numeric are comparable + if (ContainsNumeric(GetETSChecker(), this, type)) { + return true; + } + + // 7.25 If it is known at compile-time, that comparison of values of types A and B always evaluates to false, a + // compile-time error occurs + SavedTypeRelationFlagsContext const savedFlags(relation, relation->GetTypeRelationFlags() | + TypeRelationFlag::IGNORE_TYPE_PARAMETERS); + if (!relation->IsSupertypeOf(this, type) && !relation->IsSupertypeOf(type, this)) { + return false; + } + + // NOTE (mxlgv): Skip for generic. Required implementation of the specification section: + // 7.25.6 Reference Equality Based on Actual Type (Type Parameter Equality Operators) + if (HasTypeFlag(TypeFlag::GENERIC) || type->HasTypeFlag(TypeFlag::GENERIC)) { + return true; + }; + + return true; +} + } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index 2f81c4be7c98481b663be75eb3c0a94a6bb28383..077e154eda46e4de9653f9491d5f49bd1fe6c481 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -383,6 +383,7 @@ public: void ToDebugInfoType(std::stringstream &ss) const override; void ToDebugInfoSignatureType(std::stringstream &ss) const; void CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) override; + bool IsOverlapWith(TypeRelation *relation, Type *type) override; void AddReExports(ETSObjectType *reExport); void AddReExportAlias(util::StringView const &value, util::StringView const &key); diff --git a/ets2panda/checker/types/ets/etsStringType.cpp b/ets2panda/checker/types/ets/etsStringType.cpp index ef98c512f8887eff0ba6f19d14f95fa89d0d081b..743c55899db42e0f531c96b74fccc3661abb47e0 100644 --- a/ets2panda/checker/types/ets/etsStringType.cpp +++ b/ets2panda/checker/types/ets/etsStringType.cpp @@ -74,4 +74,16 @@ void ETSStringType::IsSubtypeOf(TypeRelation *relation, Type *source) auto *const checker = relation->GetChecker()->AsETSChecker(); relation->IsSupertypeOf(source, checker->GlobalBuiltinETSStringType()); } + +bool ETSStringType::IsOverlapWith(TypeRelation *relation, Type *type) +{ + // Equality expression can only be applied to String and String + if (!type->IsETSStringType()) { + return false; + } + auto *const checker = relation->GetChecker()->AsETSChecker(); + auto *const nonConstLhs = checker->GetNonConstantType(this); + auto *const nonConstRhs = checker->GetNonConstantType(type); + return relation->IsIdenticalTo(nonConstLhs, nonConstRhs) || relation->IsIdenticalTo(nonConstRhs, nonConstLhs); +} } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsStringType.h b/ets2panda/checker/types/ets/etsStringType.h index ab6b6e07608388106a8f0b8b2fc043fbffb6f6c5..f311957eaa97350e5f01bdbbdd2f69cb4e8858e6 100644 --- a/ets2panda/checker/types/ets/etsStringType.h +++ b/ets2panda/checker/types/ets/etsStringType.h @@ -56,6 +56,7 @@ public: Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; void IsSupertypeOf(TypeRelation *relation, Type *source) override; void IsSubtypeOf(TypeRelation *relation, Type *source) override; + bool IsOverlapWith(TypeRelation *relation, Type *type) override; void ToString(std::stringstream &ss, [[maybe_unused]] bool precise) const override { diff --git a/ets2panda/checker/types/ets/etsTypeParameter.cpp b/ets2panda/checker/types/ets/etsTypeParameter.cpp index ebb370321da70c44aa3855509d3387f22c3d2244..3ce69538644f2858b4d555679508a09918a99858 100644 --- a/ets2panda/checker/types/ets/etsTypeParameter.cpp +++ b/ets2panda/checker/types/ets/etsTypeParameter.cpp @@ -167,4 +167,9 @@ util::StringView const &ETSTypeParameter::Name() const noexcept { return GetDeclNode()->Name()->Name(); } + +bool ETSTypeParameter::IsOverlapWith([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *type) +{ + return true; +} } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsTypeParameter.h b/ets2panda/checker/types/ets/etsTypeParameter.h index d38b1b7b1d11ac0349d5ceb04e8d4b8916fc91f0..13c63a28cf70914749e1fb6326c09d6ed582914a 100644 --- a/ets2panda/checker/types/ets/etsTypeParameter.h +++ b/ets2panda/checker/types/ets/etsTypeParameter.h @@ -73,6 +73,7 @@ public: void CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; Type *Substitute(TypeRelation *relation, const Substitution *substitution) override; + bool IsOverlapWith(TypeRelation *relation, Type *type) override; void ToAssemblerType(std::stringstream &ss) const override; void ToDebugInfoType(std::stringstream &ss) const override; diff --git a/ets2panda/checker/types/ets/etsUnionType.cpp b/ets2panda/checker/types/ets/etsUnionType.cpp index 3bfeecc8cc9282d8c9d2cd9a936db99701553574..34e78ff45bd370e04732c6cfea733de733336e43 100644 --- a/ets2panda/checker/types/ets/etsUnionType.cpp +++ b/ets2panda/checker/types/ets/etsUnionType.cpp @@ -509,24 +509,47 @@ Type *ETSUnionType::FindUnboxableType() const noexcept return FindSpecificType([](Type *t) { return t->IsETSUnboxableObject(); }); } -bool ETSUnionType::IsOverlapWith(TypeRelation *relation, Type const *type) const noexcept +static bool HasNullishType(TypeRelation *relation, ETSUnionType *unionType, Type *nullishType) { - // NOTE(aakmaev): replace this func with intersection type when it will be implemented + const auto &types = unionType->ConstituentTypes(); + return std::any_of(types.begin(), types.end(), + [relation, nullishType](Type *t) { return relation->IsIdenticalTo(t, nullishType); }); +} + +bool ETSUnionType::IsOverlapWithRemoveNullishType(TypeRelation *relation, Type *type) +{ + auto *checker = relation->GetChecker()->AsETSChecker(); + auto *globalTypes = checker->GetGlobalTypesHolder(); + + if (HasNullishType(relation, this, globalTypes->GlobalETSUndefinedType()) && + HasNullishType(relation, type->AsETSUnionType(), globalTypes->GlobalETSUndefinedType())) { + return true; + } + if (HasNullishType(relation, this, globalTypes->GlobalETSNullType()) && + HasNullishType(relation, type->AsETSUnionType(), globalTypes->GlobalETSNullType())) { + return true; + } + + return checker->GetNonNullishType(this)->IsOverlapWith(relation, checker->GetNonNullishType(type)); +} + +bool ETSUnionType::IsOverlapWith(TypeRelation *relation, Type *type) +{ + auto needRemoveNullishType = [relation](ETSUnionType *unionType) { + auto *globalTypes = relation->GetChecker()->AsETSChecker()->GetGlobalTypesHolder(); + return HasNullishType(relation, unionType, globalTypes->GlobalETSUndefinedType()) || + HasNullishType(relation, unionType, globalTypes->GlobalETSNullType()); + }; + if (type->IsETSUnionType() && (needRemoveNullishType(this) || needRemoveNullishType(type->AsETSUnionType()))) { + return IsOverlapWithRemoveNullishType(relation, type); + } + + bool isOverlap = false; for (auto *ct : constituentTypes_) { - if (type->IsETSUnionType() && type->AsETSUnionType()->IsOverlapWith(relation, ct)) { - return true; - } - if (type->IsETSObjectType() && ct->IsETSObjectType()) { - if (type->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_NUMERIC) && - ct->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::BUILTIN_NUMERIC)) { - return true; - } - } - if (relation->IsSupertypeOf(ct, type) || relation->IsSupertypeOf(type, ct)) { - return true; - } + isOverlap |= ct->IsOverlapWith(relation, type); + isOverlap |= type->IsOverlapWith(relation, ct); } - return false; + return isOverlap; } ArenaVector ETSUnionType::GetNonConstantTypes(ETSChecker *checker) const noexcept diff --git a/ets2panda/checker/types/ets/etsUnionType.h b/ets2panda/checker/types/ets/etsUnionType.h index 71c9ac8601f4de50b818fac6c149ee28950068cb..09bd44f29ffb62925a1d70608218ddca02c00ed5 100644 --- a/ets2panda/checker/types/ets/etsUnionType.h +++ b/ets2panda/checker/types/ets/etsUnionType.h @@ -45,11 +45,11 @@ public: void IsSupertypeOf(TypeRelation *relation, Type *source) override; void IsSubtypeOf(TypeRelation *relation, Type *target) override; void CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) override; + bool IsOverlapWith(TypeRelation *relation, Type *type) override; + bool IsOverlapWithRemoveNullishType(TypeRelation *relation, Type *type); [[nodiscard]] Type *FindUnboxableType() const noexcept; - [[nodiscard]] bool IsOverlapWith(TypeRelation *relation, Type const *type) const noexcept; - static void NormalizeTypes(TypeRelation *relation, ArenaVector &types); [[nodiscard]] ArenaVector GetNonConstantTypes(ETSChecker *checker) const noexcept; diff --git a/ets2panda/checker/types/type.cpp b/ets2panda/checker/types/type.cpp index 61a6b8568e82040ac0fe3ebbed737ee8846d6c40..b08b76ddf79615eb4dc03d25c2cd22dd69c79e84 100644 --- a/ets2panda/checker/types/type.cpp +++ b/ets2panda/checker/types/type.cpp @@ -157,6 +157,11 @@ Type *Type::Substitute([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] return this; } +bool Type::IsOverlapWith([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *type) +{ + return relation->IsSupertypeOf(this, type) || relation->IsSupertypeOf(type, this); +} + bool IsTypeError(Type const *tp) { return tp != nullptr && tp->IsTypeError(); diff --git a/ets2panda/checker/types/type.h b/ets2panda/checker/types/type.h index 3840d6ab66b98a8570b957cad0c6b5cde073c655..011c8ae499274399c1048f7b34f4f71bc2918d5e 100644 --- a/ets2panda/checker/types/type.h +++ b/ets2panda/checker/types/type.h @@ -274,6 +274,7 @@ public: virtual Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes); [[nodiscard]] virtual Type *Clone(Checker *checker); virtual Type *Substitute(TypeRelation *relation, const Substitution *substitution); + virtual bool IsOverlapWith(TypeRelation *relation, Type *type); protected: // NOLINTBEGIN(misc-non-private-member-variables-in-classes) diff --git a/ets2panda/test/runtime/ets/RestTuple5.ets b/ets2panda/test/ast/compiler/ets/RestTuple5.ets similarity index 85% rename from ets2panda/test/runtime/ets/RestTuple5.ets rename to ets2panda/test/ast/compiler/ets/RestTuple5.ets index 09fb7a01ef7b1701febacbd41db5a6a5cfe2431b..ad73c779709b6f0b45a728c8ebc9f4d919b18235 100644 --- a/ets2panda/test/runtime/ets/RestTuple5.ets +++ b/ets2panda/test/ast/compiler/ets/RestTuple5.ets @@ -17,11 +17,11 @@ class A {} class B {} function foo(...p: [A, B]): boolean { - return p[0] == p[1] + return /* @@ label1 */p[0] == p[1] } function moo(a:int, ...p: [A, B]): boolean { - return p[0] == p[1] + return /* @@ label2 */p[0] == p[1] } function main() { @@ -39,3 +39,6 @@ function main() { arktest.assertTrue(foo(new A, new B) == false) arktest.assertTrue(moo(12, new A, new B) == false) } + +/* @@@ label1 Error TypeError: Operator '==' cannot be applied to types 'A' and 'B'. */ +/* @@@ label2 Error TypeError: Operator '==' cannot be applied to types 'A' and 'B'. */ diff --git a/ets2panda/test/runtime/ets/RestTuple6.ets b/ets2panda/test/ast/compiler/ets/RestTuple6.ets similarity index 85% rename from ets2panda/test/runtime/ets/RestTuple6.ets rename to ets2panda/test/ast/compiler/ets/RestTuple6.ets index a4a6a0f4e02690b4885786c9f2d61394955fb02f..4727208e2c784e2858693d7476cc0287dc338455 100644 --- a/ets2panda/test/runtime/ets/RestTuple6.ets +++ b/ets2panda/test/ast/compiler/ets/RestTuple6.ets @@ -18,11 +18,11 @@ class B {} class C { foo(...p: [A, B]): boolean { - return p[0] == p[1] + return /* @@ label1 */p[0] == p[1] } moo(a:int, ...p: [A, B]): boolean { - return p[0] == p[1] + return /* @@ label2 */p[0] == p[1] } } @@ -41,3 +41,6 @@ function main() { arktest.assertTrue((new C()).foo(new A, new B) == false) arktest.assertTrue((new C()).moo(12, new A, new B) == false) } + +/* @@@ label1 Error TypeError: Operator '==' cannot be applied to types 'A' and 'B'. */ +/* @@@ label2 Error TypeError: Operator '==' cannot be applied to types 'A' and 'B'. */ diff --git a/ets2panda/test/runtime/ets/RestTuple7.ets b/ets2panda/test/ast/compiler/ets/RestTuple7.ets similarity index 84% rename from ets2panda/test/runtime/ets/RestTuple7.ets rename to ets2panda/test/ast/compiler/ets/RestTuple7.ets index ed7c05fc24641df5f0704526a2095a404947462b..f061283ba53d7d6ed875e8dbfbaffab72a08073a 100644 --- a/ets2panda/test/runtime/ets/RestTuple7.ets +++ b/ets2panda/test/ast/compiler/ets/RestTuple7.ets @@ -18,11 +18,11 @@ class B {} class C { static foo(...p: [A, B]): boolean { - return p[0] == p[1] + return /* @@ label1 */p[0] == p[1] } static moo(a:int, ...p: [A, B]): boolean { - return p[0] == p[1] + return /* @@ label2 */p[0] == p[1] } } @@ -41,3 +41,6 @@ function main() { arktest.assertTrue(C.foo(new A, new B) == false) arktest.assertTrue(C.moo(12, new A, new B) == false) } + +/* @@@ label1 Error TypeError: Operator '==' cannot be applied to types 'A' and 'B'. */ +/* @@@ label2 Error TypeError: Operator '==' cannot be applied to types 'A' and 'B'. */ diff --git a/ets2panda/test/runtime/ets/RestTuple8.ets b/ets2panda/test/ast/compiler/ets/RestTuple8.ets similarity index 85% rename from ets2panda/test/runtime/ets/RestTuple8.ets rename to ets2panda/test/ast/compiler/ets/RestTuple8.ets index fb89b88ee80d58bde5cfbca089509b1cec1a36a0..1d4ebe1ae0887831889863df849150e2ddea5d1c 100644 --- a/ets2panda/test/runtime/ets/RestTuple8.ets +++ b/ets2panda/test/ast/compiler/ets/RestTuple8.ets @@ -20,11 +20,11 @@ class C { public field : boolean constructor(...p: [A, B]) { - this.field = p[0] == p[1] + this.field = /* @@ label1 */p[0] == p[1] } constructor(a: int, ...p: [A, B]) { - this.field = p[0] == p[1] + this.field = /* @@ label2 */p[0] == p[1] } } @@ -43,3 +43,6 @@ function main() { arktest.assertTrue((new C(new A, new B)).field == false) arktest.assertTrue((new C(22, new A, new B)).field == false) } + +/* @@@ label1 Error TypeError: Operator '==' cannot be applied to types 'A' and 'B'. */ +/* @@@ label2 Error TypeError: Operator '==' cannot be applied to types 'A' and 'B'. */ diff --git a/ets2panda/test/ast/compiler/ets/equality_null.ets b/ets2panda/test/ast/compiler/ets/equality_null.ets new file mode 100644 index 0000000000000000000000000000000000000000..de86e80dbe68648757f731ab08148e8e1fd85f7b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/equality_null.ets @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function foo1(a:number,b:undefined){ + if(a == b){} +} +function foo2(a:number|string,b:undefined){ + if(a == b){} +} +function foo3(a:number|null,b:string|undefined){ + if(/* @@ label1 */a == b){} +} +function foo4(a:number|undefined,b:string|undefined){ + if(a == b){} +} + +/* @@@ label1 Error TypeError: Operator '==' cannot be applied to types 'Double|null' and 'String|undefined'. */ diff --git a/ets2panda/test/ast/compiler/ets/equality_reference.ets b/ets2panda/test/ast/compiler/ets/equality_reference.ets new file mode 100644 index 0000000000000000000000000000000000000000..ab5eec4d546ac18e1157468ed4128c2b7df3a56b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/equality_reference.ets @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A{} +class B{} + +function main(){ + let map = new Map(); + let array = new Array(); + let a = new A(); + let b = new B(); + + let test1 = /* @@ label1 */map === 1; + let test2 = /* @@ label2 */array === 1; + let test3 = /* @@ label3 */a == b; + let test4 = /* @@ label4 */a == map; + let test5 = /* @@ label5 */b == array; + let test6 = /* @@ label6 */map == array; +} + +/* @@@ label1 Error TypeError: Operator '===' cannot be applied to types 'Map' and 'Int'. */ +/* @@@ label2 Error TypeError: Operator '===' cannot be applied to types 'Array' and 'Int'. */ +/* @@@ label3 Error TypeError: Operator '==' cannot be applied to types 'A' and 'B'. */ +/* @@@ label4 Error TypeError: Operator '==' cannot be applied to types 'A' and 'Map'. */ +/* @@@ label5 Error TypeError: Operator '==' cannot be applied to types 'B' and 'Array'. */ +/* @@@ label6 Error TypeError: Operator '==' cannot be applied to types 'Map' and 'Array'. */ diff --git a/ets2panda/test/ast/compiler/ets/equality_reference_2.ets b/ets2panda/test/ast/compiler/ets/equality_reference_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..852efc14bdaf21a0669da7781bb77dda65ebfa12 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/equality_reference_2.ets @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + x: string = "" +} +class B { + y: number = 1 +} +class C { + v: string|number = 2 +} +class D { + b = new A +} +class X extends A { + m: D = new D +} + +function f1(x: A|B, y: C|D) { + return /* @@ label1 */x == y +} + +function f2(x: A|B, y: C) { + return /* @@ label2 */x == y +} + +function f3(x: A, y: C) { + return /* @@ label3 */x == y +} + +function f4(x: A|B, y: C|X|D) { + return x == y +} + +function f5(x: A|T, y: C|D) { + return x == y +} + +function f6(x: A|T, y: C|D) { + return /* @@ label4 */x == y +} + +function f7(x: A, y: C|D|T) { + return x == y +} + +function f8(x: A[][], y: C|D|T[][]) { + return x == y +} + +function f9(x: ()=>A|B, y: ()=>C|D) { + return /* @@ label5 */x == y +} + +function f10(x: ()=>A|B, y: ()=>C|T) { + return x == y +} + +function f11(x: (p: string)=>A|B, y: (p: number)=>C|T) { + return /* @@ label6 */x == y +} + +function f12(x: (p: string)=>A|B, y: (p: "aa"|"bb"|number)=>C|T) { + return x == y +} + +function f13(x: (p: string)=>A|B, y: (p: "aa"|"bb"|number, q:A)=>C|T) { + return x == y +} + +function f14(x: (p: string)=>A|B, y: (p: "aa"|"bb"|number, q?:A)=>C|T) { + return x == y +} + +enum E1 {A = 1, B = 4} +enum E2 {A = "aa", B = "bb"} +function f15(x: E1) { + return x == 2 +} + +function f16(x: E1) { + return x == 4 +} + +function f17(x: E2) { + return x == "cc" +} + +function f18(a: short, b: long) { + return a == b +} + +/* @@@ label1 Error TypeError: Operator '==' cannot be applied to types 'A|B' and 'C|D'. */ +/* @@@ label2 Error TypeError: Operator '==' cannot be applied to types 'A|B' and 'C'. */ +/* @@@ label3 Error TypeError: Operator '==' cannot be applied to types 'A' and 'C'. */ +/* @@@ label4 Error TypeError: Operator '==' cannot be applied to types 'A' and 'C|D'. */ +/* @@@ label5 Error TypeError: Operator '==' cannot be applied to types '() => A|B' and '() => C|D'. */ +/* @@@ label6 Error TypeError: Operator '==' cannot be applied to types '(p: String) => A|B' and '(p: Double) => C|T'. */ diff --git a/ets2panda/test/ast/compiler/ets/referenceEqualityNotCastable_n.ets b/ets2panda/test/ast/compiler/ets/referenceEqualityNotCastable_n.ets index 51f4fc103e2a54f85a4f7cc30ba05034a6ebeabe..7ab8672e40fa0764068991c7da53a0704aa6d43d 100644 --- a/ets2panda/test/ast/compiler/ets/referenceEqualityNotCastable_n.ets +++ b/ets2panda/test/ast/compiler/ets/referenceEqualityNotCastable_n.ets @@ -22,4 +22,4 @@ function main(): void { let c = /* @@ label */a === b; } -/* @@@ label Node { "type": "BinaryExpression", "operator": "===" } */ +/* @@@ label Error TypeError: Operator '===' cannot be applied to types 'A' and 'B'. */ diff --git a/ets2panda/test/ast/compiler/ets/resolve_func_name_union_type.ets b/ets2panda/test/ast/compiler/ets/resolve_func_name_union_type.ets index 5cfc8c78642328650aac7d6c878559420bd02e27..63fa4303230bda5d52dffa24ce6f7073819c6f16 100644 --- a/ets2panda/test/ast/compiler/ets/resolve_func_name_union_type.ets +++ b/ets2panda/test/ast/compiler/ets/resolve_func_name_union_type.ets @@ -27,3 +27,4 @@ function main() { /* @@? 24:17 Error TypeError: Type '() => Double' cannot be assigned to type '() => void|Double' */ /* @@? 25:24 Error TypeError: Cannot use type 'void' as value. */ +/* @@? 25:24 Error TypeError: Operator '==' cannot be applied to types 'void' and 'Double'. */ diff --git a/ets2panda/test/ast/compiler/ets/union_string_literals_6.ets b/ets2panda/test/ast/compiler/ets/union_string_literals_6.ets index fe111c8edc03e57e698fd712bfbd2c24c29844da..ef6a0aa1ad40fd76418018d3f1a696208ef8fc3b 100644 --- a/ets2panda/test/ast/compiler/ets/union_string_literals_6.ets +++ b/ets2panda/test/ast/compiler/ets/union_string_literals_6.ets @@ -19,9 +19,7 @@ function id(v: Object): T { function main() { let s = id<"a"|"b"|"c">("d") - if (/* @@ label */s == "d") { + if (s == "d") { console.log(s) } } - -/* @@@ label Error TypeError: Operator '==' cannot be applied to types '"a"|"b"|"c"' and '"d"'. */ diff --git a/ets2panda/test/ast/parser/ets/rest_parameter_13.ets b/ets2panda/test/ast/parser/ets/rest_parameter_13.ets index 46f794926f745d3fcf69c72449cc26f3095e3e87..573f8ada1a069b38ad49e4cabd0c4f11e2f91aef 100644 --- a/ets2panda/test/ast/parser/ets/rest_parameter_13.ets +++ b/ets2panda/test/ast/parser/ets/rest_parameter_13.ets @@ -20,28 +20,30 @@ class C { public field : boolean constructor(...p: [A, B]) { - this.field = p[0] == p[1] + this.field = /* @@ label1 */p[0] == p[1] } constructor(a: int, ...p: [A, B]) { - this.field = p[0] == p[1] + this.field = /* @@ label2 */p[0] == p[1] } } function main() { - /* @@ label1 */new C - /* @@ label2 */new C(new A) - /* @@ label3 */new C(new A, new B, new B) + /* @@ label3 */new C + /* @@ label4 */new C(/* @@ label5 */new A) + /* @@ label6 */new C(/* @@ label7 */new A, new B, new B) } -/* @@@ label1 Error TypeError: Expected 1 arguments, got 0. */ -/* @@@ label1 Error TypeError: Expected 2 arguments, got 0. */ -/* @@@ label1 Error TypeError: Expected 3 arguments, got 0. */ -/* @@@ label1 Error TypeError: No matching construct signature */ -/* @@@ label2 Error TypeError: Expected 2 arguments, got 1. */ -/* @@@ label2 Error TypeError: Expected 3 arguments, got 1. */ -/* @@@ label2 Error TypeError: No matching construct signature for rest_parameter_13.C(A) */ -/* @@? 33:37 Error TypeError: Type 'A' is not compatible with type 'Int' at index 1 */ -/* @@@ label3 Error TypeError: Expected 2 arguments, got 3. */ -/* @@@ label3 Error TypeError: No matching construct signature for rest_parameter_13.C(A, B, B) */ -/* @@? 34:37 Error TypeError: Type 'A' is not compatible with type 'Int' at index 1 */ +/* @@@ label1 Error TypeError: Operator '==' cannot be applied to types 'A' and 'B'. */ +/* @@@ label2 Error TypeError: Operator '==' cannot be applied to types 'A' and 'B'. */ +/* @@@ label3 Error TypeError: Expected 1 arguments, got 0. */ +/* @@@ label3 Error TypeError: Expected 2 arguments, got 0. */ +/* @@@ label3 Error TypeError: Expected 3 arguments, got 0. */ +/* @@@ label3 Error TypeError: No matching construct signature */ +/* @@@ label4 Error TypeError: Expected 2 arguments, got 1. */ +/* @@@ label4 Error TypeError: Expected 3 arguments, got 1. */ +/* @@@ label4 Error TypeError: No matching construct signature for rest_parameter_13.C(A) */ +/* @@@ label5 Error TypeError: Type 'A' is not compatible with type 'Int' at index 1 */ +/* @@@ label6 Error TypeError: Expected 2 arguments, got 3. */ +/* @@@ label6 Error TypeError: No matching construct signature for rest_parameter_13.C(A, B, B) */ +/* @@@ label7 Error TypeError: Type 'A' is not compatible with type 'Int' at index 1 */ diff --git a/ets2panda/test/runtime/ets/overload_declaration/RestTuple8.ets b/ets2panda/test/runtime/ets/equal_numeric_bigint.ets similarity index 35% rename from ets2panda/test/runtime/ets/overload_declaration/RestTuple8.ets rename to ets2panda/test/runtime/ets/equal_numeric_bigint.ets index 5a33c0f26e7719e1fee0c255c6f87773127350b4..367873f1664060836bfdf555042e4eb0072bb976 100644 --- a/ets2panda/test/runtime/ets/overload_declaration/RestTuple8.ets +++ b/ets2panda/test/runtime/ets/equal_numeric_bigint.ets @@ -13,35 +13,13 @@ * limitations under the License. */ -class A { } -class B { } - -class C { - public field: boolean - - constructor constructor2(...p: [A, B]) { - this.field = p[0] == p[1] - } - - constructor constructor1(a: int, ...p: [A, B]) { - this.field = p[0] == p[1] - } - - overload constructor{ constructor1, constructor2 } -} - function main() { - let a1: [A, B] = [new A, new B] - - arktest.assertTrue((new C(...a1)).field == false) - arktest.assertTrue((new C(22, ...a1)).field == false) - - arktest.assertTrue((new C(...[new A, new B])).field == false) - arktest.assertTrue((new C(22, ...[new A, new B])).field == false) - - arktest.assertTrue((new C(...[new A, new B] as [A, B])).field == false) - arktest.assertTrue((new C(22, ...[new A, new B] as [A, B])).field == false) + const v0 = 1516532564n; + const v1 = 545314157; + arktest.assertFalse(v0 == v1); + test(v0, v1); +} - arktest.assertTrue((new C(new A, new B)).field == false) - arktest.assertTrue((new C(22, new A, new B)).field == false) +function test(a: BigInt, b: int) { + arktest.assertFalse(a == b); }