[Chapel Merge] IFC: implement more features and a hashtable test

Branch: refs/heads/main
Revision: 3216fdc
Author: vasslitvinov
Log Message:

Merge pull request #18000 from vasslitvinov/ifc-hashtable

IFC: implement more features and a hashtable test

This PR:

  • converts (most of) ChapelHashtable.chpl and test-chpl-hashtable.chpl
    to interfaces -- placed in test/constrained-generics/hashtable/, and

  • advances the implementation of interfaces to make that possible.

ChapelHashtable.chpl

This PR makes the following changes to a copy of the revision 309ebb8173
of modules/internal/ChapelHashtable.chpl .

  • Create an interface chpl_Hashtable that covers most of the functionality
    of the record chpl__hashtable. The record "implements" the interface.

  • Convert most methods on chpl__hashtable to methods on chpl_Hashtable.
    A "method on an interface" means that the implicit this argument
    is interface-generic, constrained by the interface.

  • Add an explicit this. to references to associated types of chpl_Hashtable
    within these interface methods. TODO: eliminate the need to do so.

  • Remove or replace the iterators. Currently an interface cannot contain
    iterators as required functions. TODO: can we define and use an iterator
    as an interface-constrained function?

  • Add a toString function to the interface - and implement it with
    a traditional-generic function - to enable printing the keys and the values
    in a hashtable.

test-chpl-hashtable.chpl

This PR makes the following changes to a copy of the revision 309ebb8173
of test/types/chplhashtable/test-chpl-hashtable.chpl .

  • Convert test1() to an interface-constrained function, accepting
    a chpl_Hashtable.

  • Have test1() accept a hashtable, key, and value arguments.
    Use the key and the value instead of integer constants in its body.

  • Invoke test1 on a hashtable of integers and a hashtable of Rs.

Compiler implementation changes

  • Implement interface methods.

  • Support passing arguments of associated types, as in
    test/constrained-generics/basic/set3/arguments-of-assoc-types.chpl
    test/constrained-generics/basic/associated/associated-constraint-used.chpl

  • Support calling functions defined in the interface of an IC formal, as in
    test/constrained-generics/basic/set3/invoke-functions-in-formals-ifc.chpl

  • Support calling functions defined by associative constraints in default
    implementations, as in
    test/constrained-generics/basic/set3/invoke-functions-in-assoc-cons.chpl

  • Handle the AST representation details that arise upon IC functions
    with formals of ref, in, out intents.

  • Minor reformatting, re-indent, etc.

Other

I beefed up the test:
test/constrained-generics/basic/generic/ic-req-function.chpl
It now crashes the compiler, so I futurized it.
A working variant of it is available as:
test/constrained-generics/basic/generic/ic-req-function-dflt.chpl

One interesting question is why I did not include operator ==
in interface StdOps in MyHashtable.chpl. Indeed, we have:

// extracted from test/constrained-generics/hashtable/MyHashtable.chpl

interface Hashable(Key) {
  proc chpl__defaultHashWrapper(arg: Key): int;
  operator ==(lhs: Key, rhs: Key): bool;
}

interface StdOps(Val) {
  proc chpl__initCopy(arg: Val, definedConst: bool): Val;
  operator =(ref lhs: Val, rhs: Val);
}

The reason is the use of these interfaces in chpl_Hashtable:

// more from test/constrained-generics/hashtable/MyHashtable.chpl

interface chpl_Hashtable(HT) {
  type keyType;
  type valType;
  keyType implements Hashable;
  keyType implements StdOps;
  valType implements StdOps;
  .....
}

If we had operator == in both interfaces Hashable and StdOps,
there would be two definitions of == on keyType, one coming
from Hashable and the other from StdOps. Therefore the compiler
would produce an "ambiguous call" error when invoking ==.
We could discuss whether this is the desired behavior.
At the moment this makes sense because there is no guarantee that
the implementations of these interfaces for a given type will provide
the same implementation of ==.

One way to improve the situation is to implement interface inheritance.
Then we could define Hashable to inherit from StdOps and move
operator == from Hashable to StdOps.

Partial development history: 9db468ef4a..faff72290d and 8a80bcf420..c64e9b4338

Reviewed and contributed by: @mppf

Modified Files:
A test/constrained-generics/basic/generic/ic-req-function-dflt.chpl

A test/constrained-generics/basic/generic/ic-req-function-dflt.good
A test/constrained-generics/basic/generic/ic-req-function.bad
A test/constrained-generics/basic/generic/ic-req-function.future
A test/constrained-generics/basic/set3/arguments-of-assoc-types.chpl
A test/constrained-generics/basic/set3/arguments-of-assoc-types.good
A test/constrained-generics/basic/set3/invoke-functions-in-assoc-cons.chpl
A test/constrained-generics/basic/set3/invoke-functions-in-assoc-cons.good
A test/constrained-generics/basic/set3/invoke-functions-in-formals-ifc.chpl
A test/constrained-generics/basic/set3/invoke-functions-in-formals-ifc.good
A test/constrained-generics/basic/set3/out-intents-and-inout.chpl
A test/constrained-generics/basic/set3/out-intents-and-inout.good
A test/constrained-generics/basic/set3/out-intents-from-in.chpl
A test/constrained-generics/basic/set3/out-intents-from-in.good
A test/constrained-generics/hashtable/MyHashtable.notest
A test/constrained-generics/hashtable/test-chpl-hashtable.good
R test/constrained-generics/basic/associated/associated-constraint-used.bad
R test/constrained-generics/basic/associated/associated-constraint-used.future
R test/constrained-generics/hashtable/NOTEST
M compiler/AST/interfaces.cpp
M compiler/AST/type.cpp
M compiler/include/passes.h
M compiler/include/resolution.h
M compiler/include/symbol.h
M compiler/passes/normalize.cpp
M compiler/passes/scopeResolve.cpp
M compiler/resolution/ResolutionCandidate.cpp
M compiler/resolution/interfaceResolution.cpp
M compiler/resolution/preFold.cpp
M test/constrained-generics/basic/associated/associated-constraint-used.good
M test/constrained-generics/basic/generic/ic-req-function.chpl
M test/constrained-generics/basic/generic/ic-req-function.good
M test/constrained-generics/hashtable/MyHashtable.chpl
M test/constrained-generics/hashtable/test-chpl-hashtable.chpl

Compare: https://github.com/chapel-lang/chapel/compare/525ed5642c88...3216fdc5bc56