Skip to content

Commit

Permalink
Fix Closure span assignment in makeClosure (#15841)
Browse files Browse the repository at this point in the history
Fixes #15098
[Cherry-picked c8c3bde][modified]
  • Loading branch information
WojciechMazur committed Jul 4, 2024
1 parent 7e8323e commit 50a844d
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 18 deletions.
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1437,7 +1437,7 @@ object desugar {
DefDef(nme.ANON_FUN, params :: Nil, if (tpt == null) TypeTree() else tpt, body)
.withSpan(span)
.withMods(synthetic | Artifact),
Closure(Nil, Ident(nme.ANON_FUN), if (isContextual) ContextualEmptyTree else EmptyTree))
Closure(Nil, Ident(nme.ANON_FUN), if (isContextual) ContextualEmptyTree else EmptyTree).withSpan(span))

/** If `nparams` == 1, expand partial function
*
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/ast/NavigateAST.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package ast
import core.Contexts.*
import core.Decorators.*
import util.Spans.*
import Trees.{MemberDef, DefTree, WithLazyFields}
import Trees.{Closure, MemberDef, DefTree, WithLazyFields}
import dotty.tools.dotc.core.Types.AnnotatedType
import dotty.tools.dotc.core.Types.ImportType
import dotty.tools.dotc.core.Types.Type
Expand Down Expand Up @@ -76,7 +76,7 @@ object NavigateAST {
var bestFit: List[Positioned] = path
while (it.hasNext) {
val path1 = it.next() match {
case p: Positioned => singlePath(p, path)
case p: Positioned if !p.isInstanceOf[Closure[?]] => singlePath(p, path)
case m: untpd.Modifiers => childPath(m.productIterator, path)
case xs: List[?] => childPath(xs.iterator, path)
case _ => path
Expand Down
58 changes: 58 additions & 0 deletions compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1785,6 +1785,64 @@ class DottyBytecodeTests extends DottyBytecodeTest {
}
}


@Test def i15098 = {
val source =
"""object Main {
| def main(args: Array[String]): Unit = {
| Array(1).foreach { n =>
| val x = 123
| println(n)
| }
| }
|}
""".stripMargin

checkBCode(source) { dir =>
val clsIn = dir.lookupName("Main$.class", directory = false).input
val clsNode = loadClassNode(clsIn, skipDebugInfo = false)
val method = getMethod(clsNode, "main")
val instructions = instructionsFromMethod(method).filter(_.isInstanceOf[LineNumber])

val expected = List(
LineNumber(3, Label(0)),
)

assertSameCode(instructions, expected)
}
}

@Test def i15098_2 = {
val source =
"""object Main {
| def main(args: Array[String]): Unit = {
| Array(1).map { n =>
| val x = 123
| x + n
| }.foreach { n =>
| println(n)
| println(n)
| }
| }
|}
""".stripMargin

checkBCode(source) { dir =>
val clsIn = dir.lookupName("Main$.class", directory = false).input
val clsNode = loadClassNode(clsIn, skipDebugInfo = false)
val method = getMethod(clsNode, "main")
val instructions = instructionsFromMethod(method).filter(_.isInstanceOf[LineNumber])

val expected = List(
LineNumber(3, Label(0)),
LineNumber(6, Label(15)),
LineNumber(3, Label(24)),
LineNumber(6, Label(27)),
)

assertSameCode(instructions, expected)
}
}
}

object invocationReceiversTestCode {
Expand Down
8 changes: 4 additions & 4 deletions tests/neg/i15741.scala
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
def get(using Int): String = summon[Int].toString

def pf2: PartialFunction[String, Int ?=> String] = {
def pf2: PartialFunction[String, Int ?=> String] = { // error
case "hoge" => get
case "huga" => get
} // error
}

type IS = Int ?=> String

def pf3: PartialFunction[String, IS] = {
def pf3: PartialFunction[String, IS] = { // error
case "hoge" => get
case "huga" => get
} // error
}


10 changes: 1 addition & 9 deletions tests/neg/i19351a.check
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
-- Error: tests/neg/i19351a/Test.scala:8:34 ----------------------------------------------------------------------------
8 |inline def not(b: Bool): Bool = ${notMacro('b)} // error // error
8 |inline def not(b: Bool): Bool = ${notMacro('b)} // error
| ^
|Cyclic macro dependency; macro refers to a toplevel symbol in tests/neg/i19351a/Test.scala from which the macro is called
-- [E046] Cyclic Error: tests/neg/i19351a/Test.scala:8:46 --------------------------------------------------------------
8 |inline def not(b: Bool): Bool = ${notMacro('b)} // error // error
| ^
| Cyclic reference involving method $anonfun
|
| Run with -explain-cyclic for more details.
|
| longer explanation available when compiling with `-explain`
2 changes: 1 addition & 1 deletion tests/neg/i19351a/Test.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ type Bool = [R] => (R, R) => R
val True: Bool = [R] => (t: R, _: R) => t
val False: Bool = [R] => (_: R, f: R) => f

inline def not(b: Bool): Bool = ${notMacro('b)} // error // error
inline def not(b: Bool): Bool = ${notMacro('b)} // error
inline def show(b: Bool): String = ${showMacro('b)}
//inline def not(b: Bool): Bool = ${foldMacro('b, 'False, 'True)}
//inline def show(b: Bool): String = ${foldMacro('b, '{"TRUE"}, '{"FALSE"})}
Expand Down
2 changes: 1 addition & 1 deletion tests/neg/i9299.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
type F <: F = 1 match { // error
case _ => foo.foo // error // error
case _ => foo.foo // error
}
def foo(a: Int): Unit = ???

0 comments on commit 50a844d

Please sign in to comment.