Skip to content

Commit

Permalink
Merge pull request scala#7963 from hrhino/t11465
Browse files Browse the repository at this point in the history
Eta lifts function before args.
  • Loading branch information
adriaanm authored Jun 18, 2019
2 parents 14e469f + 64a2e55 commit c1be65a
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 5 deletions.
4 changes: 2 additions & 2 deletions spec/06-expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -431,8 +431,8 @@ The method values in the left column are each equivalent to the [eta-expanded ex
|`math.sin _` | `x => math.sin(x)` |
|`math.pow _` | `(x1, x2) => math.pow(x1, x2)` |
|`val vs = 1 to 9; vs.fold _` | `(z) => (op) => vs.fold(z)(op)` |
|`(1 to 9).fold(z)_` | `{ val eta1 = z; val eta2 = 1 to 9; op => eta2.fold(eta1)(op) }` |
|`Some(1).fold(??? : Int)_` | `{ val eta1 = () => ???; val eta2 = Some(1); op => eta2.fold(eta1())(op) }` |
|`(1 to 9).fold(z)_` | `{ val eta1 = 1 to 9; val eta2 = z; op => eta1.fold(eta2)(op) }` |
|`Some(1).fold(??? : Int)_` | `{ val eta1 = Some(1); val eta2 = () => ???; op => eta1.fold(eta2())(op) }` |

Note that a space is necessary between a method name and the trailing underscore
because otherwise the underscore would be considered part of the name.
Expand Down
5 changes: 3 additions & 2 deletions src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ trait EtaExpansion { self: Analyzer =>
* - typedEta (when type checking a method value, `m _`).
*
**/
def etaExpand(unit: CompilationUnit, tree: Tree, owner: Symbol)(implicit creator: FreshNameCreator): Tree = {
def etaExpand(tree: Tree, owner: Symbol)(implicit creator: FreshNameCreator): Tree = {
val tpe = tree.tpe
var cnt = 0 // for NoPosition
def freshName() = {
Expand Down Expand Up @@ -95,11 +95,12 @@ trait EtaExpansion { self: Analyzer =>
liftoutPrefix(fun)
case Apply(fn, args) =>
val byName: Int => Option[Boolean] = fn.tpe.params.map(p => definitions.isByNameParamType(p.tpe)).lift
val liftedFn = liftoutPrefix(fn) // scala/bug#11465: lift fn before args
val newArgs = mapWithIndex(args) { (arg, i) =>
// with repeated params, there might be more or fewer args than params
liftout(arg, byName(i).getOrElse(false))
}
treeCopy.Apply(tree, liftoutPrefix(fn), newArgs).clearType()
treeCopy.Apply(tree, liftedFn, newArgs).clearType()
case TypeApply(fn, args) =>
treeCopy.TypeApply(tree, liftoutPrefix(fn), args).clearType()
case Select(qual, name) =>
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/typechecker/Typers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3203,7 +3203,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper

if (tree.tpe.isDependentMethodType) DependentMethodTpeConversionToFunctionError(tree, tree.tpe) // TODO: support this
else {
val expansion = etaExpand(context.unit, tree, context.owner)
val expansion = etaExpand(tree, context.owner)
if (context.undetparams.isEmpty) typed(expansion, mode, pt)
else instantiate(typed(expansion, mode), mode, pt)
}
Expand Down
6 changes: 6 additions & 0 deletions test/files/run/t11465.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
F
Z
55
F
Z
55
5 changes: 5 additions & 0 deletions test/files/run/t11465.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
object Test extends App {
def f = { println("F") ; 1 to 10 }
println { f.foldLeft{ println("Z"); 0 }(_ + _) }
println { (f.foldLeft{ println("Z"); 0 } _) (_ + _) }
}

0 comments on commit c1be65a

Please sign in to comment.