Skip to content

Conversation

@mbland
Copy link

@mbland mbland commented Dec 17, 2025

Updates the -Wconf:src filter to avoid using java.nio.file.Path.toURI in order to fix Windows source path conversions.

Path.toURI prepends the current working directory to Windows-like paths unconditionally, and converts backslashes in such paths to %5C escape sequences This can cause -Wconf:src filters that work on non-Windows platforms to fail on Windows.

For example, before this change, the Path.toURI conversion in the SourcePattern case from MessageFilter.matches() produced:

original: Optional[C:\foo\bar\myfile.scala]
resolved: /Users/mbland/src/scala/scala3/C:%5Cfoo%5Cbar%5Cmyfile.scala

After this change, it produces the following, which still prepends the current working directory, but properly converts path separators to /:

original: Optional[C:\foo\bar\myfile.scala]
resolved: /Users/mbland/src/scala/scala3/C:/foo/bar/myfile.scala

This change is based on scala/scala#11192, and also adapts some test cases from that pull request to validate symlink and normalized path handling. This change also extracts the diagnosticWarning helper method to reduce duplication between new and existing test cases.

Fixes #24771. Review by @lrytz.

Updates the -Wconf:src filter to avoid using `java.nio.file.Path.toURI`
in order to fix Windows source path conversions.

`Path.toURI` prepends the current working directory to Windows-like
paths unconditionally, and converts backslashes in such paths to `%5C`
escape sequences  This can cause `-Wconf:src` filters that work on
non-Windows platforms to fail on Windows.

For example, before this change, the `Path.toURI` conversion in the
`SourcePattern` case from `MessageFilter.matches()` produced:

```txt
original: Optional[C:\foo\bar\myfile.scala]
resolved: /Users/mbland/src/scala/scala3/C:%5Cfoo%5Cbar%5Cmyfile.scala
```

After this change, it produces the following, which still prepends the
current working directory, but properly converts path separators to `/`:

```txt
original: Optional[C:\foo\bar\myfile.scala]
resolved: /Users/mbland/src/scala/scala3/C:/foo/bar/myfile.scala
```

This change is based on scala/scala#11192, and also adapts some test
cases from that pull request to validate symlink and normalized path
handling. This change also extracts the `diagnosticWarning` helper
method to reduce duplication between new and existing test cases.
@lrytz
Copy link
Member

lrytz commented Dec 18, 2025

After this change, it produces the following, which still prepends the current working directory, but properly converts path separators to /:

original: Optional[C:\foo\bar\myfile.scala]
resolved: /Users/mbland/src/scala/scala3/C:/foo/bar/myfile.scala

After blowing the dust off my Windows VM, I can confirm this is platform dependent.

On Windows:

scala> java.io.File("C:\\foo\\..\\bar\\f.txt").toPath.toAbsolutePath.normalize
val res0: java.nio.file.Path = C:\bar\f.txt

scala> java.io.File("C:\\foo\\..\\bar\\f.txt").toPath.toAbsolutePath.toUri.normalize.getRawPath
val res1: String = /C:/bar/f.txt

On macOS:

scala> java.io.File("C:\\foo\\..\\bar\\f.txt").toPath.toAbsolutePath.normalize
val res0: java.nio.file.Path = /Users/luc/code/scala/scala13/sandbox/C:\foo\..\bar\f.txt

scala> java.io.File("C:\\foo\\..\\bar\\f.txt").toPath.toAbsolutePath.toUri.normalize.getRawPath
val res1: String = /Users/luc/code/scala/scala13/sandbox/C:%5Cfoo%5C..%5Cbar%5Cf.txt

So arguably the current implementation using toUri is also OK..?

@mbland
Copy link
Author

mbland commented Dec 18, 2025

So arguably the current implementation using toUri is also OK..?

Hmm, arguably, yes. So if you want, I could:

  • Close this pull request outright (and maybe open a new one for Scala 2 that uses toURI and removes the Windows path assertions, to ensure parity between the implementations?)
  • Pare the changes down to only add the new tests (minus the Windows path test), which may be good to have
  • Keep the pull request as it is, to make the Scala 3 implementation closer to the implementation from Don't resolve symlinks in -Wconf:src scala#11192

One other thing I noticed was that, unlike the Scala 2 implementation, the src filter doesn't automatically prepend / to patterns to ensure they match an entire path component. For example, this currently fails:

  @Test def `Wconf src filter only matches entire directory path components`: Unit =
    val path = Path("foobar/File.scala")
    val result = wconfSrcFilterTest(
      argsStr = "-Wconf:src=bar/.*\\.scala:s",
      warning = diagnosticWarning(util.SourceFile(new PlainFile(path), "UTF-8"))
    )
    assertEquals(result, Right(reporting.Action.Warning))

Note that the current tests reverse the expected, actual ordering of the assertEquals parameters, so the assertion failure message reads backwards:

[error] Test dotty.tools.dotc.config.ScalaSettingsTests.Wconf src filter only matches entire directory path components failed:
  java.lang.AssertionError: expected:<Right(Silent)> but was:<Right(Warning)>, took 0.001 sec
[error]     at dotty.tools.dotc.config.ScalaSettingsTests.Wconf src filter only matches entire directory path components(ScalaSettingsTests.scala:308)

So the fourth option would be:

  • Repurpose this pull request so that src path prefixes only match entire directory path components.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

-Wconf:src source path conversion to URI breaks Windows paths

3 participants