Skip to content

Commit ab57803

Browse files
Backport "Fix Closure span assignment in makeClosure" to LTS (#21027)
Backports #15841 to the LTS branch. PR submitted by the release tooling. [skip ci]
2 parents 58af2b0 + 50a844d commit ab57803

File tree

7 files changed

+68
-18
lines changed

7 files changed

+68
-18
lines changed

Diff for: compiler/src/dotty/tools/dotc/ast/Desugar.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1437,7 +1437,7 @@ object desugar {
14371437
DefDef(nme.ANON_FUN, params :: Nil, if (tpt == null) TypeTree() else tpt, body)
14381438
.withSpan(span)
14391439
.withMods(synthetic | Artifact),
1440-
Closure(Nil, Ident(nme.ANON_FUN), if (isContextual) ContextualEmptyTree else EmptyTree))
1440+
Closure(Nil, Ident(nme.ANON_FUN), if (isContextual) ContextualEmptyTree else EmptyTree).withSpan(span))
14411441

14421442
/** If `nparams` == 1, expand partial function
14431443
*

Diff for: compiler/src/dotty/tools/dotc/ast/NavigateAST.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ package ast
44
import core.Contexts.*
55
import core.Decorators.*
66
import util.Spans.*
7-
import Trees.{MemberDef, DefTree, WithLazyFields}
7+
import Trees.{Closure, MemberDef, DefTree, WithLazyFields}
88
import dotty.tools.dotc.core.Types.AnnotatedType
99
import dotty.tools.dotc.core.Types.ImportType
1010
import dotty.tools.dotc.core.Types.Type
@@ -76,7 +76,7 @@ object NavigateAST {
7676
var bestFit: List[Positioned] = path
7777
while (it.hasNext) {
7878
val path1 = it.next() match {
79-
case p: Positioned => singlePath(p, path)
79+
case p: Positioned if !p.isInstanceOf[Closure[?]] => singlePath(p, path)
8080
case m: untpd.Modifiers => childPath(m.productIterator, path)
8181
case xs: List[?] => childPath(xs.iterator, path)
8282
case _ => path

Diff for: compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala

+58
Original file line numberDiff line numberDiff line change
@@ -1785,6 +1785,64 @@ class DottyBytecodeTests extends DottyBytecodeTest {
17851785
}
17861786
}
17871787

1788+
1789+
@Test def i15098 = {
1790+
val source =
1791+
"""object Main {
1792+
| def main(args: Array[String]): Unit = {
1793+
| Array(1).foreach { n =>
1794+
| val x = 123
1795+
| println(n)
1796+
| }
1797+
| }
1798+
|}
1799+
""".stripMargin
1800+
1801+
checkBCode(source) { dir =>
1802+
val clsIn = dir.lookupName("Main$.class", directory = false).input
1803+
val clsNode = loadClassNode(clsIn, skipDebugInfo = false)
1804+
val method = getMethod(clsNode, "main")
1805+
val instructions = instructionsFromMethod(method).filter(_.isInstanceOf[LineNumber])
1806+
1807+
val expected = List(
1808+
LineNumber(3, Label(0)),
1809+
)
1810+
1811+
assertSameCode(instructions, expected)
1812+
}
1813+
}
1814+
1815+
@Test def i15098_2 = {
1816+
val source =
1817+
"""object Main {
1818+
| def main(args: Array[String]): Unit = {
1819+
| Array(1).map { n =>
1820+
| val x = 123
1821+
| x + n
1822+
| }.foreach { n =>
1823+
| println(n)
1824+
| println(n)
1825+
| }
1826+
| }
1827+
|}
1828+
""".stripMargin
1829+
1830+
checkBCode(source) { dir =>
1831+
val clsIn = dir.lookupName("Main$.class", directory = false).input
1832+
val clsNode = loadClassNode(clsIn, skipDebugInfo = false)
1833+
val method = getMethod(clsNode, "main")
1834+
val instructions = instructionsFromMethod(method).filter(_.isInstanceOf[LineNumber])
1835+
1836+
val expected = List(
1837+
LineNumber(3, Label(0)),
1838+
LineNumber(6, Label(15)),
1839+
LineNumber(3, Label(24)),
1840+
LineNumber(6, Label(27)),
1841+
)
1842+
1843+
assertSameCode(instructions, expected)
1844+
}
1845+
}
17881846
}
17891847

17901848
object invocationReceiversTestCode {

Diff for: tests/neg/i15741.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
def get(using Int): String = summon[Int].toString
22

3-
def pf2: PartialFunction[String, Int ?=> String] = {
3+
def pf2: PartialFunction[String, Int ?=> String] = { // error
44
case "hoge" => get
55
case "huga" => get
6-
} // error
6+
}
77

88
type IS = Int ?=> String
99

10-
def pf3: PartialFunction[String, IS] = {
10+
def pf3: PartialFunction[String, IS] = { // error
1111
case "hoge" => get
1212
case "huga" => get
13-
} // error
13+
}
1414

1515

Diff for: tests/neg/i19351a.check

+1-9
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
11
-- Error: tests/neg/i19351a/Test.scala:8:34 ----------------------------------------------------------------------------
2-
8 |inline def not(b: Bool): Bool = ${notMacro('b)} // error // error
2+
8 |inline def not(b: Bool): Bool = ${notMacro('b)} // error
33
| ^
44
|Cyclic macro dependency; macro refers to a toplevel symbol in tests/neg/i19351a/Test.scala from which the macro is called
5-
-- [E046] Cyclic Error: tests/neg/i19351a/Test.scala:8:46 --------------------------------------------------------------
6-
8 |inline def not(b: Bool): Bool = ${notMacro('b)} // error // error
7-
| ^
8-
| Cyclic reference involving method $anonfun
9-
|
10-
| Run with -explain-cyclic for more details.
11-
|
12-
| longer explanation available when compiling with `-explain`

Diff for: tests/neg/i19351a/Test.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ type Bool = [R] => (R, R) => R
55
val True: Bool = [R] => (t: R, _: R) => t
66
val False: Bool = [R] => (_: R, f: R) => f
77

8-
inline def not(b: Bool): Bool = ${notMacro('b)} // error // error
8+
inline def not(b: Bool): Bool = ${notMacro('b)} // error
99
inline def show(b: Bool): String = ${showMacro('b)}
1010
//inline def not(b: Bool): Bool = ${foldMacro('b, 'False, 'True)}
1111
//inline def show(b: Bool): String = ${foldMacro('b, '{"TRUE"}, '{"FALSE"})}

Diff for: tests/neg/i9299.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
type F <: F = 1 match { // error
2-
case _ => foo.foo // error // error
2+
case _ => foo.foo // error
33
}
44
def foo(a: Int): Unit = ???

0 commit comments

Comments
 (0)