Skip to content

Commit 057d2d2

Browse files
committed
Put back tuple unpack assignment kind adjustments
Signed-off-by: Anna Rift <[email protected]>
1 parent 685378d commit 057d2d2

File tree

2 files changed

+47
-39
lines changed

2 files changed

+47
-39
lines changed

frontend/lib/resolution/VarScopeVisitor.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "VarScopeVisitor.h"
2121

2222
#include "chpl/parsing/parsing-queries.h"
23+
#include "chpl/resolution/can-pass.h"
2324
#include "chpl/resolution/ResolvedVisitor.h"
2425
#include "chpl/resolution/resolution-queries.h"
2526
#include "chpl/resolution/resolution-types.h"
@@ -227,6 +228,45 @@ int VarScopeVisitor::indexWithinContainingTuple(const AstNode* ast) const {
227228
return indexWithinParent;
228229
}
229230

231+
// Adjusts LHS tuple type so that its components are all values.
232+
// Does no sanity checks.
233+
static QualifiedType
234+
getLhsForTupleUnpackAssign(Context* context,
235+
const uast::AstNode* astForErr,
236+
const Tuple* lhsTuple,
237+
const QualifiedType& lhsType) {
238+
std::vector<QualifiedType> eltTypes;
239+
240+
auto lhsT = lhsType.type() ? lhsType.type()->toTupleType() : nullptr;
241+
if (!lhsT || lhsT->numElements() != lhsTuple->numActuals()) return lhsType;
242+
243+
for (int i = 0; i < lhsTuple->numActuals(); i++) {
244+
auto actual = lhsTuple->actual(i);
245+
auto ident = actual->toIdentifier();
246+
QualifiedType qt;
247+
248+
if (ident && ident->name() == USTR("_")) {
249+
// If the LHS actual is '_', then use the Nothing type. This is fine
250+
// since the '_' will never be set.
251+
qt = { QualifiedType::VAR, NothingType::get(context) };
252+
253+
} else {
254+
// Otherwise, turn its qualifier into 'var' / 'const var'
255+
auto eqt = lhsT->elementType(i);
256+
auto useKind = KindProperties::removeRef(eqt.kind());
257+
qt = { useKind, eqt.type(), eqt.param() };
258+
}
259+
260+
eltTypes.push_back(std::move(qt));
261+
}
262+
263+
// Set the 'LHS' tuple type.
264+
auto k = QualifiedType::VAR;
265+
auto t = TupleType::getQualifiedTuple(context, std::move(eltTypes));
266+
QualifiedType ret = { k, t };
267+
return ret;
268+
}
269+
230270
const QualifiedType& VarScopeVisitor::returnOrYieldType() {
231271
return fnReturnType;
232272
}
@@ -546,6 +586,13 @@ bool VarScopeVisitor::enter(const Tuple* ast, RV& rv) {
546586

547587
if (!inTupleAssignment) return true;
548588

589+
// TODO: tests expect these kind adjustments to be done, but why here vs
590+
// in resolution?
591+
auto lhsTupleType = rv.byAst(ast).type();
592+
auto adjustedLhsType =
593+
getLhsForTupleUnpackAssign(context, inTupleAssignment, ast, lhsTupleType);
594+
rv.byPostorder().byAst(ast).setType(adjustedLhsType);
595+
549596
// Gather info for this assignment (at whatever level of nesting)
550597
QualifiedType tupInitType = QualifiedType();
551598
const Tuple* tupInitPart = nullptr;

frontend/lib/resolution/call-init-deinit.cpp

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -603,45 +603,6 @@ void CallInitDeinit::resolveDefaultInit(const NamedDecl* ast, Qualifier intentOr
603603
}
604604
}
605605

606-
// Adjusts LHS tuple type so that its components are all values.
607-
// Does no sanity checks.
608-
// static QualifiedType
609-
// getLhsForTupleUnpackAssign(Context* context,
610-
// const uast::AstNode* astForErr,
611-
// const Tuple* lhsTuple,
612-
// const QualifiedType& lhsType) {
613-
// std::vector<QualifiedType> eltTypes;
614-
615-
// auto lhsT = lhsType.type() ? lhsType.type()->toTupleType() : nullptr;
616-
// if (!lhsT || lhsT->numElements() != lhsTuple->numActuals()) return lhsType;
617-
618-
// for (int i = 0; i < lhsTuple->numActuals(); i++) {
619-
// auto actual = lhsTuple->actual(i);
620-
// auto ident = actual->toIdentifier();
621-
// QualifiedType qt;
622-
623-
// if (ident && ident->name() == USTR("_")) {
624-
// // If the LHS actual is '_', then use the Nothing type. This is fine
625-
// // since the '_' will never be set.
626-
// qt = { QualifiedType::VAR, NothingType::get(context) };
627-
628-
// } else {
629-
// // Otherwise, turn its qualifier into 'var' / 'const var'
630-
// auto eqt = lhsT->elementType(i);
631-
// auto useKind = KindProperties::removeRef(eqt.kind());
632-
// qt = { useKind, eqt.type(), eqt.param() };
633-
// }
634-
635-
// eltTypes.push_back(std::move(qt));
636-
// }
637-
638-
// // Set the 'LHS' tuple type.
639-
// auto k = QualifiedType::VAR;
640-
// auto t = TupleType::getQualifiedTuple(context, std::move(eltTypes));
641-
// QualifiedType ret = { k, t };
642-
// return ret;
643-
// }
644-
645606
// bool CallInitDeinit::validateTuplesForAssignOrInit(const AstNode* ast,
646607
// const QualifiedType& lhsType,
647608
// const QualifiedType& rhsType) {

0 commit comments

Comments
 (0)