Branch: refs/heads/main
Revision: 5822073813d9a6230a68e07fd5d782c0cab117f3
Author: DanilaFe
Link: dyno: resolve nested init calls by DanilaFe · Pull Request #24906 · chapel-lang/chapel · GitHub
Log Message:
dyno: resolve nested init calls (#24906)
Closes dyno: calls to initializers from other initializers aren't reflected. · Issue #24854 · chapel-lang/chapel · GitHub. Closes
https://github.com/Cray/chapel-private/issues/6182 (sprint task).
This PR adjusts the InitResolver
to support calls like this.init
inside other init
procedures.
To make this work, the PR does the following things:
- It disallows calls to 'init' on anything other than 'super' and
'this'. As far as I know, this is already effectively the standard for
Chapel; however, it was not enforced. As a result, the following program
-- which is legal onmain
-- is now illegal.record myRec { var x: int; proc init(x: int, y: int) { this.x = x + y; } proc init(x: int) { init(x, 0); } proc init() {} } record container { var r: myRec; proc init() { init this; r.init(10); // bad bad bad } } var c: container;
By doing so, the PR makes it possible for the InitResolver
to
syntactically detect calls such as this.init()
. By doing this, in
turn, we can start representing their effects on the resolution state.
2. Adding new handling methods to InitResolver
that operate on
CallResolutionResult
s in addition to AST nodes. This is required
because the effects of calling this.init
depend on which overload of
init
is called; as such, we want to go through the usual mechanism for
resolving the initializer. Doing so using CallResolutionResult
s makes
the most sense. As a result of this PR, the handleCallExpr
follows up
resolution with handleResoledCall
, which descends into the
InitResolver.
- When handling
init
, theInitResolver
populates the individual
field states as if they were assigned to. This is useful because the
calls to 'this.init' need to fit into the existing framework of
initialization: handling branches, merging intermediate results, etc. - This also requires a slight adjustment to the
handleCallExpr
to stop
skipping call resolution when the receiver formal is generic. Thethis
inthis.init
for a generic method is going to be generic, but that
should not stop us from performing resolution.
As a result, dyno: calls to initializers from other initializers aren't reflected. · Issue #24854 · chapel-lang/chapel · GitHub is
resolved; a major consequence of that is that ranges with the by
operator (mentioned in dyno: (almost) resolve nontrivial ranges by DanilaFe · Pull Request #24853 · chapel-lang/chapel · GitHub)
now resolve correctly: the constructor that previously threw away the
stride
now properly takes it into account. I was able to validate that
the implementation of ranges in Dyno works with strides as one would
expect.
Reviewed by @benharsh -- thanks!
Testing
- paratest
- dyno tests
Diff:
M frontend/include/chpl/resolution/resolution-error-classes-list.h
M frontend/lib/resolution/InitResolver.cpp
M frontend/lib/resolution/InitResolver.h
M frontend/lib/resolution/Resolver.cpp
M frontend/lib/resolution/resolution-error-classes-list.cpp
M frontend/lib/uast/post-parse-checks.cpp
M frontend/test/resolution/testInitSemantics.cpp
M frontend/test/resolution/testRanges.cpp
A test/errors/parsing/initnotthis.1.good
A test/errors/parsing/initnotthis.2.good
A test/errors/parsing/initnotthis.chpl
https://github.com/chapel-lang/chapel/pull/24906.diff