On a branch that I'm working on, I'm disabling the ability to directly read and write sync variables, requiring .readFE() and .writeEF() to be explicitly invoked instead. The one place that direct writes are supported are in initialization, such that:
var x: sync int = 42;
is supported. And due to split initialization, this also means that:
var x: sync int;
x = 42;
is supported, which makes sense. However, I'm finding something odd. While I can do:
var x: sync int, y: sync int;
x = 42;
y = 33;
and:
var x: sync int;
var y: sync int;
x = 45;
y = 33;
I can't do:
var x, y: sync int;
x = 45;
y = 33;
This makes me think that something is broken w.r.t. split initialization and variables sharing a common type expression.
(running into this makes me think we've seen this in some other context, but with a quick search, I couldn't find a related issue. For some reason, I think @dlongnecke-cray was involved?)
@mppf: Is this familiar to you? Any guesses what might be going wrong?
Not familiar to me, no. I suspect the normalizer is somehow having a problem matching this variant for split initialization.
@bradcray -- similar thing came up in automatic localAccess work, maybe you are thinking of that? See the first bullet here.
If it helps save few minutes for someone, based on what I have seen on that work, I think the parser converts
var x, y: sync int
into
var x: sync int;
var y: x.type;
whereas I was thinking that it would convert it to
var x: sync int;
var y: sync int;
It might be implemented that way as a measure against computing types repeatedly for more complicated cases.
It might be implemented that way as a measure against computing types repeatedly for more complicated cases.
I think that's accurate. Specifically, if the type expression were a function:
var x, y: computeType();
We'd only want to call it once rather than twice. In most cases it probably doesn't matter, but maybe in others...?
And not surprisingly, doing the rewrite Engin mentions manually in the code:
var x: sync int;
var y: x.type;
also fails to work for some reason even though it's the initialization of x that causes the complaint.
Oh, I see what's happening then. Since the type signature involves a reference to x, it effectively forces the default initialization of x before that point. Hmm, that seems like an unfortunate side-effect of transforming it in that way.
Perhaps instead, we should have the parser turn this into:
type t = xTypeExpr;
var x: xTypeExpr;
var y: xTypeExpr;
Perhaps instead, we should have the parser turn this into:
My two cents: I think that would make the most sense. This is a nit but, when you say "parser" do you mean parser proper (chapel.ypp), or do you mean "right after parsing" (build.cpp). I find some of these transformations done by the parser potentially confusing. So, maybe we should have a buildMultiVarDeclStmt or something that can build the AST that way.
when you say "parser" do you mean
I only said "parser" because you said "parser" first... :)
[but to not sidestep the philosophical part of your question, generally when I say "parser" I mean "the parsing pass" which would include routines outside of chapel.lex and chapel.ypp such as those in build.cpp]
There is a difference between the two for array variables:
var x, y: [1..3] int;
// this is different:
var x: [1..3] int;
var y: [1..3] int;
// from this:
var x: [1..3] int;
var y: x.type;
// because of whether or not `x.domain` is the same object as `y.domain`.
It looks to me like you typed the same thing twice?
oops, thanks, fixed
Good point. Although in the case that it's a constant / anonymous domain, this probably wouldn't have any observable effect unless someone poked into the internals. That said, I still agree that it'd be better to share the domain for this declaration style (and some domains are expensive to set up, so we wouldn't want to do it twice).
And happily, the proposed "other rewrite" seems to have the desired effect:
type t = [1..3] real;
var A: t;
var B: t;
writeln(A.domain == B.domain); // prints true, no surprise
writeln(A.domain._value == B.domain._value); // also prints true, happily