Skip to content

Commit

Permalink
Dyno: Improve resolution of where-clauses on generic methods (chapel-…
Browse files Browse the repository at this point in the history
…lang#24645)

This PR updates the implementation of instantiating a signature in dyno
to correctly set the type of ``this`` while resolving the non-formal
elements of a secondary method. Prior to this PR, we were potentially
setting the type of ``this`` to be the fully-generic type, rather than
the instantiation we had just computed. For example, for a method like
``R.foo()`` we would use ``R`` instead of something like ``R(int)``.

While in the area, I also observed and fixed a related issue when
referencing fields of a generic type while within an instantiated
secondary method. The solution was to simply reset the Resolver's
"computed receiver scopes" flag so that they would be appropriately
recomputed.

This PR also includes a couple of minor cleanups to avoid generating
some false "unimplemented" warnings during resolution.

[reviewed-by @mppf]
  • Loading branch information
benharsh authored Mar 19, 2024
2 parents 1921764 + c91f3f9 commit 1a45d3f
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 3 deletions.
4 changes: 2 additions & 2 deletions frontend/lib/resolution/can-pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -781,12 +781,12 @@ bool CanPassResult::canInstantiateBuiltin(Context* context,
return true;

if (formalT->isAnyIteratorClassType()) {
CHPL_UNIMPL("iterator classes"); // TODO: represent iterators
// TODO: represent iterators
return false;
}

if (formalT->isAnyIteratorRecordType()) {
CHPL_UNIMPL("iterator records"); // TODO: represent iterators
// TODO: represent iterators
return false;
}

Expand Down
8 changes: 7 additions & 1 deletion frontend/lib/resolution/resolution-queries.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1972,7 +1972,13 @@ ApplicabilityResult instantiateSignature(Context* context,
}

if (fn != nullptr && fn->isMethod() && fn->thisFormal() == formal) {
visitor.setCompositeType(qFormalType.type()->toCompositeType());
// Set the visitor's 'inCompositeType' property to the final
// instantiation of 'this' so that we can correctly resolve methods.
//
// Also recompute receiver scopes based on the instantiated type so
// that we correctly resolve the types of field identifiers.
visitor.setCompositeType(formalType.type()->toCompositeType());
visitor.receiverScopesComputed = false;
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions frontend/lib/resolution/resolution-types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ CallInfo CallInfo::create(Context* context,
name = calledIdent->name();
} else if (auto calledDot = called->toDot()) {
name = calledDot->field();
} else if (auto op = called->toOpCall()) {
name = op->op();
} else {
CHPL_UNIMPL("CallInfo without a name");
}
Expand Down
37 changes: 37 additions & 0 deletions frontend/test/resolution/testMethodCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,42 @@ static void test8() {
}
}

static void test9() {
Context ctx;
Context* context = &ctx;
ErrorGuard guard(context);

std::string program = R"""(
record R {
type T;
var field : T;
}
// Case 1: correctly call 'helper' in a where-clause when declared as a
// secondary method on a generic record.
proc R.helper() param do return field.type == int;
proc R.foo() where helper() do return 5;
proc R.foo() where !helper() do return "hello";
// Case 2: correctly resolve the identifier 'T' implicitly referenced
// within a where-clause of an instantiated method
proc R.wrapper() param where T == int do return helper();
proc R.baz() where wrapper() do return 5;
proc R.baz() where !wrapper() do return "hello";
var r : R(int);
var x = r.foo();
var y = r.baz();
)""";

auto results = resolveTypesOfVariables(context, program, {"x", "y"});
assert(results["x"].type()->isIntType());
assert(results["y"].type()->isIntType());
assert(guard.numErrors() == 0);
}


int main() {
test1();
Expand All @@ -510,6 +546,7 @@ int main() {
test6();
test7();
test8();
test9();

return 0;
}
Expand Down

0 comments on commit 1a45d3f

Please sign in to comment.