Skip to content

Commit

Permalink
Dyno resolve tuple 'this' (#25006)
Browse files Browse the repository at this point in the history
Resolve tuple `this` calls (with non-param index values) in Dyno.

This is implemented by wiring up Dyno's `TupleType` to
`ChapelTuple._tuple` in the bundled modules. The module implementation
of `_tuple.size` (called by `this`) is technically used but its param
value is computed by dyno, since in production it is only set later
during generic instantiation.

Depends on: #25007,
#25102,
#25231,
#25315.

Resolves Cray/chapel-private#6104.

[reviewed by @dlongnecke-cray , thanks!]

Testing:
- [x] dyno tests
- [x] paratest
- [x] reproducer from backing issue now resolves
  • Loading branch information
riftEmber authored Jul 3, 2024
2 parents a32cc42 + fca9276 commit 5911c2b
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 34 deletions.
4 changes: 3 additions & 1 deletion frontend/include/chpl/types/TupleType.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class TupleType final : public CompositeType {
instantiatedFrom, std::move(subs)),
isVarArgTuple_(isVarArgTuple)
{
assert(!id.isEmpty());
assert(!name.isEmpty());
// Let a single entry in the SubstitutionsMap with a postOrderId of '-1'
// represent the star-type of a tuple with an unknown size. This is a
// useful representation for VarArgs.
Expand Down Expand Up @@ -74,7 +76,7 @@ class TupleType final : public CompositeType {
}

static const owned<TupleType>&
getTupleType(Context* context, ID id, UniqueString name,
getTupleType(Context* context,
const TupleType* instantiatedFrom,
SubstitutionsMap subs,
bool isVarArgTuple = false);
Expand Down
4 changes: 0 additions & 4 deletions frontend/lib/resolution/default-functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,6 @@ needCompilerGeneratedMethod(Context* context, const Type* type,
}
}

if (type->isTupleType() && name == "size") {
return true;
}

// Some basic getter methods for domain properties
//
// TODO: We can eventually replace these for calls on a domain *value* by
Expand Down
18 changes: 11 additions & 7 deletions frontend/lib/resolution/return-type-inference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -918,11 +918,6 @@ static bool helpComputeCompilerGeneratedReturnType(Context* context,
CHPL_ASSERT(false && "unhandled compiler-generated array method");
}
return true;
} else if (untyped->isMethod() && sig->formalType(0).type()->isTupleType() &&
untyped->name() == "size") {
auto tup = sig->formalType(0).type()->toTupleType();
result = QualifiedType(QualifiedType::PARAM, IntType::get(context, 0), IntParam::get(context, tup->numElements()));
return true;
} else if (untyped->isMethod() && sig->formalType(0).type()->isCPtrType() && untyped->name() == "eltType") {
auto cpt = sig->formalType(0).type()->toCPtrType();
result = QualifiedType(QualifiedType::TYPE, cpt->eltType());
Expand Down Expand Up @@ -1003,8 +998,17 @@ static bool helpComputeReturnType(Context* context,
result = QualifiedType(QualifiedType::TYPE, t);
return true;

// if method call and the receiver points to a composite type definition,
// then it's some sort of compiler-generated method
// special case to set param value of tuple size, which is set late by
// production compiler
} else if (untyped->isMethod() && sig->formalType(0).type()->isTupleType() &&
untyped->name() == "size") {
auto tup = sig->formalType(0).type()->toTupleType();
result = QualifiedType(QualifiedType::PARAM, IntType::get(context, 0),
IntParam::get(context, tup->numElements()));
return true;

// if method call and the receiver points to a composite type definition,
// then it's some sort of compiler-generated method
} else if (untyped->isCompilerGenerated()) {
return helpComputeCompilerGeneratedReturnType(context, sig, poiScope,
result, untyped);
Expand Down
3 changes: 3 additions & 0 deletions frontend/lib/resolution/scope-queries.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ struct GatherDecls {
// skip gathering _tuple from the standard library
// since dyno handles tuple types directly rather
// than through a record.

// TODO: can we remove this at some point when TupleType becomes close
// enough to the _tuple record?
skip = true;
} else if (d->name() == "eltType" &&
atFieldLevel && tagParent == asttags::Class &&
Expand Down
1 change: 1 addition & 0 deletions frontend/lib/types/CompositeType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ bool CompositeType::isMissingBundledRecordType(Context* context, ID id) {
auto path = id.symbolPath();
return path == "String._string" ||
path == "ChapelRange._range" ||
path == "ChapelTuple._tuple" ||
path == "Bytes._bytes";
}

Expand Down
34 changes: 12 additions & 22 deletions frontend/lib/types/TupleType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "chpl/types/TupleType.h"

#include "chpl/framework/query-impl.h"
#include "chpl/parsing/parsing-queries.h"
#include "chpl/resolution/intents.h"
#include "chpl/types/Param.h"

Expand Down Expand Up @@ -92,16 +93,16 @@ void TupleType::computeIsParamKnown() {
}

const owned<TupleType>&
TupleType::getTupleType(Context* context, ID id, UniqueString name,
const TupleType* instantiatedFrom,
TupleType::getTupleType(Context* context, const TupleType* instantiatedFrom,
SubstitutionsMap subs,
bool isVarArgTuple) {
QUERY_BEGIN(getTupleType, context, id, name, instantiatedFrom, subs,
QUERY_BEGIN(getTupleType, context, instantiatedFrom, subs,
isVarArgTuple);

auto result = toOwned(new TupleType(id, name,
instantiatedFrom, std::move(subs),
isVarArgTuple));
auto name = UniqueString::get(context, "_tuple");
auto id = parsing::getSymbolFromTopLevelModule(context, "ChapelTuple", "_tuple");
auto result = toOwned(new TupleType(id, name, instantiatedFrom,
std::move(subs), isVarArgTuple));

return QUERY_END(result);
}
Expand All @@ -116,10 +117,8 @@ TupleType::getValueTuple(Context* context, std::vector<const Type*> eltTypes) {
i++;
}

auto name = UniqueString::get(context, "_tuple");
auto id = ID();
const TupleType* instantiatedFrom = getGenericTupleType(context);
return getTupleType(context, id, name, instantiatedFrom,
return getTupleType(context, instantiatedFrom,
std::move(subs)).get();
}

Expand All @@ -144,20 +143,16 @@ TupleType::getReferentialTuple(Context* context,
i++;
}

auto name = UniqueString::get(context, "_tuple");
auto id = ID();
const TupleType* instantiatedFrom = getGenericTupleType(context);
return getTupleType(context, id, name, instantiatedFrom,
return getTupleType(context, instantiatedFrom,
std::move(subs)).get();
}

const TupleType*
TupleType::getGenericTupleType(Context* context) {
auto name = UniqueString::get(context, "_tuple");
auto id = ID();
SubstitutionsMap subs;
const TupleType* instantiatedFrom = nullptr;
return getTupleType(context, id, name, instantiatedFrom, subs).get();
return getTupleType(context, instantiatedFrom, subs).get();
}

const TupleType*
Expand All @@ -170,10 +165,8 @@ TupleType::getQualifiedTuple(Context* context,
i++;
}

auto name = UniqueString::get(context, "_tuple");
auto id = ID();
const TupleType* instantiatedFrom = getGenericTupleType(context);
return getTupleType(context, id, name, instantiatedFrom,
return getTupleType(context, instantiatedFrom,
std::move(subs), true).get();
}

Expand All @@ -190,13 +183,10 @@ TupleType::getStarTuple(Context* context,
return getQualifiedTuple(context, eltTypes);
} else {
// Size unknown, store the expected element type
auto name = UniqueString::get(context, "_tuple");
auto id = ID();
const TupleType* instantiatedFrom = getGenericTupleType(context);
SubstitutionsMap subs;
subs.emplace(idForTupElt(-1), varArgEltType);
return getTupleType(context, id, name, instantiatedFrom,
subs, true).get();
return getTupleType(context, instantiatedFrom, subs, true).get();
}
}

Expand Down

0 comments on commit 5911c2b

Please sign in to comment.