So I have a program in which I have a function that needs to be passed as an argument to another function call. So I was running a Test Case. Let's say there are two classes Abstract and Concrete, the latter one being the child class of earlier.
// This enum is designed to distinguish between 'int', 'real', and 'bool' types
enum myTypes { i, r, b };
// This helper function converts from a type to one of the above enum values
proc typeToEnum(type t) {
select t {
when int do
return myTypes.i;
when real do
return myTypes.r;
when bool do
return myTypes.b;
otherwise
compilerError("Unexpected type in typeToEnum()");
}
}
// This is an abstract class that isn't good for much other than
// supporting the ability to mix various sub-class instantiations
// within a data structure.
//
class AbstractDataArray {
// This stores information sufficient for determining a concrete
// subclass's static type
var concType: myTypes;
const rank: int;
// This is its initializer
proc init(type t,rank) {
this.concType = typeToEnum(t);
this.rank = rank;
}
// This is a dynamically dispatched method
proc printMe() {
writeln("I am a generic Abstract class");
}
}
// This is a concrete class that contains everything important through
// generic fields
//
class Concrete: Abstract {
type t; // the type of elements stored
var x: t; // an example element of that type
// The class's initializer
proc init(x) {
super.init(x.type);
this.t = x.type;
this.x = x;
}
// The class's override of the dynamically dispatched method
override proc printMe() {
writeln("I am a Concrete class with type ", t:string, " and value ", x);
}
// This is a non-dynamically dispatched method, because its return
// type will vary across classes in the hierarchy, so it can't be
// inherited.
//
proc getValue() {
return x;
}
}
and the function which I need to pass as an argument is as follwing
proc rhs(u:shared Abstract,t:real){
// Does some stuff by changing abstract to one of concerete types
// returns rh which is object of class Concerete typecasted to class Abstract
return rh:Abstract;
}
var a = rhs;
a(U_0,1.20); // Assume U_0 has been defined somewhere above and is an object of class Concerete
And upon running the last code, the output is
Tests/sphinx_solvingPDE.chpl:81: error: in call to 'this', cannot pass result of coercion by reference
Tests/sphinx_solvingPDE.chpl:81: note: implicit coercion from 'shared DataArray(real(64),1,false)' to 'shared AbstractDataArray'
Tests/sphinx_solvingPDE.chpl:80: note: when passing to 'const ref' intent formal 'u'
So the solution to above problem was simple. I typecasted the variable to Abstract and then passed it to function, instead of directly passing it.
var arg = U_0:AbstractDataArray;
a(arg,1);