From 0a67b15968fec802579b5f2805742390395f42f1 Mon Sep 17 00:00:00 2001 From: Florian3k Date: Fri, 22 Mar 2024 12:06:45 +0100 Subject: [PATCH] Fix Closure span assignment in makeClosure --- .../src/dotty/tools/dotc/ast/Desugar.scala | 2 +- .../dotty/tools/dotc/ast/NavigateAST.scala | 4 +- .../backend/jvm/DottyBytecodeTests.scala | 58 +++++++++++++++++++ tests/neg/i15741.scala | 8 +-- tests/neg/i19351a.check | 10 +--- tests/neg/i19351a/Test.scala | 2 +- tests/neg/i9299.scala | 2 +- 7 files changed, 68 insertions(+), 18 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index 2d99cf201375..6ed05976a19e 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -1523,7 +1523,7 @@ object desugar { DefDef(nme.ANON_FUN, paramss, if (tpt == null) TypeTree() else tpt, body) .withSpan(span) .withMods(synthetic | Artifact), - Closure(Nil, Ident(nme.ANON_FUN), EmptyTree)) + Closure(Nil, Ident(nme.ANON_FUN), EmptyTree).withSpan(span)) /** If `nparams` == 1, expand partial function * diff --git a/compiler/src/dotty/tools/dotc/ast/NavigateAST.scala b/compiler/src/dotty/tools/dotc/ast/NavigateAST.scala index 2960af8fcdec..f83f12e1c027 100644 --- a/compiler/src/dotty/tools/dotc/ast/NavigateAST.scala +++ b/compiler/src/dotty/tools/dotc/ast/NavigateAST.scala @@ -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 @@ -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 diff --git a/compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala b/compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala index 51390e35b527..f446913d7964 100644 --- a/compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala +++ b/compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala @@ -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 { diff --git a/tests/neg/i15741.scala b/tests/neg/i15741.scala index 2d536c515f76..45d6c3bed16d 100644 --- a/tests/neg/i15741.scala +++ b/tests/neg/i15741.scala @@ -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 + } diff --git a/tests/neg/i19351a.check b/tests/neg/i19351a.check index 3c1353811f3d..10789c2db5aa 100644 --- a/tests/neg/i19351a.check +++ b/tests/neg/i19351a.check @@ -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` diff --git a/tests/neg/i19351a/Test.scala b/tests/neg/i19351a/Test.scala index 51f608aa46ea..84fb6ca4ae78 100644 --- a/tests/neg/i19351a/Test.scala +++ b/tests/neg/i19351a/Test.scala @@ -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"})} diff --git a/tests/neg/i9299.scala b/tests/neg/i9299.scala index 6c23d11553ff..c3ae55ab9d18 100644 --- a/tests/neg/i9299.scala +++ b/tests/neg/i9299.scala @@ -1,4 +1,4 @@ type F <: F = 1 match { // error - case _ => foo.foo // error // error + case _ => foo.foo // error } def foo(a: Int): Unit = ???