Skip to content

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

Closed
@kkebo

Description

@kkebo

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions