[Chapel Merge] Fix `out` formals as promoted arguments; disallow `out` and `inout` as scalar arguments for promoted calls

Branch: refs/heads/main
Revision: cd8a9e2e572551094494af8d188e806573111f97
Author: DanilaFe
Link: Fix `out` formals as promoted arguments; disallow `out` and `inout` as scalar arguments for promoted calls by DanilaFe · Pull Request #28791 · chapel-lang/chapel · GitHub
Log Message:
Fix out formals as promoted arguments; disallow out and inout as scalar arguments for promoted calls (#28791)

Closes [Bug]: out intent unable(?) to identify when a real array is passed in lieu of a real · Issue #28696 · chapel-lang/chapel · GitHub.

There are two issues at play.

  • Regardless of whether it is promoted or scalar, an out formal/actual
    pair in a promoted call is converted into a temporary that's written
    back to the original actual. This introduces unexpected code when
    creating promotion wrappers, and is the direct source of the original
    crash in #28696. It looks like, however, we already have logic to
    disable generating the temporary write-back for inout formals, because
    it's "handled elsewhere". Adding a similar check for out formals makes
    the original example work.
    // corresponding case
    proc foo(x: int, out y: int) do y = x;
    var A, B = [1,2,3,4];
    foo(A, B);
    
  • For scalar out / inout formals, this is not the end of the story;
    they run into a late const check. However, the fact is that scalar
    out arguments to a promoted call will be written to from every
    iteration of the loop over said promotion. This would be unsafe and
    racey if the promotion were done in parallel. To deal with this,
    disallow scalar out / inout actuals to promoted functions. This PR
    does this both in production and in Dyno. I updated Dyno so that CLS
    etc. are able to check for this error.
    // corresponding case
    proc foo(x: int, out y: int) do y = x;
    var A = [1,2,3,4], b = 0;
    foo(A, b);
    

Reviewed by @jabraham17 -- thanks!

Testing

  • paratest
  • make frontend-tests

Compare: Comparing 2ca26260e113551de4e85f2b42448cc122d63d16...c7761be3f1a6a01ad11edb1a47a733b25c9c245c · chapel-lang/chapel · GitHub

Diff:
M compiler/resolution/wrappers.cpp
M frontend/include/chpl/resolution/resolution-error-classes-list.h
M frontend/include/chpl/resolution/resolution-types.h
M frontend/lib/resolution/Resolver.cpp
M frontend/lib/resolution/disambiguation.cpp
M frontend/lib/resolution/resolution-error-classes-list.cpp
M frontend/lib/resolution/resolution-types.cpp
M frontend/test/framework/testQueryEquivalence.cpp
M frontend/test/resolution/testPromotion.cpp
M frontend/test/resolution/testResolve.cpp
A test/functions/promotion/issue-28696.chpl
A test/functions/promotion/issue-28696.good
A test/functions/promotion/move-over-arr.chpl
A test/functions/promotion/move-over-arr.good
A test/functions/promotion/move-over-scalar-out.chpl
A test/functions/promotion/move-over-scalar-out.good
A test/functions/promotion/move-over-scalar.chpl
A test/functions/promotion/move-over-scalar.good
https://github.com/chapel-lang/chapel/pull/28791.diff