16673, “e-kayrakli”, “‘Reflection.canResolveMethod’ and formals with type ‘this.type’ don’t get along well”, “2020-11-06T00:50:55Z”
There is a bug (quirk?) with canResolveMethod that these where clauses should remain or I should change this.type
in the formal declaration to something more explicit.
use Reflection;
record R {
var x;
proc foo(r: this.type) {
compilerWarning("Resolving foo. this.type: ", this.type:string,
" r.type: ", r.type:string);
}
proc bar(r: R(int(64))) {
compilerWarning("Resolving foo. this.type: ", this.type:string,
" r.type: ", r.type:string);
}
proc baz(r: R(this.x.type)) {
compilerWarning("Resolving foo. this.type: ", this.type:string,
" r.type: ", r.type:string);
}
}
var r1 = new R(5);
var r2 = new R(5.2);
compilerWarning("Can resolve foo? ", canResolveMethod(r1, "foo", r2):string);
compilerWarning("Can resolve bar? ", canResolveMethod(r1, "bar", r2):string);
compilerWarning("Can resolve baz? ", canResolveMethod(r1, "baz", r2):string);
Generates:
$CHPL_HOME/canResolveBug.chpl:6: In method 'foo':
$CHPL_HOME/canResolveBug.chpl:7: warning: Resolving foo. this.type: R(int(64)) r.type: R(real(64))
$CHPL_HOME/modules/standard/Reflection.chpl:290: called as R(int(64)).foo(r: R(real(64))) from function 'canResolveMethod'
$CHPL_HOME/canResolveBug.chpl:1: called as canResolveMethod(obj: _any, param fname = "foo": string, args(0): _any)
note: generic instantiations are underlined in the above callstack
$CHPL_HOME/canResolveBug.chpl:1: In module 'canResolveBug':
$CHPL_HOME/canResolveBug.chpl:25: note: Can resolve foo? true
$CHPL_HOME/canResolveBug.chpl:26: warning: Can resolve bar? false
$CHPL_HOME/canResolveBug.chpl:27: warning: Can resolve baz? false
Where if the formal type is this.type
we don’t match against the generic fields and try to resolve the function.
I think canResolveMethod
should return false for foo
and not try to resolve the function body.
Note that I can use this.type
in the method body and it works as you’d expect:
record R {
var x;
proc generateNewR() {
var r: this.type;
return r;
}
}
var r = new R(5);
writeln(r.generateNewR().type:string); // prints R(int(64))