Skip to content

Fix relative extern URL depth on source pages#153160

Open
arferreira wants to merge 2 commits intorust-lang:mainfrom
arferreira:fix-relative-extern-url-root-path
Open

Fix relative extern URL depth on source pages#153160
arferreira wants to merge 2 commits intorust-lang:mainfrom
arferreira:fix-relative-extern-url-root-path

Conversation

@arferreira
Copy link
Contributor

@arferreira arferreira commented Feb 27, 2026

View all comments

Source pages with --extern-html-root-url pointing to a relative URL like ../ were generating links with one extra ../. So instead of ../../core/iter/index.html you'd get ../../../core/iter/index.html. Took a while to notice because htmldocck.py uses substring matching — ../../core/ is a substring of ../../../core/ so the test passed anyway.

Two root causes. remote_url_prefix was using cx.current.len() for depth, but during source rendering cx.current is empty — SourceCollector doesn't do module descent. Source pages live under src/<crate_name>/ so the real depth is 2, not 0. On top of that, make_href was trying to compensate by prepending root_path to relative remote URLs (there was a FIXME about this), which just made it worse — ../../ + ../core/iter/ = ../../../core/iter/.

Fix: added remote_item_depth(root_path, doc_depth) that counts ../ segments in root_path when present, falls back to doc_depth otherwise. With the right depth in remote_url_prefix, make_href no longer needs to touch remote URLs at all — so url_parts now returns is_remote = true for all Remote locations. Also renamed is_absoluteis_remote since the semantics were always about "don't modify this URL", not about whether it has a scheme.

Added !has assertions to the test so the wrong URL gets caught explicitly next time.

Follow-up to #152977.

r? @notriddle

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. labels Feb 27, 2026
@rust-log-analyzer

This comment has been minimized.

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 27, 2026
@rustbot
Copy link
Collaborator

rustbot commented Feb 27, 2026

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@arferreira arferreira force-pushed the fix-relative-extern-url-root-path branch from d71f355 to bfeb902 Compare February 27, 2026 12:01
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 27, 2026
@rust-log-analyzer

This comment has been minimized.

@arferreira
Copy link
Contributor Author

@rustbot ready

@rust-log-analyzer

This comment has been minimized.

@arferreira arferreira force-pushed the fix-relative-extern-url-root-path branch from 0f28723 to 6017689 Compare February 27, 2026 14:54
@notriddle
Copy link
Contributor

@bors r+

@rust-bors
Copy link
Contributor

rust-bors bot commented Feb 27, 2026

📌 Commit 6017689 has been approved by notriddle

It is now in the queue for this repository.

@rust-bors rust-bors bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Feb 27, 2026
@rust-bors

This comment has been minimized.

@arferreira arferreira force-pushed the fix-relative-extern-url-root-path branch from 6017689 to 59b37bb Compare March 12, 2026 00:31
@rustbot
Copy link
Collaborator

rustbot commented Mar 12, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@notriddle
Copy link
Contributor

@bors r+

@rust-bors
Copy link
Contributor

rust-bors bot commented Mar 12, 2026

📌 Commit 59b37bb has been approved by notriddle

It is now in the queue for this repository.

@rust-bors rust-bors bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Mar 12, 2026
@rust-bors

This comment has been minimized.

rust-bors bot pushed a commit that referenced this pull request Mar 12, 2026
… r=notriddle

Fix relative extern URL depth on source pages

Source pages with `--extern-html-root-url` pointing to a relative URL like `../` were generating links with one extra `../`. So instead of `../../core/iter/index.html` you'd get `../../../core/iter/index.html`. Took a while to notice because `htmldocck.py` uses substring matching — `../../core/` is a substring of `../../../core/` so the test passed anyway.

Two root causes. `remote_url_prefix` was using `cx.current.len()` for depth, but during source rendering `cx.current` is empty — `SourceCollector` doesn't do module descent. Source pages live under `src/<crate_name>/` so the real depth is 2, not 0. On top of that, `make_href` was trying to compensate by prepending `root_path` to relative remote URLs (there was a FIXME about this), which just made it worse — `../../` + `../core/iter/` = `../../../core/iter/`.

Fix: added `remote_item_depth(root_path, doc_depth)` that counts `../` segments in `root_path` when present, falls back to `doc_depth` otherwise. With the right depth in `remote_url_prefix`, `make_href` no longer needs to touch remote URLs at all — so `url_parts` now returns `is_remote = true` for all `Remote` locations. Also renamed `is_absolute` → `is_remote` since the semantics were always about "don't modify this URL", not about whether it has a scheme.

Added `!has` assertions to the test so the wrong URL gets caught explicitly next time.

Follow-up to #152977.

r? @notriddle
@rust-bors rust-bors bot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Mar 12, 2026
@rust-bors
Copy link
Contributor

rust-bors bot commented Mar 12, 2026

💔 Test for e95d0cd failed: CI. Failed job:

@rust-log-analyzer

This comment has been minimized.

@Zalathar
Copy link
Member

@bors retry

@rust-bors rust-bors bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 12, 2026
Zalathar added a commit to Zalathar/rust that referenced this pull request Mar 12, 2026
…-root-path, r=notriddle

Fix relative extern URL depth on source pages

Source pages with `--extern-html-root-url` pointing to a relative URL like `../` were generating links with one extra `../`. So instead of `../../core/iter/index.html` you'd get `../../../core/iter/index.html`. Took a while to notice because `htmldocck.py` uses substring matching — `../../core/` is a substring of `../../../core/` so the test passed anyway.

Two root causes. `remote_url_prefix` was using `cx.current.len()` for depth, but during source rendering `cx.current` is empty — `SourceCollector` doesn't do module descent. Source pages live under `src/<crate_name>/` so the real depth is 2, not 0. On top of that, `make_href` was trying to compensate by prepending `root_path` to relative remote URLs (there was a FIXME about this), which just made it worse — `../../` + `../core/iter/` = `../../../core/iter/`.

Fix: added `remote_item_depth(root_path, doc_depth)` that counts `../` segments in `root_path` when present, falls back to `doc_depth` otherwise. With the right depth in `remote_url_prefix`, `make_href` no longer needs to touch remote URLs at all — so `url_parts` now returns `is_remote = true` for all `Remote` locations. Also renamed `is_absolute` → `is_remote` since the semantics were always about "don't modify this URL", not about whether it has a scheme.

Added `!has` assertions to the test so the wrong URL gets caught explicitly next time.

Follow-up to rust-lang#152977.

r? @notriddle
Zalathar added a commit to Zalathar/rust that referenced this pull request Mar 12, 2026
…-root-path, r=notriddle

Fix relative extern URL depth on source pages

Source pages with `--extern-html-root-url` pointing to a relative URL like `../` were generating links with one extra `../`. So instead of `../../core/iter/index.html` you'd get `../../../core/iter/index.html`. Took a while to notice because `htmldocck.py` uses substring matching — `../../core/` is a substring of `../../../core/` so the test passed anyway.

Two root causes. `remote_url_prefix` was using `cx.current.len()` for depth, but during source rendering `cx.current` is empty — `SourceCollector` doesn't do module descent. Source pages live under `src/<crate_name>/` so the real depth is 2, not 0. On top of that, `make_href` was trying to compensate by prepending `root_path` to relative remote URLs (there was a FIXME about this), which just made it worse — `../../` + `../core/iter/` = `../../../core/iter/`.

Fix: added `remote_item_depth(root_path, doc_depth)` that counts `../` segments in `root_path` when present, falls back to `doc_depth` otherwise. With the right depth in `remote_url_prefix`, `make_href` no longer needs to touch remote URLs at all — so `url_parts` now returns `is_remote = true` for all `Remote` locations. Also renamed `is_absolute` → `is_remote` since the semantics were always about "don't modify this URL", not about whether it has a scheme.

Added `!has` assertions to the test so the wrong URL gets caught explicitly next time.

Follow-up to rust-lang#152977.

r? @notriddle
rust-bors bot pushed a commit that referenced this pull request Mar 12, 2026
Rollup of 7 pull requests

Successful merges:

 - #153736 (add test that an incomplete feature emits a warning)
 - #153160 (Fix relative extern URL depth on source pages)
 - #153432 (Fix some comments about dataflow analysis.)
 - #153694 (fix(query): Pass Query Key to `value_from_cycle_error`)
 - #153717 (unused_macro_rules switched used and unused comments)
 - #153748 (editorconfig: css uses tabs)
 - #153750 (rustc-dev-guide subtree update)
@rust-bors
Copy link
Contributor

rust-bors bot commented Mar 12, 2026

⌛ Testing commit 59b37bb with merge c66e4b8...

Workflow: https://github.com/rust-lang/rust/actions/runs/22995536645

rust-bors bot pushed a commit that referenced this pull request Mar 12, 2026
… r=notriddle

Fix relative extern URL depth on source pages

Source pages with `--extern-html-root-url` pointing to a relative URL like `../` were generating links with one extra `../`. So instead of `../../core/iter/index.html` you'd get `../../../core/iter/index.html`. Took a while to notice because `htmldocck.py` uses substring matching — `../../core/` is a substring of `../../../core/` so the test passed anyway.

Two root causes. `remote_url_prefix` was using `cx.current.len()` for depth, but during source rendering `cx.current` is empty — `SourceCollector` doesn't do module descent. Source pages live under `src/<crate_name>/` so the real depth is 2, not 0. On top of that, `make_href` was trying to compensate by prepending `root_path` to relative remote URLs (there was a FIXME about this), which just made it worse — `../../` + `../core/iter/` = `../../../core/iter/`.

Fix: added `remote_item_depth(root_path, doc_depth)` that counts `../` segments in `root_path` when present, falls back to `doc_depth` otherwise. With the right depth in `remote_url_prefix`, `make_href` no longer needs to touch remote URLs at all — so `url_parts` now returns `is_remote = true` for all `Remote` locations. Also renamed `is_absolute` → `is_remote` since the semantics were always about "don't modify this URL", not about whether it has a scheme.

Added `!has` assertions to the test so the wrong URL gets caught explicitly next time.

Follow-up to #152977.

r? @notriddle
@Zalathar
Copy link
Member

Failed in rollup: #153761 (comment)

@bors r-

@rust-bors rust-bors bot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Mar 12, 2026
@rust-bors
Copy link
Contributor

rust-bors bot commented Mar 12, 2026

This pull request was unapproved.

This PR was contained in a rollup (#153761), which was unapproved.

Auto build was cancelled due to unapproval. Cancelled workflows:

@Zalathar
Copy link
Member

@bors try jobs=dist-x86_64-linux-alt

@rust-bors
Copy link
Contributor

rust-bors bot commented Mar 12, 2026

⌛ Trying commit 1369e07 with merge 052b44b

To cancel the try build, run the command @bors try cancel.

Workflow: https://github.com/rust-lang/rust/actions/runs/22998576397

rust-bors bot pushed a commit that referenced this pull request Mar 12, 2026
… r=<try>

Fix relative extern URL depth on source pages


try-job: dist-x86_64-linux-alt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants