From 77a34f7fdb2359096fad9d4fee6817c8600314d4 Mon Sep 17 00:00:00 2001 From: Ben Harshbarger Date: Sun, 24 Nov 2024 18:44:20 -0800 Subject: [PATCH 1/9] Implement implicit 'size' field for tuples in typeForId Signed-off-by: Ben Harshbarger --- frontend/lib/resolution/Resolver.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/frontend/lib/resolution/Resolver.cpp b/frontend/lib/resolution/Resolver.cpp index ff7d8a87d986..b947214fd362 100644 --- a/frontend/lib/resolution/Resolver.cpp +++ b/frontend/lib/resolution/Resolver.cpp @@ -2704,6 +2704,17 @@ QualifiedType Resolver::typeForId(const ID& id, bool localGenericToUnknown) { } } + if (auto tup = rt->toTupleType()) { + auto field = parsing::idToAst(context, id)->toNamedDecl(); + if (field && field->name() == USTR("size")) { + // Tuples don't store a 'size' in their substitutions map, so + // manually take care of things here. + auto intType = IntType::get(context, 0); + auto val = IntParam::get(context, tup->numElements()); + return QualifiedType(QualifiedType::PARAM, intType, val); + } + } + if (auto comprt = rt->getCompositeType()) { if (comprt->id() == parentId) { ct = comprt; // handle record, class with field From 613a56ee628ef2410bf4e2604be232d99841e637 Mon Sep 17 00:00:00 2001 From: Ben Harshbarger Date: Sun, 24 Nov 2024 19:05:26 -0800 Subject: [PATCH 2/9] Handle class types to avoid resolving init= on classes Signed-off-by: Ben Harshbarger --- frontend/lib/types/Type.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/lib/types/Type.cpp b/frontend/lib/types/Type.cpp index 14d0a1eef22f..4e0149d9a5c3 100644 --- a/frontend/lib/types/Type.cpp +++ b/frontend/lib/types/Type.cpp @@ -242,6 +242,10 @@ static bool compositeTypeIsPod(Context* context, const Type* t) { using namespace resolution; + if (auto cls = t->toClassType()) { + return !cls->decorator().isManaged(); + } + auto ct = t->getCompositeType(); if (!ct) return false; From 07eecabe8bbd535cb982c75c4a8e238b17d552b7 Mon Sep 17 00:00:00 2001 From: Ben Harshbarger Date: Sun, 24 Nov 2024 19:28:17 -0800 Subject: [PATCH 3/9] Remove whitespace Signed-off-by: Ben Harshbarger --- frontend/lib/resolution/resolution-queries.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/lib/resolution/resolution-queries.cpp b/frontend/lib/resolution/resolution-queries.cpp index 5fb3b01b47bb..3e82c365041e 100644 --- a/frontend/lib/resolution/resolution-queries.cpp +++ b/frontend/lib/resolution/resolution-queries.cpp @@ -5029,7 +5029,7 @@ resolveCallInMethod(ResolutionContext* rc, std::vector* rejected) { CallResolutionResult asFunction = resolveCall(rc,call,ci,inScopes,rejected); - + CallResolutionResult asMethod; if (shouldAttemptImplicitReceiver(ci, implicitReceiver)) { auto methodCi = CallInfo::createWithReceiver(ci, implicitReceiver); From e71ab0899ddcc9c7ff84689f2d172bf0871aedd7 Mon Sep 17 00:00:00 2001 From: Ben Harshbarger Date: Sun, 24 Nov 2024 19:36:35 -0800 Subject: [PATCH 4/9] Build uAST for 'init=' Builds a signature and body for 'init='. An open TODO is to constrain the type of 'other' to be the same as the type being initialized. While there, refactor some common logic with 'init'. Signed-off-by: Ben Harshbarger --- frontend/lib/resolution/default-functions.cpp | 182 +++++++++++------- 1 file changed, 110 insertions(+), 72 deletions(-) diff --git a/frontend/lib/resolution/default-functions.cpp b/frontend/lib/resolution/default-functions.cpp index ad668ea3bdd9..77df0e51773d 100644 --- a/frontend/lib/resolution/default-functions.cpp +++ b/frontend/lib/resolution/default-functions.cpp @@ -163,55 +163,6 @@ needCompilerGeneratedMethod(Context* context, const Type* type, return false; } -// generates the untyped function signature and typed function -// signature formal entries for the 'this' method receiver for -// some kind of 'init' or 'init=' -static void -generateInitParts(Context* context, - const CompositeType* inCompType, - const CompositeType*& compType, - std::vector& ufsFormals, - std::vector& formalTypes, - bool useGeneric) { - // adjust to refer to fully generic signature if needed - auto genericCompType = inCompType->instantiatedFromCompositeType(); - if (useGeneric && genericCompType != nullptr) { - compType = genericCompType; - } else { - compType = inCompType; - } - - // start by adding a formal for the receiver - auto ufsReceiver = - UntypedFnSignature::FormalDetail(USTR("this"), - UntypedFnSignature::DK_NO_DEFAULT, - nullptr); - ufsFormals.push_back(std::move(ufsReceiver)); - - // Determine the receiver type and intent. - QualifiedType qtReceiver; - - // If the receiver is a record type, just give it the 'ref' intent. - if (compType->isRecordType() || compType->isUnionType()) { - qtReceiver = QualifiedType(QualifiedType::REF, compType); - - // If the receiver is a basic class C, use 'const in x: borrowed C'. - } else if (auto basic = compType->toBasicClassType()) { - const Type* manager = nullptr; - auto borrowedNonnilDecor = - ClassTypeDecorator(ClassTypeDecorator::BORROWED_NONNIL); - auto receiverType = - ClassType::get(context, basic, manager, borrowedNonnilDecor); - CHPL_ASSERT(receiverType); - qtReceiver = QualifiedType(QualifiedType::CONST_IN, receiverType); - - } else { - CHPL_ASSERT(false && "Not possible!"); - } - - formalTypes.push_back(std::move(qtReceiver)); -} - static bool initHelper(Context* context, Builder* builder, const AggregateDecl* typeDecl, @@ -406,18 +357,8 @@ const BuilderResult& buildInitializer(Context* context, ID typeID) { return QUERY_END(result); } -static const TypedFnSignature* -generateInitSignature(Context* context, const CompositeType* inCompType) { - if (auto ct = inCompType->getCompositeType()->toBasicClassType()) { - if (ct->isObjectType()) { - return nullptr; - } - } - - auto& br = buildInitializer(context, inCompType->id()); - - auto initFn = br.topLevelExpression(0)->toFunction(); - +static std::vector +buildInitUfsFormals(const uast::Function* initFn) { // compute the FormalDetails manually so that we can set the default-kind // appropriately. // @@ -427,14 +368,19 @@ generateInitSignature(Context* context, const CompositeType* inCompType) { for (auto decl : initFn->formals()) { UniqueString name; bool hasDefault = false; + if (auto formal = decl->toFormal()) { name = formal->name(); - hasDefault = formal->initExpression() != nullptr; - if (decl != initFn->thisFormal()) { - if (formal->intent() != Formal::Intent::TYPE && - formal->intent() != Formal::Intent::PARAM) { - if (formal->typeExpression() != nullptr) { - hasDefault = true; + + // Check if formal should have a default, which is never true for init= + if (initFn->name() != USTR("init=")) { + hasDefault = formal->initExpression() != nullptr; + if (decl != initFn->thisFormal()) { + if (formal->intent() != Formal::Intent::TYPE && + formal->intent() != Formal::Intent::PARAM) { + if (formal->typeExpression() != nullptr) { + hasDefault = true; + } } } } @@ -447,6 +393,22 @@ generateInitSignature(Context* context, const CompositeType* inCompType) { formals.push_back(fd); } + return formals; +} + +static const TypedFnSignature* +generateInitSignature(Context* context, const CompositeType* inCompType) { + if (auto ct = inCompType->getCompositeType()->toBasicClassType()) { + if (ct->isObjectType()) { + return nullptr; + } + } + + auto& br = buildInitializer(context, inCompType->id()); + + auto initFn = br.topLevelExpression(0)->toFunction(); + auto formals = buildInitUfsFormals(initFn); + // find the unique-ified untyped signature auto uSig = UntypedFnSignature::get(context, initFn->id(), initFn->name(), true, @@ -462,14 +424,90 @@ generateInitSignature(Context* context, const CompositeType* inCompType) { return typedSignatureInitial(&rcval, uSig); } +const BuilderResult& buildInitEquals(Context* context, ID typeID) { + QUERY_BEGIN(buildInitEquals, context, typeID); + + auto typeDecl = parsing::idToAst(context, typeID)->toAggregateDecl(); + auto bld = Builder::createForGeneratedCode(context, typeID); + auto builder = bld.get(); + auto dummyLoc = parsing::locateId(context, typeID); + + auto thisType = Identifier::build(builder, dummyLoc, typeDecl->name()); + auto thisFormal = Formal::build(builder, dummyLoc, nullptr, + USTR("this"), Formal::DEFAULT_INTENT, + std::move(thisType), nullptr); + + auto otherName = UniqueString::get(context, "other"); + auto otherFormal = Formal::build(builder, dummyLoc, nullptr, + otherName, Formal::DEFAULT_INTENT, + nullptr, nullptr); + AstList formals; + formals.push_back(std::move(otherFormal)); + + AstList stmts; + + std::vector fields; + for (auto d : typeDecl->decls()) { + collectFields(d, fields); + } + + for (auto field : fields) { + // Create 'this.field = other.field;' statement + owned lhs = Dot::build(builder, dummyLoc, + Identifier::build(builder, dummyLoc, USTR("this")), + field->name()); + owned rhs = Dot::build(builder, dummyLoc, + Identifier::build(builder, dummyLoc, otherName), + field->name()); + owned assign = OpCall::build(builder, dummyLoc, USTR("="), + std::move(lhs), std::move(rhs)); + stmts.push_back(std::move(assign)); + } + + auto body = Block::build(builder, dummyLoc, std::move(stmts)); + auto genFn = Function::build(builder, + dummyLoc, {}, + Decl::Visibility::PUBLIC, + Decl::Linkage::DEFAULT_LINKAGE, + /*linkageName=*/{}, + USTR("init="), + /*inline=*/false, /*override=*/false, + Function::Kind::PROC, + /*receiver=*/std::move(thisFormal), + Function::ReturnIntent::DEFAULT_RETURN_INTENT, + // throws, primaryMethod, parenless + false, false, false, + std::move(formals), + // returnType, where, lifetime, body + {}, {}, {}, std::move(body)); + + builder->noteChildrenLocations(genFn.get(), dummyLoc); + builder->addToplevelExpression(std::move(genFn)); + + auto result = builder->result(); + return QUERY_END(result); +} + static const TypedFnSignature* generateInitCopySignature(Context* context, const CompositeType* inCompType) { - const CompositeType* compType = nullptr; - std::vector ufsFormals; - std::vector formalTypes; + auto& br = buildInitEquals(context, inCompType->id()); + auto initFn = br.topLevelExpression(0)->toFunction(); + auto formals = buildInitUfsFormals(initFn); - generateInitParts(context, inCompType, compType, - ufsFormals, formalTypes, /*useGeneric*/ false); + // find the unique-ified untyped signature + auto uSig = UntypedFnSignature::get(context, initFn->id(), initFn->name(), + true, + /* isTypeConstructor */ false, + /* isCompilerGenerated */ true, + /* throws */ false, + /* idTag */ asttags::Function, + uast::Function::Kind::PROC, + std::move(formals), nullptr, + inCompType->id()); + + ResolutionContext rcval(context); + return typedSignatureInitial(&rcval, uSig); +} // add a formal for the 'other' argument auto name = UniqueString::get(context, "other"); From 4f9bc31a4155875117d16bc7e24e0b4a72043118 Mon Sep 17 00:00:00 2001 From: Ben Harshbarger Date: Sun, 24 Nov 2024 19:38:56 -0800 Subject: [PATCH 5/9] Add TODO for init= argument type Signed-off-by: Ben Harshbarger --- frontend/lib/resolution/default-functions.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/lib/resolution/default-functions.cpp b/frontend/lib/resolution/default-functions.cpp index 77df0e51773d..a2636e8dc575 100644 --- a/frontend/lib/resolution/default-functions.cpp +++ b/frontend/lib/resolution/default-functions.cpp @@ -437,6 +437,7 @@ const BuilderResult& buildInitEquals(Context* context, ID typeID) { USTR("this"), Formal::DEFAULT_INTENT, std::move(thisType), nullptr); + // TODO: constrain type to be same as 'typeID', possibly through 'this.type'? auto otherName = UniqueString::get(context, "other"); auto otherFormal = Formal::build(builder, dummyLoc, nullptr, otherName, Formal::DEFAULT_INTENT, From c8f9d514d447efabe3d4694e66398ef848c5df12 Mon Sep 17 00:00:00 2001 From: Ben Harshbarger Date: Sun, 24 Nov 2024 19:40:09 -0800 Subject: [PATCH 6/9] Generate uAST for 'deinit' Signed-off-by: Ben Harshbarger --- frontend/lib/resolution/default-functions.cpp | 95 +++++++++---------- 1 file changed, 46 insertions(+), 49 deletions(-) diff --git a/frontend/lib/resolution/default-functions.cpp b/frontend/lib/resolution/default-functions.cpp index a2636e8dc575..abca94f61a7e 100644 --- a/frontend/lib/resolution/default-functions.cpp +++ b/frontend/lib/resolution/default-functions.cpp @@ -510,78 +510,75 @@ generateInitCopySignature(Context* context, const CompositeType* inCompType) { return typedSignatureInitial(&rcval, uSig); } - // add a formal for the 'other' argument - auto name = UniqueString::get(context, "other"); - auto defaultKind = UntypedFnSignature::DK_NO_DEFAULT; - const uast::Decl* node = nullptr; +const BuilderResult& buildDeinit(Context* context, ID typeID) { + QUERY_BEGIN(buildDeinit, context, typeID); - auto fd = UntypedFnSignature::FormalDetail(name, defaultKind, node); - ufsFormals.push_back(std::move(fd)); + auto bld = Builder::createForGeneratedCode(context, typeID); + auto builder = bld.get(); + auto dummyLoc = parsing::locateId(context, typeID); - CHPL_ASSERT(formalTypes.size() == 1); - auto otherType = QualifiedType(QualifiedType::CONST_REF, - formalTypes[0].type()); - formalTypes.push_back(std::move(otherType)); + auto thisType = Identifier::build(builder, dummyLoc, typeID.symbolName(context)); + auto thisFormal = Formal::build(builder, dummyLoc, nullptr, + USTR("this"), Formal::DEFAULT_INTENT, + std::move(thisType), nullptr); - // build the untyped signature - auto ufs = UntypedFnSignature::get(context, - /*id*/ compType->id(), - /*name*/ USTR("init="), - /*isMethod*/ true, - /*isTypeConstructor*/ false, - /*isCompilerGenerated*/ true, - /*throws*/ false, - /*idTag*/ parsing::idToTag(context, compType->id()), - /*kind*/ uast::Function::Kind::PROC, - /*formals*/ std::move(ufsFormals), - /*whereClause*/ nullptr); + AstList formals; - // now build the other pieces of the typed signature - auto ret = TypedFnSignature::get(context, - ufs, - std::move(formalTypes), - TypedFnSignature::WHERE_NONE, - /*needsInstantiation*/ false, - /* instantiatedFrom */ nullptr, - /* parentFn */ nullptr, - /* formalsInstantiated */ Bitmap(), - /* outerVariables */ {}); + // Empty body. Easier to let other parts of resolution infer the contents. + // TODO: Insert call to parent deinit + AstList stmts; + auto body = Block::build(builder, dummyLoc, std::move(stmts)); - return ret; + auto genFn = Function::build(builder, + dummyLoc, {}, + Decl::Visibility::PUBLIC, + Decl::Linkage::DEFAULT_LINKAGE, + /*linkageName=*/{}, + USTR("deinit"), + /*inline=*/false, /*override=*/false, + Function::Kind::PROC, + /*receiver=*/std::move(thisFormal), + Function::ReturnIntent::DEFAULT_RETURN_INTENT, + // throws, primaryMethod, parenless + false, false, false, + std::move(formals), + // returnType, where, lifetime, body + {}, {}, {}, std::move(body)); + + builder->noteChildrenLocations(genFn.get(), dummyLoc); + builder->addToplevelExpression(std::move(genFn)); + + auto result = builder->result(); + return QUERY_END(result); } static const TypedFnSignature* generateDeinitSignature(Context* context, const CompositeType* inCompType) { - const CompositeType* compType = nullptr; std::vector ufsFormals; - std::vector formalTypes; + auto& br = buildDeinit(context, inCompType->id()); + auto deinitFn = br.topLevelExpression(0)->toFunction(); - generateInitParts(context, inCompType, compType, - ufsFormals, formalTypes, /*useGeneric*/ false); + auto fd = UntypedFnSignature::FormalDetail(USTR("this"), + UntypedFnSignature::DK_NO_DEFAULT, + deinitFn->thisFormal(), false); + ufsFormals.push_back(fd); // build the untyped signature auto ufs = UntypedFnSignature::get(context, - /*id*/ compType->id(), + /*id*/ deinitFn->id(), /*name*/ USTR("deinit"), /*isMethod*/ true, /*isTypeConstructor*/ false, /*isCompilerGenerated*/ true, /*throws*/ false, - /*idTag*/ parsing::idToTag(context, compType->id()), + /*idTag*/ asttags::Function, /*kind*/ uast::Function::Kind::PROC, /*formals*/ std::move(ufsFormals), /*whereClause*/ nullptr); - // now build the other pieces of the typed signature - auto ret = TypedFnSignature::get(context, - ufs, - std::move(formalTypes), - TypedFnSignature::WHERE_NONE, - /*needsInstantiation*/ false, - /* instantiatedFrom */ nullptr, - /* parentFn */ nullptr, - /* formalsInstantiated */ Bitmap(), - /* outerVariables */ {}); + ResolutionContext rcval(context); + return typedSignatureInitial(&rcval, ufs); +} return ret; } From 07585d5fa0a9c38dbb0f75747ac436a8958e3d38 Mon Sep 17 00:00:00 2001 From: Ben Harshbarger Date: Sun, 24 Nov 2024 19:40:40 -0800 Subject: [PATCH 7/9] Generate uAST for serialize/deserialize Signed-off-by: Ben Harshbarger --- frontend/lib/resolution/default-functions.cpp | 94 ++++++++++++------- 1 file changed, 58 insertions(+), 36 deletions(-) diff --git a/frontend/lib/resolution/default-functions.cpp b/frontend/lib/resolution/default-functions.cpp index abca94f61a7e..d916de7762d0 100644 --- a/frontend/lib/resolution/default-functions.cpp +++ b/frontend/lib/resolution/default-functions.cpp @@ -580,7 +580,54 @@ generateDeinitSignature(Context* context, const CompositeType* inCompType) { return typedSignatureInitial(&rcval, ufs); } - return ret; +const BuilderResult& buildDeSerialize(Context* context, ID typeID, bool isSerializer) { + QUERY_BEGIN(buildDeSerialize, context, typeID, isSerializer); + + // TODO: + // - use types for formals + // - add calls to (de)serializeDefaultImpl + + auto bld = Builder::createForGeneratedCode(context, typeID); + auto builder = bld.get(); + auto dummyLoc = parsing::locateId(context, typeID); + + auto thisType = Identifier::build(builder, dummyLoc, typeID.symbolName(context)); + auto thisFormal = Formal::build(builder, dummyLoc, nullptr, + USTR("this"), Formal::DEFAULT_INTENT, + std::move(thisType), nullptr); + + auto writerArg = Formal::build(builder, dummyLoc, nullptr, UniqueString::get(context, "writer"), + Formal::DEFAULT_INTENT, {}, nullptr); + auto serializerArg = Formal::build(builder, dummyLoc, nullptr, UniqueString::get(context, "serializer"), + Formal::DEFAULT_INTENT, {}, nullptr); + AstList formals; + formals.push_back(std::move(writerArg)); + formals.push_back(std::move(serializerArg)); + + AstList stmts; + auto body = Block::build(builder, dummyLoc, std::move(stmts)); + + auto genFn = Function::build(builder, + dummyLoc, {}, + Decl::Visibility::PUBLIC, + Decl::Linkage::DEFAULT_LINKAGE, + /*linkageName=*/{}, + USTR("serialize"), + /*inline=*/false, /*override=*/false, + Function::Kind::PROC, + /*receiver=*/std::move(thisFormal), + Function::ReturnIntent::DEFAULT_RETURN_INTENT, + // throws, primaryMethod, parenless + true, false, false, + std::move(formals), + // returnType, where, lifetime, body + {}, {}, {}, std::move(body)); + + builder->noteChildrenLocations(genFn.get(), dummyLoc); + builder->addToplevelExpression(std::move(genFn)); + + auto result = builder->result(); + return QUERY_END(result); } static const TypedFnSignature* @@ -590,62 +637,37 @@ generateDeSerialize(Context* context, const CompositeType* compType, std::vector ufsFormals; std::vector formalTypes; + auto& br = buildDeSerialize(context, compType->id(), name == USTR("serialize")); + auto genFn = br.topLevelExpression(0)->toFunction(); + ufsFormals.push_back( UntypedFnSignature::FormalDetail(USTR("this"), UntypedFnSignature::DK_NO_DEFAULT, - nullptr)); - - QualifiedType thisType; - if (compType->isBasicClassType()) { - const Type* manager = nullptr; - auto borrowedNonnilDecor = - ClassTypeDecorator(ClassTypeDecorator::BORROWED_NONNIL); - auto receiverType = - ClassType::get(context, compType->toBasicClassType(), manager, borrowedNonnilDecor); - thisType = QualifiedType(QualifiedType::CONST_IN, receiverType); - } else { - thisType =QualifiedType(QualifiedType::CONST_REF, compType); - } - formalTypes.push_back(thisType); - - // TODO: Add constraints to these arguments + genFn->thisFormal())); ufsFormals.push_back( UntypedFnSignature::FormalDetail(UniqueString::get(context, channel), UntypedFnSignature::DK_NO_DEFAULT, - nullptr)); - formalTypes.push_back(QualifiedType(QualifiedType::CONST_REF, AnyType::get(context))); - + genFn->formal(0))); ufsFormals.push_back( UntypedFnSignature::FormalDetail(UniqueString::get(context, deSerializer), UntypedFnSignature::DK_NO_DEFAULT, - nullptr)); - formalTypes.push_back(QualifiedType(QualifiedType::REF, AnyType::get(context))); + genFn->formal(1))); // build the untyped signature auto ufs = UntypedFnSignature::get(context, - /*id*/ compType->id(), + /*id*/ genFn->id(), /*name*/ name, /*isMethod*/ true, /*isTypeConstructor*/ false, /*isCompilerGenerated*/ true, /*throws*/ true, - /*idTag*/ parsing::idToTag(context, compType->id()), + /*idTag*/ asttags::Function, /*kind*/ uast::Function::Kind::PROC, /*formals*/ std::move(ufsFormals), /*whereClause*/ nullptr); - // now build the other pieces of the typed signature - auto ret = TypedFnSignature::get(context, - ufs, - std::move(formalTypes), - TypedFnSignature::WHERE_NONE, - /*needsInstantiation*/ false, - /* instantiatedFrom */ nullptr, - /* parentFn */ nullptr, - /* formalsInstantiated */ Bitmap(), - /* outerVariables */ {}); - - return ret; + ResolutionContext rcval(context); + return typedSignatureInitial(&rcval, ufs); } static const TypedFnSignature* From f825dd9738eef9b18c816f6b1d5e89a7d7e3653b Mon Sep 17 00:00:00 2001 From: Ben Harshbarger Date: Sun, 24 Nov 2024 19:41:19 -0800 Subject: [PATCH 8/9] Wire up new helpers in 'builderResultForDefaultFunction' Signed-off-by: Ben Harshbarger --- frontend/lib/resolution/default-functions.cpp | 8 ++++++++ frontend/lib/resolution/default-functions.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/frontend/lib/resolution/default-functions.cpp b/frontend/lib/resolution/default-functions.cpp index d916de7762d0..f1486bd94737 100644 --- a/frontend/lib/resolution/default-functions.cpp +++ b/frontend/lib/resolution/default-functions.cpp @@ -1431,6 +1431,14 @@ builderResultForDefaultFunction(Context* context, if (name == USTR("init")) { return &buildInitializer(context, typeID); + } else if (name == USTR("init=")) { + return &buildInitEquals(context, typeID); + } else if (name == USTR("deinit")) { + return &buildDeinit(context, typeID); + } else if (name == USTR("serialize")) { + return &buildDeSerialize(context, typeID, true); + } else if (name == USTR("deserialize")) { + return &buildDeSerialize(context, typeID, false); } else if (typeID.symbolName(context) == name) { return &buildTypeConstructor(context, typeID); } diff --git a/frontend/lib/resolution/default-functions.h b/frontend/lib/resolution/default-functions.h index 2f5c79051b2d..24ab4d888232 100644 --- a/frontend/lib/resolution/default-functions.h +++ b/frontend/lib/resolution/default-functions.h @@ -84,7 +84,10 @@ getCompilerGeneratedBinaryOp(Context* context, UniqueString name); const uast::BuilderResult& buildInitializer(Context* context, ID typeID); +const uast::BuilderResult& buildInitEquals(Context* context, ID typeID); const uast::BuilderResult& buildTypeConstructor(Context* context, ID typeID); +const uast::BuilderResult& buildDeinit(Context* context, ID typeID); +const uast::BuilderResult& buildDeSerialize(Context* context, ID typeID, bool isSerializer); } // end namespace resolution } // end namespace chpl From fdf882d71cff18504ce1b53d5bf270b3a37e9e81 Mon Sep 17 00:00:00 2001 From: Ben Harshbarger Date: Tue, 10 Dec 2024 15:23:51 -0800 Subject: [PATCH 9/9] Replace 'collectFields' with 'fieldsForTypeDecl' Signed-off-by: Ben Harshbarger --- frontend/lib/resolution/default-functions.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/frontend/lib/resolution/default-functions.cpp b/frontend/lib/resolution/default-functions.cpp index f1486bd94737..7812a16f2a68 100644 --- a/frontend/lib/resolution/default-functions.cpp +++ b/frontend/lib/resolution/default-functions.cpp @@ -447,19 +447,22 @@ const BuilderResult& buildInitEquals(Context* context, ID typeID) { AstList stmts; - std::vector fields; - for (auto d : typeDecl->decls()) { - collectFields(d, fields); - } + auto ct = initialTypeForTypeDecl(context, typeID)->getCompositeType(); - for (auto field : fields) { + // attempt to resolve the fields + DefaultsPolicy defaultsPolicy = DefaultsPolicy::IGNORE_DEFAULTS; + const ResolvedFields& rf = fieldsForTypeDecl(context, ct, + defaultsPolicy, + /* syntaxOnly */ true); + for (int i = 0; i < rf.numFields(); i++) { + auto name = rf.fieldName(i); // Create 'this.field = other.field;' statement owned lhs = Dot::build(builder, dummyLoc, Identifier::build(builder, dummyLoc, USTR("this")), - field->name()); + name); owned rhs = Dot::build(builder, dummyLoc, Identifier::build(builder, dummyLoc, otherName), - field->name()); + name); owned assign = OpCall::build(builder, dummyLoc, USTR("="), std::move(lhs), std::move(rhs)); stmts.push_back(std::move(assign));