Skip to content

Commit

Permalink
Merge pull request scala#1645 from scalamacros/ticket/6673
Browse files Browse the repository at this point in the history
SI-6673 fixes macro problems with eta expansions
  • Loading branch information
jsuereth committed Nov 21, 2012
2 parents 1a487a5 + 1fd3a2a commit a0e642b
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 4 deletions.
9 changes: 5 additions & 4 deletions src/compiler/scala/tools/nsc/typechecker/Typers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1117,7 +1117,8 @@ trait Typers extends Modes with Adaptations with Tags {
adaptType()
else if (
inExprModeButNot(mode, FUNmode) && !tree.isDef && // typechecking application
tree.symbol != null && tree.symbol.isTermMacro) // of a macro
tree.symbol != null && tree.symbol.isTermMacro && // of a macro
!tree.attachments.get[SuppressMacroExpansionAttachment.type].isDefined)
macroExpand(this, tree, mode, pt)
else if ((mode & (PATTERNmode | FUNmode)) == (PATTERNmode | FUNmode))
adaptConstrPattern()
Expand Down Expand Up @@ -5221,9 +5222,9 @@ trait Typers extends Modes with Adaptations with Tags {
// find out whether the programmer is trying to eta-expand a macro def
// to do that we need to typecheck the tree first (we need a symbol of the eta-expandee)
// that typecheck must not trigger macro expansions, so we explicitly prohibit them
// Q: "but, " - you may ask - ", `typed1` doesn't call adapt, which does macro expansion, so why explicit check?"
// A: solely for robustness reasons. this mechanism might change in the future, which might break unprotected code
val exprTyped = context.withMacrosDisabled(typed1(expr, mode, pt))
// however we cannot do `context.withMacrosDisabled`
// because `expr` might contain nested macro calls (see SI-6673)
val exprTyped = typed1(expr updateAttachment SuppressMacroExpansionAttachment, mode, pt)
exprTyped match {
case macroDef if macroDef.symbol != null && macroDef.symbol.isTermMacro && !macroDef.symbol.isErroneous =>
MacroEtaError(exprTyped)
Expand Down
17 changes: 17 additions & 0 deletions src/reflect/scala/reflect/internal/StdAttachments.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,26 @@ trait StdAttachments {
def setPos(newpos: Position): this.type = { pos = newpos; this }
}

/** When present, indicates that the host `Ident` has been created from a backquoted identifier.
*/
case object BackquotedIdentifierAttachment

/** Stores the trees that give rise to a refined type to be used in reification.
* Unfortunately typed `CompoundTypeTree` is lacking essential info, and the reifier cannot use `CompoundTypeTree.tpe`.
* Therefore we need this hack (see `Reshape.toPreTyperTypeTree` for a detailed explanation).
*/
case class CompoundTypeTreeOriginalAttachment(parents: List[Tree], stats: List[Tree])

/** Is added by the macro engine to the results of macro expansions.
* Stores the original expandee as it entered the `macroExpand` function.
*/
case class MacroExpansionAttachment(original: Tree)

/** When present, suppresses macro expansion for the host.
* This is occasionally necessary, e.g. to prohibit eta-expansion of macros.
*
* Does not affect expandability of child nodes, there's context.withMacrosDisabled for that
* (but think thrice before using that API - see the discussion at https://github.com/scala/scala/pull/1639).
*/
case object SuppressMacroExpansionAttachment
}
1 change: 1 addition & 0 deletions test/files/run/t6673.check
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
List(x)
5 changes: 5 additions & 0 deletions test/files/run/t6673.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
object Test extends App {
def foo(f: String => Array[String])(s: String) = f(s)
val test = foo(Array(_)) _
println(test("x").toList)
}

0 comments on commit a0e642b

Please sign in to comment.