Strange error message when defining a function that returns a tuple of sets

Hello,

I'm new to Chapel, and I was doing Advent of Code 2022 day 3, when I came upon a curious error message when I tried to compile this code.

import IO;
use Set;

type compartment = set(string);

type rucksack = (compartment, compartment);

// Creates a set out of a string
proc setFromString(s: string): set(string) {
    var comp: set(string);
    for c in s {
        comp.add(c);
    }

    return comp;
}

// This function parses a line of the input
// It splits the line in half, and makes a
// pair of sets out of individual characters
// (as 1-character-wide strings)
// from each half
proc parseLine(line: string): rucksack {
    const midPoint = line.size / 2;
    return (setFromString(line[0..<midPoint]), setFromString(line[midPoint..<line.size]));
}

// Opens the filename for parsing and parses each line,
// yielding a rucksack for each line as defined above
proc parse(filename: string): []rucksack throws {
    var reader = IO.openReader(filename, locking=false);
    defer reader.close();
    return parseLine(reader.lines(stripNewline=true));
}

The compiler simply says

$CHPL_HOME/modules/internal/ChapelArray.chpl:3611: error: const actual is passed to a 'ref' formal of chpl__initCopy()

I think this has something to do with trying to return an array of tuples of sets (the parse proc), but I'm not sure, because the compiler gives me no information about where the issue is actually arising in my code.

Chapel version: 2.1.0 compiled with LLVM 18.1.8

1 Like

Hello @Evan-Hock, welcome to Chapel! We will be thrilled to hear about your experiences learning and using the language.

Sometimes you can get more information about an error if you compile with --print-callstack-on-error or --devel or --print-additional-errors. Sometimes the problem is due to our compiler when your code is legal and should work as expected. This is unfortunately the case with your code.

The last line of you parse() has a promoted call to parseLine() and converts the outcome to an array, which it returns. This is legal and a good use of Chapel's features. Alas due to some logic in the compiler this conversion fails to compile.

One straightforward workaround is to create a list and add rucksacks to it one by one instead of a promoted call to parseLine(). There is probably an elegant workaround as well.

How does this sound to you?

Vass

Howdy,

Thanks for the quick response.

Compiling with --devel produces the following output:

$CHPL_HOME/modules/internal/ChapelArray.chpl:3573: In function 'chpl__initCopy':
$CHPL_HOME/modules/internal/ChapelArray.chpl:3611: error: const actual is passed to 'ref' formal 'x' of chpl__initCopy()
  day3.chpl:25: called as chpl__initCopy(ir: _ir_chpl_promo1_parseLine, definedConst: bool)
note: generic instantiations are underlined in the above callstack

(_ir_chpl_prom1_parseLine is underlined)

I hope that can be of some assistance.

The list workaround works just fine, and I was able to use promotion elsewhere in my code to get the solution:

proc part1(rucksacks: []rucksack): uint {
    return + reduce priorityOf(misplacedItem(rucksacks));
}

Thank you for your help,

Evan

1 Like

Thank you Evan. If this issue is a blocker for you, please let us know. I will see if we can fix it in an upcoming release.

Vass

1 Like

@vass : Catching up on this thread, have you already fixed the issue? Or did you find it to already be fixed? I was unable to reproduce it on main today, but was able to on ATO, which is running Chapel 2.2.

I had to add a call to parse("infile.txt"); to the program—without that, I believe the compiler treats everything as dead code.

Thanks,
-Brad

I fixed this following Vass' initial investigation in Fix yielding objects from an iterator record whose copy mutates them by DanilaFe · Pull Request #26230 · chapel-lang/chapel · GitHub.

Great, thanks Daniel! And thanks @Evan-Hock for reporting the issue to us! Please let us know if you hit additional surprises.

-Brad