Skip to content

🐛 fix(mirror): drop the unreachable parent fallback - #2189

Merged
gaborbernat merged 1 commit into
mainfrom
fix/mirror-parent-fallback-2180
Sep 4, 2026
Merged

🐛 fix(mirror): drop the unreachable parent fallback#2189
gaborbernat merged 1 commit into
mainfrom
fix/mirror-parent-fallback-2180

Conversation

@gaborbernat

@gaborbernat gaborbernat commented Sep 4, 2026

Copy link
Copy Markdown
Member

A requirements include resolved its target against file.path.parent() with a . fallback for the None case. No input reaches that branch, so #2162 cannot hold main at 100%: a test can neither cover the line nor remove it. What makes it uncoverable rather than untested is the closure inside unwrap_or_else, a function in this crate that nothing calls. An expect takes a &str and leaves no such function behind.

I treated the deletion as something to prove rather than to take on the issue's word, and the proof came out stronger than the issue states. Path::parent answers None for an empty path, or one that is nothing but a root or a prefix, and for nothing else. A bare requirements.txt yields Some(""), not None, and that empty parent joins to the sibling path this code wants. Every file on the include stack came from requirement_file, which calls read_to_string before the file joins the stack. A root and a drive prefix are directories, and an empty path names nothing, so none of them survives that read. The property generalises: any path with no parent denotes a root, a prefix, or nothing, and none of those reads as a regular file. It rests on no enumeration of / and "" as special cases.

Three tests pin the refusal the argument depends on, and they passed against unmodified e64cc8308 before the fallback came out, which is what makes them evidence rather than decoration. Two cover the top level, where the path arrives straight from configuration, and one covers an include of -r /, where an absolute target replaces the parent during the join. Those are the only two ways to construct a RequirementFile.

The call now states the invariant through expect, matching the loop above it, which already says expect("the stack has a completed file") for its own stack invariant. Every input that can reach the call behaves as before, because the tests show that no input with a None parent gets that far. The difference lives in a state something earlier refuses.

The coverage numbers confirm that mechanism rather than just agreeing with it. Before the change llvm-cov reported selection.rs with 55 functions, one of them missed, and one missed line. After it, 54 functions, none missed, and no missed lines. The function count falls by exactly one, which is the closure going away and taking the uncoverable line with it, so the line leaves the report because it stopped existing.

A workspace grep finds no other parent().unwrap_or anywhere. The three remaining unwrap_or calls in this file take a different shape and stay: two default a string scan when no delimiter is present, which ordinary lines do, and one defaults an absent digest. None stands in for an unreachable state.

Closes #2180

A requirements include resolved its target against `parent()` with a `.`
fallback for the `None` case. Nothing can take that branch, so the coverage gate
reported a line no input reaches, and the closure behind `unwrap_or_else` is
what made it uncoverable rather than merely untested.

`Path::parent` answers `None` only for an empty path or one that is nothing but
a root or a prefix, and every file on the include stack came from
`requirement_file`, which reads it first. A root is a directory and an empty
path names nothing, so neither survives that read. The call now says so through
an `expect`, matching how the loop above already states its stack invariant, and
a bare filename still keeps the empty parent that joins to its sibling.

Three tests pin the refusal the argument rests on, at the top level for both
shapes and through an include, so the invariant is checked rather than asserted.
@gaborbernat gaborbernat added the bug Something isn't working label Sep 4, 2026
@codspeed-hq

codspeed-hq Bot commented Sep 4, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 29 untouched benchmarks
⏩ 133 skipped benchmarks1


Comparing fix/mirror-parent-fallback-2180 (5c88dff) with main (6fa86d9)

Open in CodSpeed

Footnotes

  1. 133 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@gaborbernat
gaborbernat merged commit 0df149b into main Sep 4, 2026
20 checks passed
@gaborbernat
gaborbernat deleted the fix/mirror-parent-fallback-2180 branch September 4, 2026 09:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove the unreachable parent fallback in mirror selection

1 participant