Avoid Box in href_relative_parts.
This reverts part of #91948, going back to returning a `UrlPartsBuilder`. It makes the code simpler, and also avoids some allocations.
This commit is contained in:
parent
283db70ace
commit
581fd271f6
3 changed files with 20 additions and 25 deletions
|
|
@ -510,7 +510,7 @@ fn url_parts(
|
|||
builder.extend(module_fqp.iter().copied());
|
||||
Ok(builder)
|
||||
}
|
||||
ExternalLocation::Local => Ok(href_relative_parts(module_fqp, relative_to).collect()),
|
||||
ExternalLocation::Local => Ok(href_relative_parts(module_fqp, relative_to)),
|
||||
ExternalLocation::Unknown => Err(HrefError::DocumentationNotBuilt),
|
||||
}
|
||||
}
|
||||
|
|
@ -587,7 +587,7 @@ pub(crate) fn href_with_root_path(
|
|||
Some(&(ref fqp, shortty)) => (fqp, shortty, {
|
||||
let module_fqp = to_module_fqp(shortty, fqp.as_slice());
|
||||
debug!(?fqp, ?shortty, ?module_fqp);
|
||||
href_relative_parts(module_fqp, relative_to).collect()
|
||||
href_relative_parts(module_fqp, relative_to)
|
||||
}),
|
||||
None => {
|
||||
// Associated items are handled differently with "jump to def". The anchor is generated
|
||||
|
|
@ -619,34 +619,30 @@ pub(crate) fn href(
|
|||
/// Both paths should only be modules.
|
||||
/// This is because modules get their own directories; that is, `std::vec` and `std::vec::Vec` will
|
||||
/// both need `../iter/trait.Iterator.html` to get at the iterator trait.
|
||||
pub(crate) fn href_relative_parts<'fqp>(
|
||||
fqp: &'fqp [Symbol],
|
||||
relative_to_fqp: &[Symbol],
|
||||
) -> Box<dyn Iterator<Item = Symbol> + 'fqp> {
|
||||
pub(crate) fn href_relative_parts(fqp: &[Symbol], relative_to_fqp: &[Symbol]) -> UrlPartsBuilder {
|
||||
for (i, (f, r)) in fqp.iter().zip(relative_to_fqp.iter()).enumerate() {
|
||||
// e.g. linking to std::iter from std::vec (`dissimilar_part_count` will be 1)
|
||||
if f != r {
|
||||
let dissimilar_part_count = relative_to_fqp.len() - i;
|
||||
let fqp_module = &fqp[i..];
|
||||
return Box::new(
|
||||
iter::repeat_n(sym::dotdot, dissimilar_part_count)
|
||||
.chain(fqp_module.iter().copied()),
|
||||
);
|
||||
return iter::repeat_n(sym::dotdot, dissimilar_part_count)
|
||||
.chain(fqp_module.iter().copied())
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
match relative_to_fqp.len().cmp(&fqp.len()) {
|
||||
Ordering::Less => {
|
||||
// e.g. linking to std::sync::atomic from std::sync
|
||||
Box::new(fqp[relative_to_fqp.len()..fqp.len()].iter().copied())
|
||||
fqp[relative_to_fqp.len()..fqp.len()].iter().copied().collect()
|
||||
}
|
||||
Ordering::Greater => {
|
||||
// e.g. linking to std::sync from std::sync::atomic
|
||||
let dissimilar_part_count = relative_to_fqp.len() - fqp.len();
|
||||
Box::new(iter::repeat_n(sym::dotdot, dissimilar_part_count))
|
||||
iter::repeat_n(sym::dotdot, dissimilar_part_count).collect()
|
||||
}
|
||||
Ordering::Equal => {
|
||||
// linking to the same module
|
||||
Box::new(iter::empty())
|
||||
UrlPartsBuilder::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,51 +1,51 @@
|
|||
use rustc_span::{Symbol, sym};
|
||||
use rustc_span::{Symbol, create_default_session_globals_then, sym};
|
||||
|
||||
use crate::html::format::href_relative_parts;
|
||||
|
||||
fn assert_relative_path(expected: &[Symbol], relative_to_fqp: &[Symbol], fqp: &[Symbol]) {
|
||||
// No `create_default_session_globals_then` call is needed here because all
|
||||
// the symbols used are static, and no `Symbol::intern` calls occur.
|
||||
assert_eq!(expected, href_relative_parts(&fqp, &relative_to_fqp).collect::<Vec<_>>());
|
||||
fn assert_relative_path(expected: &str, relative_to_fqp: &[Symbol], fqp: &[Symbol]) {
|
||||
create_default_session_globals_then(|| {
|
||||
assert_eq!(expected, href_relative_parts(&fqp, &relative_to_fqp).finish());
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn href_relative_parts_basic() {
|
||||
let relative_to_fqp = &[sym::std, sym::vec];
|
||||
let fqp = &[sym::std, sym::iter];
|
||||
assert_relative_path(&[sym::dotdot, sym::iter], relative_to_fqp, fqp);
|
||||
assert_relative_path("../iter", relative_to_fqp, fqp);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn href_relative_parts_parent_module() {
|
||||
let relative_to_fqp = &[sym::std, sym::vec];
|
||||
let fqp = &[sym::std];
|
||||
assert_relative_path(&[sym::dotdot], relative_to_fqp, fqp);
|
||||
assert_relative_path("..", relative_to_fqp, fqp);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn href_relative_parts_different_crate() {
|
||||
let relative_to_fqp = &[sym::std, sym::vec];
|
||||
let fqp = &[sym::core, sym::iter];
|
||||
assert_relative_path(&[sym::dotdot, sym::dotdot, sym::core, sym::iter], relative_to_fqp, fqp);
|
||||
assert_relative_path("../../core/iter", relative_to_fqp, fqp);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn href_relative_parts_same_module() {
|
||||
let relative_to_fqp = &[sym::std, sym::vec];
|
||||
let fqp = &[sym::std, sym::vec];
|
||||
assert_relative_path(&[], relative_to_fqp, fqp);
|
||||
assert_relative_path("", relative_to_fqp, fqp);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn href_relative_parts_child_module() {
|
||||
let relative_to_fqp = &[sym::std];
|
||||
let fqp = &[sym::std, sym::vec];
|
||||
assert_relative_path(&[sym::vec], relative_to_fqp, fqp);
|
||||
assert_relative_path("vec", relative_to_fqp, fqp);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn href_relative_parts_root() {
|
||||
let relative_to_fqp = &[];
|
||||
let fqp = &[sym::std];
|
||||
assert_relative_path(&[sym::std], relative_to_fqp, fqp);
|
||||
assert_relative_path("std", relative_to_fqp, fqp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ pub(crate) struct UrlPartsBuilder {
|
|||
|
||||
impl UrlPartsBuilder {
|
||||
/// Create an empty buffer.
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn new() -> Self {
|
||||
Self { buf: String::new() }
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue