Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nullary returntype-refining whitebox macros sometimes can't be applied #7914

Open
scabug opened this issue Oct 15, 2013 · 4 comments
Open

nullary returntype-refining whitebox macros sometimes can't be applied #7914

scabug opened this issue Oct 15, 2013 · 4 comments
Labels
Milestone

Comments

@scabug
Copy link

scabug commented Oct 15, 2013

scala> def impl(c: Context) = { import c.universe._; q"class C { def apply(x: Int) = x }; new C {}" }
impl: (c: scala.reflect.macros.Context)c.universe.Tree

scala> def foo = macro impl
defined term macro foo: Any

scala> foo
res2: AnyRef{def apply(x: Int): Int} = $anon$1@6b58826e

scala> foo(2)
<console>:32: error: Any does not take parameters
              foo(2)
                 ^
@scabug
Copy link
Author

scabug commented Oct 15, 2013

Imported From: https://issues.scala-lang.org/browse/SI-7914?orig=1
Reporter: @xeno-by
Affected Versions: 2.10.3, 2.11.0-M5

@scabug
Copy link
Author

scabug commented Oct 15, 2013

@xeno-by said:
The culprit is another branch of adapt that's shadowed by macro expansion, similarly to the type inference branch that has been fixed in scala/scala#2494 and scala/scala#2821.

if (tree.isType)
  adaptType()
else if (mode.typingExprNotFun && treeInfo.isMacroApplication(tree))
  macroExpandApply(this, tree, mode, pt)
else if (mode.typingConstructorPattern)
  typedConstructorPattern(tree, pt)
else if (shouldInsertApply(tree)) // <----- THIS THING DOESN'T GET CALLED
  insertApply() 
else if (hasUndetsInMonoMode) { // (9)
  assert(!context.inTypeConstructorAllowed, context) //@M
  instantiatePossiblyExpectingUnit(tree, mode, pt)
}
else if (tree.tpe <:< pt)
  tree
else
  fallbackAfterVanillaAdapt()

Looks like to fix the bug we'll need to move the insertApply branch up the conditional and speculatively expand whitebox nullary macros in applyPossible in order to check whether the expansion potentially has an apply method. Blackbox nullary need not to be expanded, as their signature provides enough information:

def applyPossible = {
  def applyMeth = member(adaptToName(tree, nme.apply), nme.apply)
  def hasPolymorphicApply = applyMeth.alternatives exists (_.tpe.typeParams.nonEmpty)
  def hasMonomorphicApply = applyMeth.alternatives exists (_.tpe.paramSectionCount > 0)

  dyna.acceptsApplyDynamic(tree.tpe) || (
    if (mode.inTappMode)
      tree.tpe.typeParams.isEmpty && hasPolymorphicApply
    else
      hasMonomorphicApply
  )
}
def shouldInsertApply(tree: Tree) = mode.typingExprFun && {
  tree.tpe match {
    case _: MethodType | _: OverloadedType | _: PolyType => false
    case _                                               => applyPossible
  }
}

@scabug
Copy link
Author

scabug commented Aug 12, 2014

@scabug
Copy link
Author

scabug commented Oct 31, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants