Using Chapel 1.29
record CSR_descriptor {
var isWeighted : bool;
var isVertexT64 : bool;
var isEdgeT64 : bool;
var isWeightT64 : bool;
proc init=(rhs : 4*bool) {
this.isWeighted = rhs(0);
this.isVertexT64 = rhs(1);
this.isEdgeT64 = rhs(2);
this.isWeightT64 = rhs(3);
}
}
//Opaque handle
record CSR_handle {
var desc : CSR_descriptor; //Error points here
var data : c_void_ptr;
}
//test
proc copyDesc() {
var desc1 : CSR_descriptor;
var desc2 : CSR_descriptor;
desc1.isWeighted = true;
desc1.isVertexT64 = false;
desc1.isEdgeT64 = false;
desc1.isWeightT64 = true;
writeln(desc1);
writeln(desc2);
desc2 = desc1;
writeln(desc2);
}
In order to override this compiler-generated implementation, the user must implement an
init=
method that can accept an argument of the same type. Other user-definedinit=
methods will not prevent the compiler from generating a default implementation forinit=
.
(emphasis mine)
Since my init=
is on a 4*bool
rather than CSR_descriptor
, it shouldn't get in the way of the default copy-initializer.
Without the init=
method, it compiles and I get the expected output from copyDesc()
(isWeighted = true, isVertexT64 = false, isEdgeT64 = false, isWeightT64 = true)
(isWeighted = false, isVertexT64 = false, isEdgeT64 = false, isWeightT64 = false)
(isWeighted = true, isVertexT64 = false, isEdgeT64 = false, isWeightT64 = true)
But with the init=
function, it suddenly can't resolve the default copy initializer
CSR.chpl:52: error: could not find a copy initializer ('init=') for type 'CSR_descriptor' from type 'CSR_descriptor'
CSR.chpl:43: note: this candidate did not match: CSR_descriptor.init=(rhs: 4*bool) [184935]
CSR.chpl:52: note: because actual argument #1 with type 'CSR_descriptor'
CSR.chpl:43: note: is passed to formal 'rhs: 4*bool [184945]'
CSR.chpl:52: note: unresolved call had id 901713
I can write the trivial copy initializer below (which in turn requires the explicit assignment operator, else I get error: Type 'CSR_descriptor' uses compiler-generated default '=' but has a custom 'init=' method. Please add a '=' function.
) and then it works again, but given the documentation this feels like a regression that I shouldn't have to do?
proc init=(rhs : CSR_descriptor) {
this.isWeighted = rhs.isWeighted;
this.isVertexT64 = rhs.isVertexT64;
this.isEdgeT64 = rhs.isEdgeT64;
this.isWeightT64 = rhs.isWeightT64;
}
operator =(ref lhs : CSR_descriptor, rhs : CSR_descriptor) :void {
lhs.isWeighted = rhs.isWeighted;
lhs.isVertexT64 = rhs.isVertexT64;
lhs.isEdgeT64 = rhs.isEdgeT64;
lhs.isWeightT64 = rhs.isWeightT64;
}