From 9c21466b09bec30ab4eead0e6aeb05cba1a0dfa4 Mon Sep 17 00:00:00 2001 From: yuxin Date: Tue, 30 Apr 2024 18:07:48 +0800 Subject: [PATCH] Fix widening and unboxing conversion of compatible types Check wether the constaint type is a final type and conduct type substitution Issue:#I9KVDD Test:ninja ets_tests & bash ets_testrunner.sh --cts -r -rt Signed-off-by: yuxin --- ets2panda/checker/ETSAnalyzer.cpp | 3 +++ ets2panda/checker/ets/typeRelationContext.cpp | 7 +++++++ ets2panda/checker/ets/typeRelationContext.h | 6 ++++++ ets2panda/checker/types/ets/etsTypeParameter.cpp | 15 ++++++++++++++- ets2panda/checker/types/ets/etsTypeParameter.h | 1 + 5 files changed, 31 insertions(+), 1 deletion(-) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 359b48f15b..20fc11bf0e 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -1082,6 +1082,9 @@ checker::Type *ETSAnalyzer::Check(ir::Identifier *expr) const ETSChecker *checker = GetETSChecker(); auto *identType = checker->ResolveIdentifier(expr); + if (identType->IsETSTypeParameter() && identType->AsETSTypeParameter()->IdenticalToFinalConstraint()) { + identType = identType->AsETSTypeParameter()->GetConstraintType(); + } if (expr->Variable() != nullptr && (expr->Parent() == nullptr || !expr->Parent()->IsAssignmentExpression() || expr != expr->Parent()->AsAssignmentExpression()->Left())) { if (auto *const smartType = checker->Context().GetSmartCast(expr->Variable()); smartType != nullptr) { diff --git a/ets2panda/checker/ets/typeRelationContext.cpp b/ets2panda/checker/ets/typeRelationContext.cpp index 7d03ff0b84..723dcbb5c8 100644 --- a/ets2panda/checker/ets/typeRelationContext.cpp +++ b/ets2panda/checker/ets/typeRelationContext.cpp @@ -41,6 +41,13 @@ void AssignmentContext::ValidateArrayTypeInitializerByElement(TypeRelation *rela } } +void AssignmentContext::MaybeFinalSubstitute(Type *&type) +{ + if (type->IsETSTypeParameter() && type->AsETSTypeParameter()->IdenticalToFinalConstraint()) { + type = type->AsETSTypeParameter()->GetConstraintType(); + } +} + bool InstantiationContext::ValidateTypeArguments(ETSObjectType *type, ir::TSTypeParameterInstantiation *typeArgs, const lexer::SourcePosition &pos) { diff --git a/ets2panda/checker/ets/typeRelationContext.h b/ets2panda/checker/ets/typeRelationContext.h index 9e5943cc65..8ec9d097cb 100644 --- a/ets2panda/checker/ets/typeRelationContext.h +++ b/ets2panda/checker/ets/typeRelationContext.h @@ -41,6 +41,9 @@ public: flags_ |= flags; relation->SetNode(node); + MaybeFinalSubstitute(source); + MaybeFinalSubstitute(target); + // NOTE (oeotvos) The narrowing flag will be applied here. It means, that the result of "let tmp: int = 1.5" // will be 1, which could cause problems. if (source->HasTypeFlag(TypeFlag::CONSTANT)) { @@ -75,6 +78,8 @@ public: void ValidateArrayTypeInitializerByElement(TypeRelation *relation, ir::ArrayExpression *node, ETSArrayType *target); + void MaybeFinalSubstitute(Type *&type); + private: TypeRelationFlag flags_ = TypeRelationFlag::IN_ASSIGNMENT_CONTEXT; bool assignable_ {false}; @@ -94,6 +99,7 @@ public: auto *const etsChecker = relation->GetChecker()->AsETSChecker(); relation->SetNode(node); + relation->SetFlags(flags_ | initialFlags); if (!relation->IsAssignableTo(source, target)) { diff --git a/ets2panda/checker/types/ets/etsTypeParameter.cpp b/ets2panda/checker/types/ets/etsTypeParameter.cpp index 0ae9a6f2b5..3108ffb3f4 100644 --- a/ets2panda/checker/types/ets/etsTypeParameter.cpp +++ b/ets2panda/checker/types/ets/etsTypeParameter.cpp @@ -131,4 +131,17 @@ ETSTypeParameter *ETSTypeParameter::GetOriginal() const return GetDeclNode()->Name()->Variable()->TsType()->AsETSTypeParameter(); } -} // namespace ark::es2panda::checker +bool ETSTypeParameter::IdenticalToFinalConstraint() const +{ + if (constraint_ == nullptr) { + return false; + } + + if (constraint_->Variable() != nullptr && constraint_->Variable()->Declaration() != nullptr) { + auto declNode = constraint_->Variable()->Declaration()->Node(); + return declNode != nullptr && declNode->IsFinal(); + } + return false; +} + +} // namespace ark::es2panda::checker \ No newline at end of file diff --git a/ets2panda/checker/types/ets/etsTypeParameter.h b/ets2panda/checker/types/ets/etsTypeParameter.h index ed35e3cf64..c8d0d45dcb 100644 --- a/ets2panda/checker/types/ets/etsTypeParameter.h +++ b/ets2panda/checker/types/ets/etsTypeParameter.h @@ -71,6 +71,7 @@ public: void IsSubtypeOf(TypeRelation *relation, Type *target) override; Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; Type *Substitute(TypeRelation *relation, const Substitution *substitution) override; + bool IdenticalToFinalConstraint() const; void ToAssemblerType(std::stringstream &ss) const override; void ToDebugInfoType(std::stringstream &ss) const override; -- Gitee