我正在开发一个Scala编译器插件,尝试转换每个函数调用,如
myfuncall(1)
进入
val newvalue = myfuncall(1)
newvalue
但是,当函数调用是另一个函数的返回值时,我遇到了麻烦。这是我要转换的代码
class A[C]
class B[C] extends A[C]
trait MyTrait[C] {
def func1: A[C]
}
object MyObject extends MyTrait[Int] {
def func1 = new B
}
在上面的示例中,编译器可以成功推断出new B
的结果应该转换为A[Int]
,因为func1
中的MyObject
应该具有相同的返回类型在func1
中为MyTrait[Int]
。
但是,当我使用编译器插件进行转换时会出现问题。
class A[C]
class B[C] extends A[C]
trait MyTrait[C] {
def func1: A[C]
}
object MyObject extends MyTrait[Int] {
def func1 = {
val newvalue = new B
newvalue
}
}
现在,newvalue
没有提供任何额外的类型信息,而是编译器必须推断它。 newvalue
的结果类型是B[Nothing]
,这是编译器可以推断的最具体的类型。
当我尝试将newvalue
作为func1
的返回值时,会出现问题。 func1
需要A[Int]
,newvalue
类型为B[Nothing]
,无法匹配。
如果我能在高级中知道func1
所需的返回类型,则可以解决问题,因为我可以使用此返回类型指定newvalue
,如下所示
class A[C]
class B[C] extends A[C]
trait MyTrait[C] {
def func1: A[C]
}
object MyObject extends MyTrait[Int] {
def func1 = {
val newvalue: A[Int] = new B
newvalue
}
}
上面的代码可以成功编译。
我的问题是,在编写Scala编译器插件时,如何知道func1
中MyObject
的返回类型为A[Int]
,因为func1
的签名没有&# 39;告诉它的返回类型。
我想从A[Int]
中func1
的签名中了解编译器如何将MyObject
作为func1
的{{1}}的返回类型也是有帮助的。
在两个不同的源文件中定义MyTrait[Int]
和MyTrait
时,此问题变得更加困难。