From 4a15b7b1d87e722d44a90a1a8068308c85c0cc21 Mon Sep 17 00:00:00 2001 From: Anna Rift Date: Tue, 3 Sep 2024 12:32:37 -0700 Subject: [PATCH 1/5] Add test for calling method on generic-inheriting class Signed-off-by: Anna Rift --- frontend/test/resolution/testInitSemantics.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontend/test/resolution/testInitSemantics.cpp b/frontend/test/resolution/testInitSemantics.cpp index 4559c7d7b66a..262c0c6934b4 100644 --- a/frontend/test/resolution/testInitSemantics.cpp +++ b/frontend/test/resolution/testInitSemantics.cpp @@ -1348,9 +1348,14 @@ static void testInheritance() { proc init(type A) { super.init(A); } + + proc doNothing() {} } var x = new Child(int); + + // ensure we can call a method on this receiver type after init + x.doNothing(); )"""; auto vars = resolveTypesOfVariables(context, program, {"x"}); From c119fe5f2a34b1767b8617016bdd03d1a544a9de Mon Sep 17 00:00:00 2001 From: Anna Rift Date: Tue, 3 Sep 2024 12:08:49 -0700 Subject: [PATCH 2/5] Enable setting instantiatedFrom for classes generic due to inherit Signed-off-by: Anna Rift --- frontend/include/chpl/types/CompositeType.h | 7 +++++-- frontend/lib/resolution/InitResolver.cpp | 8 +++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/frontend/include/chpl/types/CompositeType.h b/frontend/include/chpl/types/CompositeType.h index 928b442e480a..042417ea79ba 100644 --- a/frontend/include/chpl/types/CompositeType.h +++ b/frontend/include/chpl/types/CompositeType.h @@ -117,8 +117,11 @@ class CompositeType : public Type { CHPL_ASSERT(instantiatedFrom_ == nullptr || instantiatedFrom_->instantiatedFrom_ == nullptr); - // check that subs is consistent with instantiatedFrom - CHPL_ASSERT((instantiatedFrom_ == nullptr) == subs_.empty()); + // check that subs is consistent with instantiatedFrom, except in the + // case of class types which can be generic with empty subs due to + // inheritance + CHPL_ASSERT(tag == typetags::BasicClassType || + (instantiatedFrom_ == nullptr) == subs_.empty()); } bool compositeTypeContentsMatchInner(const CompositeType* other) const { diff --git a/frontend/lib/resolution/InitResolver.cpp b/frontend/lib/resolution/InitResolver.cpp index f5bc7c652ee1..d4f435310447 100644 --- a/frontend/lib/resolution/InitResolver.cpp +++ b/frontend/lib/resolution/InitResolver.cpp @@ -279,13 +279,15 @@ static const Type* ctFromSubs(Context* context, auto oldBasic = cls->basicClassType(); CHPL_ASSERT(oldBasic && "Not handled!"); - auto instantatiatedFrom = subs.size() == 0 ? nullptr : - root->toBasicClassType(); + bool genericParent = superType && superType->substitutions().size() != 0; + auto instantiatedFrom = (subs.size() == 0 && !genericParent) + ? nullptr + : root->toBasicClassType(); auto basic = BasicClassType::get(context, oldBasic->id(), oldBasic->name(), superType, - instantatiatedFrom, + instantiatedFrom, subs); auto manager = AnyOwnedType::get(context); auto dec = ClassTypeDecorator(ClassTypeDecorator::BORROWED_NONNIL); From 67dda3e6f25f1f3185ef04004d90dc9c2a91491f Mon Sep 17 00:00:00 2001 From: Anna Rift Date: Tue, 3 Sep 2024 13:25:02 -0700 Subject: [PATCH 3/5] Add test for genericity via generic grandparent Signed-off-by: Anna Rift --- .../test/resolution/testInitSemantics.cpp | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/frontend/test/resolution/testInitSemantics.cpp b/frontend/test/resolution/testInitSemantics.cpp index 262c0c6934b4..18ff5421e52e 100644 --- a/frontend/test/resolution/testInitSemantics.cpp +++ b/frontend/test/resolution/testInitSemantics.cpp @@ -1365,6 +1365,46 @@ static void testInheritance() { x.type()->stringify(ss, chpl::StringifyKind::CHPL_SYNTAX); assert(ss.str() == "owned Child(int(64))"); } + + // Generic grandparent, concrete parent, concrete child + { + Context ctx; + Context* context = &ctx; + ErrorGuard guard(context); + + std::string program = R"""( + class Grandparent { + type A; + } + + class Parent : Grandparent { + proc init(type A) { + super.init(A); + } + } + + class Child : Parent { + + proc init(type A) { + super.init(A); + } + + proc doNothing() {} + } + + var x = new Child(int); + + // ensure we can call a method on this receiver type after init + x.doNothing(); + )"""; + + auto vars = resolveTypesOfVariables(context, program, {"x"}); + auto x = vars["x"]; + + std::stringstream ss; + x.type()->stringify(ss, chpl::StringifyKind::CHPL_SYNTAX); + assert(ss.str() == "owned Child(int(64))"); + } } static void testInitGenericAfterConcrete() { From a5a8aab786da9289bf955d7d0f7c0364a2d5fd47 Mon Sep 17 00:00:00 2001 From: Anna Rift Date: Tue, 3 Sep 2024 13:22:05 -0700 Subject: [PATCH 4/5] Also account for genericity via grandparent Signed-off-by: Anna Rift --- frontend/lib/resolution/InitResolver.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frontend/lib/resolution/InitResolver.cpp b/frontend/lib/resolution/InitResolver.cpp index d4f435310447..2b23ff2f2b6f 100644 --- a/frontend/lib/resolution/InitResolver.cpp +++ b/frontend/lib/resolution/InitResolver.cpp @@ -279,7 +279,8 @@ static const Type* ctFromSubs(Context* context, auto oldBasic = cls->basicClassType(); CHPL_ASSERT(oldBasic && "Not handled!"); - bool genericParent = superType && superType->substitutions().size() != 0; + bool genericParent = + superType && superType->instantiatedFromCompositeType() != nullptr; auto instantiatedFrom = (subs.size() == 0 && !genericParent) ? nullptr : root->toBasicClassType(); @@ -311,7 +312,8 @@ const Type* InitResolver::computeReceiverTypeConsideringState(void) { DefaultsPolicy::USE_DEFAULTS); CompositeType::SubstitutionsMap subs; - bool genericParent = superType_ && superType_->substitutions().size() != 0; + bool genericParent = + superType_ && superType_->instantiatedFromCompositeType() != nullptr; if (!rfNoDefaults.isGeneric()) { if (genericParent) { From f80630ee773fbcf6cf11e27a9b59151ed077d41b Mon Sep 17 00:00:00 2001 From: Anna Rift Date: Tue, 3 Sep 2024 13:22:48 -0700 Subject: [PATCH 5/5] Use subs.empty() instead of .size() == 0 Signed-off-by: Anna Rift --- frontend/lib/resolution/InitResolver.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/frontend/lib/resolution/InitResolver.cpp b/frontend/lib/resolution/InitResolver.cpp index 2b23ff2f2b6f..7118f0204314 100644 --- a/frontend/lib/resolution/InitResolver.cpp +++ b/frontend/lib/resolution/InitResolver.cpp @@ -270,8 +270,7 @@ static const Type* ctFromSubs(Context* context, const Type* ret = nullptr; if (auto rec = receiverType->toRecordType()) { - auto instantatiatedFrom = subs.size() == 0 ? nullptr : - root->toRecordType(); + auto instantatiatedFrom = subs.empty() ? nullptr : root->toRecordType(); ret = RecordType::get(context, rec->id(), rec->name(), instantatiatedFrom, subs); @@ -281,9 +280,8 @@ static const Type* ctFromSubs(Context* context, bool genericParent = superType && superType->instantiatedFromCompositeType() != nullptr; - auto instantiatedFrom = (subs.size() == 0 && !genericParent) - ? nullptr - : root->toBasicClassType(); + auto instantiatedFrom = + (subs.empty() && !genericParent) ? nullptr : root->toBasicClassType(); auto basic = BasicClassType::get(context, oldBasic->id(), oldBasic->name(), @@ -368,7 +366,7 @@ const Type* InitResolver::computeReceiverTypeConsideringState(void) { } } - if (subs.size() != 0 || genericParent) { + if (!subs.empty() || genericParent) { const Type* ret = ctFromSubs(ctx_, initialRecvType_, superType_, ctInitial, subs); CHPL_ASSERT(ret); return ret;