Search code examples
chapel

Error on function call when captured as values


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'

Solution

  • 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);