Chapel: Initializing a variable of declared type with an iterator ignores the declared type

Created on 30 Oct 2019  路  6Comments  路  Source: chapel-lang/chapel

Summary of Problem

Assigning a list to an iterator upon initialization results in an array. This can be surprising, because the type provided on the LHS is not the resulting type of the variable. This is likely to be a common pitfall when converting array codes to list codes.

Ideally, assigning a list to an iterator upon initialization would populate the list with the iterator values, similar to the array behavior. If this is not possible, then the assignment should generate a compiler error. Assigning a list to an iterator after initialization gives the appropriate error message (shown below).

Steps to Reproduce

Source Code:

use List;

var A: list(string) = 'echo "hello world"'.split();
writeln(A.type:string);
// [domain(1,int(64),false)] string

var B = 'echo "hello world"'.split();
writeln(B.type:string);
// [domain(1,int(64),false)] string

// What the user needs to do:
var tmp = 'echo "hello world"'.split();
var C: list(string) = tmp;
writeln(C.type:string);
// list(string,false)

The following code generates an error message as expected:

var D: list(string);
D = 'echo "hello world"'.split();
// list-iterator:2: error: Cannot assign to list(string,false) from iterator


Configuration Information

  • Output of chpl --version: 1.20.0
Libraries / Modules Bug

Most helpful comment

I think this has to do with that special untyped case in the compiler, with the bug being that the code handling that case is incorrectly assuming the LHS type will also be an array. I'll take a closer look and see what can be fixed.

All 6 comments

Probably of interest to @dlongnecke-cray

Whew, this is a bit mind boggling, I'll say that...

Well, I suppose some good news (for me) is that the following also compiles...


record foo {
  var x: int = 0;
}

proc main() {
  var f: foo = "Some message!".split();
  writeln(f.type:string);
}

And produces...

[domain(1,int(64),false)] string

Wow, yeah, that's a weird one. That said, the title and description of this issue are worded confusingly to me. "Assigning a list to an iterator upon initialization results in an array." suggests to me that you're assigning from a list on the RHS to an iterator on the LHS, when I think you're doing the opposite? I'd probably say this as "initializing a list with an iterator causes the list to have array type" instead. (Or, now with DavidL's observation above, "initializing a variable of declared type with an iterator causes the declared type to be ignored and for the variable to become an array).

I know we use some pretty special code patterns to handle the untyped var A = myIter(); case, and am guessing that they're at fault here... This seems to probably be unrelated to recent initializer work (and arrays are still outside of the recent initializer improvements world), but I'm tagging @benharsh anyway to see if he has any insights.

I think this has to do with that special untyped case in the compiler, with the bug being that the code handling that case is incorrectly assuming the LHS type will also be an array. I'll take a closer look and see what can be fixed.

Thanks Ben. I'll be curious if your conclusion involves elements of "this is a case that wouldn't have been an issue if arrays were using initializers"

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Aniket21mathur picture Aniket21mathur  路  3Comments

buddha314 picture buddha314  路  3Comments

vasslitvinov picture vasslitvinov  路  3Comments

bradcray picture bradcray  路  3Comments

Rapiz1 picture Rapiz1  路  3Comments