-
Notifications
You must be signed in to change notification settings - Fork 265
Guarantee config-file search terminates on paths with redundant separators #1213
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
Open
adityasingh2400
wants to merge
2
commits into
swiftlang:main
Choose a base branch
from
adityasingh2400:fix-issue-1035
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we stop the first time we try to delete the last path component and it's a no-op, we would never find the configuration file in a directory above that; we would stop the loop too early.
If I do the following in Swift 6.3.2 on macOS Tahoe, I see the following behavior, which seems to imply that
deleteLastPathComponent()does the right thing:I'm not sure this change is correct or doing what it's intended to do, and the test is passing because the behavior is already correct (or at least the test isn't exhibiting the bug in the original issue) and thus we never hit this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, and I verified it on the same toolchain (Swift 6.3.2, macOS Tahoe). Tracing the loop on the standardized input path:
So on current Foundation
deleteLastPathComponent()makes progress every step and the loop terminates without the guard. The guard is never reached here, and the terminate test passes because the behavior is already correct, exactly as you said. The original #1035 repro was on an older Foundation where a trailing redundant separator madedeleteLastPathComponent()a no-op (it stalled atDemoSwift//and never reached root).On your other concern, stopping too early: I do not think the guard can do that.
deleteLastPathComponent()is a pure function of the path, so if it is a no-op once it is a no-op on every later iteration too. The break therefore only fires in the exact state that would otherwise loop forever, and there is never a reachable parent above that point that it skips. I pushed a commit that rewrites the comment to say this honestly: the guard is a defensive backstop, not the load-bearing fix on current Foundation.Given that, your call on direction. Two options I am happy with: (1) close this as effectively fixed upstream in Foundation, since the live toolchains terminate, or (2) keep it as the two regression tests that lock #1035 stays fixed plus the cheap guard for any platform or Foundation version where the ascent still stalls. I lean slightly toward (2) for the regression coverage, but I will defer to your preference and can strip it to whichever shape you want.