Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

swift-format causes a infinite loop on Linux if .swift-format is missing #847

Closed
kkebo opened this issue Oct 11, 2024 · 6 comments
Closed

Comments

@kkebo
Copy link
Contributor

kkebo commented Oct 11, 2024

Description

On Linux, when all ancestor directories do not have .swift-format, swift-format causes a infinite loop. swift-format lint and swift-format format do not work.

Steps to reproduce

Please make sure that /, /home, and /home/<user name> do not contain .swift-format.

$ cd
$ echo 'let foo:Int=0' > test.swift
$ swift format lint test.swift

Expected behavior

test.swift:1:9: warning: [Spacing] add 1 space
test.swift:1:12: warning: [Spacing] add 1 space
test.swift:1:13: warning: [Spacing] add 1 space

Actual behavior

swift-format never finishes because of a infinite loop.

Environment

I use swift-format bundled in the Swift 6.0.1 toolchain.

$ uname -a
Linux Raspberry-beetle 6.6.51+rpt-rpi-2712 #1 SMP PREEMPT Debian 1:6.6.51-1+rpt2 (2024-10-01) aarch64 GNU/Linux
$ swift --version
Swift version 6.0.1 (swift-6.0.1-RELEASE)
Target: aarch64-unknown-linux-gnu
$ swift format --version
main
$ which swift-format
/home/kebo/.local/bin/swift-format
$ swiftly list
Installed release toolchains
----------------------------
Swift 6.0.1 (in use)

Installed snapshot toolchains
-----------------------------
6.0-snapshot-2024-09-17

Supplement

I think that the root cause is a combination of swift-foundation's URL and swift-format's this line.

swift-foundation's URL is different from macOS's URL.

  • On Linux (Swift 6.0.1)
    • URL(filePath: "/foo", directoryHint: .notDirectory).deletingLastPathComponent().path()
      • returns "/"
    • URL(filePath: "/foo", directoryHint: .isDirectory).deletingLastPathComponent().path()
      • returns "" (empty string)
  • On macOS 15.0.1 (Xcode 16.0)
    • Both return "/"

On Linux, when I added print(self.path) to the line, self.path changed as follows.

  • "/foo/bar/baz"
  • "/foo/bar"
  • "/foo"
  • "" (empty string)
  • "" (empty string)
  • "" (empty string)
  • ... (infinite loop)

So self.path == "/" couldn't return true forever.

@kkebo
Copy link
Contributor Author

kkebo commented Oct 11, 2024

swiftlang/swift-foundation#969 may fix this issue.

@kkebo
Copy link
Contributor Author

kkebo commented Oct 11, 2024

#802 fixed this problem once, but it happened again with #845.

@ahoppen
Copy link
Member

ahoppen commented Oct 11, 2024

Synced to Apple’s issue tracker as rdar://137738047

@ahoppen
Copy link
Member

ahoppen commented Oct 11, 2024

Neither #802 nor #845 apply if you’re using swift-format from a Swift 6.0 toolchain because those PRs only got merged into main, not into release/6.0.

I’m cherry-picking the fixes to 6.0 in #849

@kkebo
Copy link
Contributor Author

kkebo commented Oct 11, 2024

@ahoppen

My comment below is the result of building and testing from source code of the main branch with a Swift 6.0 toolchain.

#802 fixed this problem once, but it happened again with #845.

And thank you for fixing the issue in #848 and #849.

@ahoppen
Copy link
Member

ahoppen commented Oct 11, 2024

Oh, I see. I wasn’t sure if you built from source. Thanks for your detailed analysis.

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

No branches or pull requests

2 participants