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
Another "macro not expanded" error with implicits, inferred Nothing, default args #10073
Comments
Imported From: https://issues.scala-lang.org/browse/SI-10073?orig=1 |
@retronym said: class Yo[Unused] {
def yo(hasDefault: Any = ""): String = ""
}
class MacroNotExpanded {
def toYo[Unused](a: Any)(implicit ct: reflect.ClassTag[Unused]): Yo[Unused] = new Yo[Unused]
toYo("").yo()
} |
@retronym said: /** Performs macro expansion on all subtrees of a given tree.
* Innermost macros are expanded first, outermost macros are expanded last.
* See the documentation for `macroExpand` for more information.
*/
def macroExpandAll(typer: Typer, expandee: Tree): Tree =
new Transformer {
override def transform(tree: Tree) = super.transform(tree match {
// todo. expansion should work from the inside out
case tree if (delayed contains tree) && calculateUndetparams(tree).isEmpty && !tree.isErroneous =>
val context = tree.attachments.get[MacroRuntimeAttachment].get.typerContext
delayed -= tree
context.implicitsEnabled = typer.context.implicitsEnabled
context.enrichmentEnabled = typer.context.enrichmentEnabled
context.macrosEnabled = typer.context.macrosEnabled
macroExpand(newTyper(context), tree, EXPRmode, WildcardType)
case _ =>
tree
})
}.transform(expandee) /** Without any restrictions on macro expansion, macro applications will expand at will,
* and when type inference is involved, expansions will end up using yet uninferred type params.
*
* For some macros this might be ok (thanks to TreeTypeSubstituter that replaces
* the occurrences of undetparams with their inferred values), but in general case this won't work.
* E.g. for reification simple substitution is not enough - we actually need to re-reify inferred types.
*
* Luckily, there exists a very simple way to fix the problem: delay macro expansion until everything is inferred.
* Here are the exact rules. Macro application gets delayed if any of its subtrees contain:
* 1) type vars (tpe.isInstanceOf[TypeVar]) // [Eugene] this check is disabled right now, because TypeVars seem to be created from undetparams anyways
* 2) undetparams (sym.isTypeParameter && !sym.isSkolem)
*/
var hasPendingMacroExpansions = false
private val forced = perRunCaches.newWeakSet[Tree]
private val delayed = perRunCaches.newWeakMap[Tree, scala.collection.mutable.Set[Int]]() This code assumes that the enclosing expression contains the exact tree, not copies theroef. Names/defaults copies trees iirc |
@retronym said: |
I've taken another look at this problem. I first tried to change the use of the global map I then found that in https://github.com/scala/scala/compare/2.12.x...retronym:ticket/10073?expand=1 |
(Notify case 10359 when this gets merged.) |
Fixed in scala/scala#6330 |
Same symptom and similar causes to #7987
The text was updated successfully, but these errors were encountered: