Why does typecheck return NoType, even when it's calculated a valid symbol?

我的梦境 提交于 2019-12-14 02:24:27

问题


Following on from: How to Typecheck a DefDef

First, some snippets from my macro:

object log {
  def err(msg: String): Unit = c.error(c.enclosingPosition, msg)
  def warn(msg: String): Unit = c.warning(c.enclosingPosition, msg)
  def info(msg: String): Unit = c.info(c.enclosingPosition, msg, force=true)
  def rawInfo(name: String, obj: Any): Unit = info(name + " = " + showRaw(obj))
}

methodsIn(body) foreach { dd => //dd: DefDef
  val name = dd.name.toString
  log.rawInfo(name, dd)
  log.rawInfo(name + ".rhs", dd.rhs)

  try {
    val typechecked = ctx.typecheck(dd.duplicate)
    log.rawInfo(name + ".typechecked", typechecked)
    log.info(name + ".typechecked.symbol = " + typechecked.symbol)
    log.rawInfo(name + ".typechecked.symbol [raw]", typechecked.symbol)
    log.info(name + ".typechecked.symbol.info = " + typechecked.symbol.info)
    log.rawInfo(name + ".typechecked.symbol.info [raw]", typechecked.symbol.info)
    log.rawInfo(name + ".typechecked.tpe", typechecked.tpe)
  } catch { case e: Throwable => log.warn(e.toString)}
}

I then feed the macro with this class:

class BorgMe(@mymacro val param: Nanites) {
  def one(s: String) = s
}

Yes... it's a paradise annotation macro. But I don't think that's relevant here.

What's confusing me is the log output from that code, which looks like:

one = DefDef(
  Modifiers(),
  TermName("one"),
  List(),
  List(List(ValDef(
    Modifiers(PARAM),
    TermName("s"),
    Ident(TypeName("String")),
    EmptyTree
  ))),
  TypeTree(),
  Ident(TermName("s"))
)

one.rhs = Ident(TermName("s"))

one.typechecked = DefDef(
  Modifiers(),
  TermName("one"),
  List(),
  List(List(ValDef(
    Modifiers(PARAM),
    TermName("s"),
    TypeTree().setOriginal(
      Select(
        Select(
          This(TypeName("scala")),
          scala.Predef
        ),
        TypeName("String")
      )
    ),
    EmptyTree
  ))),
  TypeTree(),
  Ident(TermName("s"))
)

one.typechecked.symbol = method one
one.typechecked.symbol [raw] = TermName("one")

one.typechecked.symbol.info = (s: String)String
one.typechecked.symbol.info [raw] =
  MethodType(
    List(TermName("s")),
    TypeRef(
      SingleType(ThisType(scala), scala.Predef),
      TypeName("String"),
      List()
    )
  )

one.typechecked.tpe = NoType

Given that the typecheck is succeeding, and we clearly have all the expected symbol info:

one.typechecked.symbol = method one
one.typechecked.symbol.info = (s: String)String

How come tpe for the method is still coming out as NoType?

one.typechecked.tpe = NoType

回答1:


That's just how scalac works. Typechecked definitions (i.e. subclasses of DefTree) are assigned with NoType. To the contrast, untyped definitions have null in their tpe (just like other untyped trees), so it's possible to discern them.



来源:https://stackoverflow.com/questions/22451181/why-does-typecheck-return-notype-even-when-its-calculated-a-valid-symbol

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!