From 08658f0325a4e3f08dc4e5616fd708aaff7afe09 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Thu, 3 Apr 2025 03:19:33 -0700 Subject: [PATCH] Test chars safely when highlighting The arrow test at lastOffset - 3 is out-of-range when highlighting, which parses a snippet of source. Always check lower bound in testChar. Don't check as initial condition in testChars because it recurses. --- compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 7 ++++--- compiler/test/dotty/tools/utils.scala | 2 ++ tests/neg/i22906.check | 6 ++++++ tests/neg/i22906.scala | 6 ++++++ 4 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 tests/neg/i22906.check create mode 100644 tests/neg/i22906.scala diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 1610362c3323..3a43f53f3ca4 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -732,16 +732,17 @@ object Parsers { def testChar(idx: Int, p: Char => Boolean): Boolean = { val txt = source.content - idx < txt.length && p(txt(idx)) + idx >= 0 && idx < txt.length && p(txt(idx)) } def testChar(idx: Int, c: Char): Boolean = { val txt = source.content - idx < txt.length && txt(idx) == c + idx >= 0 && idx < txt.length && txt(idx) == c } def testChars(from: Int, str: String): Boolean = - str.isEmpty || + str.isEmpty + || testChar(from, str.head) && testChars(from + 1, str.tail) def skipBlanks(idx: Int, step: Int = 1): Int = diff --git a/compiler/test/dotty/tools/utils.scala b/compiler/test/dotty/tools/utils.scala index c33310acf06e..03e25630c421 100644 --- a/compiler/test/dotty/tools/utils.scala +++ b/compiler/test/dotty/tools/utils.scala @@ -124,6 +124,7 @@ private val toolArg = raw"(?://|/\*| \*) ?(?i:(${ToolName.values.mkString("|")}) private val directiveOptionsArg = raw"//> using options (.*)".r.unanchored private val directiveJavacOptions = raw"//> using javacOpt (.*)".r.unanchored private val directiveTargetOptions = raw"//> using target.platform (jvm|scala-js)".r.unanchored +private val directiveUnsupported = raw"//> using (scala) (.*)".r.unanchored private val directiveUnknown = raw"//> using (.*)".r.unanchored // Inspect the lines for compiler options of the form @@ -141,6 +142,7 @@ def toolArgsParse(lines: List[String], filename: Option[String]): List[(String,S case directiveOptionsArg(args) => List(("scalac", args)) case directiveJavacOptions(args) => List(("javac", args)) case directiveTargetOptions(platform) => List(("target", platform)) + case directiveUnsupported(name, args) => Nil case directiveUnknown(rest) => sys.error(s"Unknown directive: `//> using ${CommandLineParser.tokenize(rest).headOption.getOrElse("''")}`${filename.fold("")(f => s" in file $f")}") case _ => Nil } diff --git a/tests/neg/i22906.check b/tests/neg/i22906.check new file mode 100644 index 000000000000..118f9f4fa069 --- /dev/null +++ b/tests/neg/i22906.check @@ -0,0 +1,6 @@ +Flag -indent set repeatedly +-- Error: tests/neg/i22906.scala:6:15 ---------------------------------------------------------------------------------- +6 | {`1`: Int => 5} // error + | ^ + | parentheses are required around the parameter of a lambda + | This construct can be rewritten automatically under -rewrite -source 3.0-migration. diff --git a/tests/neg/i22906.scala b/tests/neg/i22906.scala new file mode 100644 index 000000000000..ca464e99bd48 --- /dev/null +++ b/tests/neg/i22906.scala @@ -0,0 +1,6 @@ +//> using options -rewrite -indent +//> nominally using scala 3.7.0-RC1 +// does not reproduce under "vulpix" test rig, which enforces certain flag sets? + +def program: Int => Int = + {`1`: Int => 5} // error