Update 2020-06-04: replaced with a comment on #6252
Towards resolving the semantic issue in #6252, here we survey the various realistic examples of code scenarios that rely on POI.
Converting these examples to Constrained Generics (CG) is discussed in this gist.
See also:
-
#8077 presents function hijacking, which arises due to the POI rule.
-
Here is the POI rule in the spec . Note that it has a special definition for methods that can be invoked through dynamic dispatch.
Here are the more prominent tests / test directories:
test/functions/generic/poi/
test/functions/ferguson/hijacking/
test/visibility/private/uses/pointOfInstantiation/
test/npb/cg/bradc/cg-sparse-partred.chpl
test/release/examples/spec/Generics/point-of-instantiation.chpl
The POI rule was introduced to allow a generic function to invoke operations defined in the caller scope. The following examples "do just that."
test/functions/generic/poi/hashed-dist-with-mapper.chpl
: the implementation of HashedDist invokes a method on the user-defined mapper to determine the locale for the particular index upon a call to domain.add(). The mapper is stored in the domain descriptor and is not passed directly to the add() call. The method in question is visible from the scope of the add() caller, not from from the HashedDist implementation.
test/functions/generic/poi/init-in-private-array.chpl
: the implementation of PrivateDist creates a new array using default initialization i.e. init() on its elements. If the array elements are of a user-defined record type, init() is defined in the user space and is not visible to PrivateDist implementation.
test/functions/generic/poi/writethis-user-record.chpl
: the implementation of writeln() invokes writeThis() on the arguments. If an argument is a user-defined record, its writeThis() is defined in the user space, even if it is compiler-generated. In other cases, <~>
is needed.
test/functions/generic/poi/reduce-user-record.chpl
: reduce implementation calls functions defined in user space when reduced elements are user-defined records.
test/functions/generic/poi/zmq-initequals.chpl
: ZMQ.recv invokes init=() or =
on a user-defined record type.
canResolve() et al. is most likely to be affected by the issue in #6252 because of how it is currently implemented. We may want to implement it differently, ex. similarly to compilerError(). Test: test/functions/generic/poi/canresolve-in-sort.chpl
test/npb/cg/bradc/cg-sparse-partred.chpl
have a reduction implementation invoke a this() method defined in the application in a local scope. It is notable because the method is defined in a local scope. Which is essential to enable the method to access the local variables in that scope. A small reproducer is in test/functions/generic/poi/reduce-nested-method.chpl
test/functions/generic/poi/forwarding-wrapper.chpl
summarizes the reliance of our array implementation on POI in conjunction with forwarding, observed in #10358
test/functions/ferguson/hijacking/ApplicationB.chpl
is the example in #6252. It is also an example of application development, where an earlier version could have been the one in ApplicationA.chpl
.
See #15714 .
In many cases, the reliance on POI can be avoided by importing the target functions explicitly. Examples:
- variants of cholesky in
test/users/jglewis
test/distributions/bharshbarg/stencil/periodic.chpl
- it uses its helper module 'util', as well as StencilDist; the 'util' module accessesfluff
in StencilDist without importing it- quickSort() in the standard module
Sort
- it is illustrated intest/functions/generic/poi/sort-check-comparator.chpl
; a similar scenario is intest/functions/generic/poi/random-choice.chpl
- the internal modules
MemConsistency
andAlignedTSupport
(in ChapelSyncvar.chpl) - they invoke _cond_test() and _cond_invalid() without importing them from ChapelBase