[Chapel Merge] Fix first-class-functions as arguments to classes

Branch: refs/heads/main
Revision: c3816097df5e08992b9475d9c064e878cd42450b
Author: DanilaFe
Link: Fix first-class-functions as arguments to classes by DanilaFe · Pull Request #25615 · chapel-lang/chapel · GitHub
Log Message:
Fix first-class-functions as arguments to classes (#25615)

Fixes Internal error calling a generic type's initializer with FCP · Issue #23701 · chapel-lang/chapel · GitHub.

This PR resolves an internal error that can be triggered by programs
that use FCFs as arguments to classes or records:

record r {
    var containedValue;
}

var x = new r(proc() { return 42; });

The bug was that the FCF was converted into a call to a factory function
(e.g. fcfFactory()), and replaced in the parent expression. However,
the resolution code downstream expects a normalized program, and new r(fcfFactory()) is not normalized. This led to an assertion error.

The reason that the fcfFactory() is not normalized is actually due to
an overzealous check in shouldInsertCallTemps. In the case this PR is
addressing, the fcfFactory() is a part of the __primitive("new", ...) call for r. Prior to the changes here, normalize didn't
flatten calls to new, to avoid normalizing the the type expression
(which we did not want to do). However, there's no reason not to
normalize the arguments to the class.

This PR adjusts the check to only avoid normalizing the type expression
to new. This has the effect of ensuring fcfFactory() is normalized
properly, and the program in the OP works as expected.

Thanks @lydia-duncan for your help in debugging this issue.

Reviewed by @lydia-duncan -- thanks!

Testing

  • paratest

Compare: Comparing db566b470d0f8b80dd87274d5823fb66c024803f...33ed20b68530c9076456269b7a88876a57c47902 · chapel-lang/chapel · GitHub

Diff:
M compiler/passes/normalize.cpp
A test/functions/fcf/fcfInInitializerCall.chpl
A test/functions/fcf/fcfInInitializerCall.good
https://github.com/chapel-lang/chapel/pull/25615.diff