chapel-lang / chapel

a Productive Parallel Programming Language
https://chapel-lang.org
Other
1.79k stars 421 forks source link

Maps where the value is a tuple containing a set error when passed to a function #23699

Open ShreyasKhandekar opened 1 year ago

ShreyasKhandekar commented 1 year ago

Summary of Problem

When trying to use a map where the value is a tuple of an int and a set, passing it to a function causes an "illegal assignment of type to value" error.

Steps to Reproduce

Source Code:

use Map, Set;

proc foo(ref x : map(int, (int, set(int)))) {
  writeln(x);
}

var x = new map(int, (int,set(int)));

foo(x);

Compile command:

❯ chpl mapsetbug.chpl 
mapsetbug.chpl:3: In function 'foo':
mapsetbug.chpl:3: error: illegal assignment of type to value
  mapsetbug.chpl:1: called as foo(x: map(int(64),(int(64),set(int(64),false)),false))
note: generic instantiations are underlined in the above callstack

Curiously, using either a generic argument in the function header along with a where clause causes the compilation to succeed:

proc foo(ref x : map(int,?t)) where t == (int, set(int)) {

Or declaring the type of the map as a named type also works:

type t = map(string, (int, set(string)));
var x = new t();

proc foo(ref x: t) {
### Configuration Information - Output of `chpl --version`: ``` chpl version 1.33.0 pre-release (f462c767fa) built with LLVM version 14.0.6 available LLVM targets: amdgcn, r600, nvptx64, nvptx, x86-64, x86 Copyright 2020-2023 Hewlett Packard Enterprise Development LP Copyright 2004-2019 Cray Inc. (See LICENSE file for more details) ``` - Output of `$CHPL_HOME/util/printchplenv --anonymize`: ``` CHPL_TARGET_PLATFORM: linux64 CHPL_TARGET_COMPILER: llvm CHPL_TARGET_ARCH: x86_64 CHPL_TARGET_CPU: native CHPL_LOCALE_MODEL: flat CHPL_COMM: none CHPL_TASKS: qthreads CHPL_LAUNCHER: none CHPL_TIMERS: generic CHPL_UNWIND: none CHPL_MEM: jemalloc CHPL_ATOMICS: cstdlib CHPL_GMP: bundled CHPL_HWLOC: bundled CHPL_RE2: bundled CHPL_LLVM: system CHPL_AUX_FILESYS: none ```
jeremiah-corrado commented 1 year ago

Adding to the list of work arounds: your code also compiles with set's parSafe field specified explicitly e.g., x : map(int, (int, set(int, parSafe=true))).

This indicates to me that sets type-initializer is not being called properly in the context of a formal type specifier (probably a more general problem that applies to any type with a default-valued param field).