chapel-lang / chapel

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

default field expression prevents coercion #24593

Open vasslitvinov opened 1 month ago

vasslitvinov commented 1 month ago

When a field is declared with a default expression and without a type, a user initializer cannot initialize that field with a different type (SymEntry2 below) even when such initialization is allowed in a different case (SymEntry1).

// compiles with --minimal-modules upon removal of writeln()

record SymEntry1 {
  var a: real;
  proc init(a) do this.a = a;
}

var se1 = new SymEntry1(5);    // success, a = 5.0
writeln(se1);

record SymEntry2 {
  var a = makeDistArray();
  proc init(a) do this.a = a;  // error: ~"cannot assign int to real"
                               // same error if we wrote 'init(a:int)'
}

proc makeDistArray() do return 3.4;

var se2 = new SymEntry2(5);    // causes the above error
writeln(se2);

Test: test/classes/fields/default-expression-1.chpl

bradcray commented 1 month ago

Though I'm not confident in my memory on this, I would've guessed that this was the intended behavior. It also seems consistent with how we handle formal arguments with defaults but not type constraints. Did you find documentation suggesting otherwise?

Tagging @benharsh who probably wrestled with this while working on initializers and may recall better than me.

benharsh commented 1 month ago

It's also my understanding that this is the intended behavior.

bradcray commented 1 month ago

Oh wait, I missed that this is a coercion (that the type of the field is real and you're assigning an int)—I was focusing on the "cannot initialize with a different type" phrasing and thought you were expecting it to be generic w.r.t. this type. I agree that's surprising.

Is the cause that we don't have a real.init=(x:int) copy initializer for reals? (since copy initialization isn't exactly a normal operation?) Or do we permit coercions in other copy initialization contexts?

vasslitvinov commented 1 month ago

Coercion works in my SymEntry1 example. This makes me think that it should for SymEntry2 as well. I clarified in the OP.