Skip to content
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

rustdoc: Disambiguate anchors #32985

Merged
merged 1 commit into from
Apr 19, 2016
Merged

rustdoc: Disambiguate anchors #32985

merged 1 commit into from
Apr 19, 2016

Conversation

caipre
Copy link
Contributor

@caipre caipre commented Apr 15, 2016

Closes #32890

@rust-highfive
Copy link
Collaborator

r? @cmr

(rust_highfive has picked a reviewer for you, use r? to override)

@caipre
Copy link
Contributor Author

caipre commented Apr 15, 2016

I'm still learning how to write idiomatic Rust, so feel free to offer suggestions.

Changing to Anchor(Option<String>) meant AssocItemLink was no longer Copy, so I changed all uses to refs.

@mitaa
Copy link
Contributor

mitaa commented Apr 15, 2016

Anchor(Option<&str>) should work too, then it would still be copy.

@@ -2506,6 +2507,11 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
if !is_static || render_static {
let id = derive_id(format!("{}.{}", shortty, name));
write!(w, "<h4 id='{}' class='{}'>", id, shortty)?;
let assoc_link = &AssocItemLink::Anchor(Some(id));
let link = match link {
&AssocItemLink::Anchor(None) => assoc_link,
Copy link
Contributor

@mitaa mitaa Apr 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine, but since you asked for suggestions... 😄

You can write that as something like if let AssocItemLink::Anchor(ref mut id) = link { *id = Some(id) } (changing the function parameter to mut link: AssocItemLink).

You can also remove those pesky & from match arms by doing match *foo.

Copy link
Contributor

@mitaa mitaa Apr 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you fill in the actual id for the other items/match arms too?

You may want to move the filling-in of the id into a inherent method of AssocItemLink then.

@mitaa
Copy link
Contributor

mitaa commented Apr 15, 2016

Looking good! Could you add a test in src/test/rustdoc too?

cc @alexcrichton

@@ -2109,15 +2110,16 @@ fn render_assoc_item(w: &mut fmt::Formatter,
g: &clean::Generics,
selfty: &clean::SelfTy,
d: &clean::FnDecl,
link: AssocItemLink)
link: &AssocItemLink)
-> fmt::Result {
use syntax::abi::Abi;

let name = meth.name.as_ref().unwrap();
let anchor = format!("#{}.{}", shortty(meth), name);
let href = match link {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More usual style would be to write match *link here and simply remove the & prefix on each pattern.

@alexcrichton
Copy link
Member

Thanks @caipre! As mentioned by @mitaa, perhaps this could store String instead of Option<String> as in theory that's the "most correct' way?

@bors
Copy link
Contributor

bors commented Apr 16, 2016

☔ The latest upstream changes (presumably #33005) made this pull request unmergeable. Please resolve the merge conflicts.

@mitaa
Copy link
Contributor

mitaa commented Apr 16, 2016

@alexcrichton
Hmm.. I still think Anchor should store a Option<&str>

  • Anchor(..) is passed down long before knowing the actual id
  • Option<_> allows asserting that an actual id has been filled in
  • For trait definitions we currently don't know the id and have to assume it naively later on https://github.com/rust-lang/rust/pull/32985/files#r59831763
  • &str for ergonomics, because as @caipre has discovered Anchor would not be Copy otherwise

@caipre
Copy link
Contributor Author

caipre commented Apr 16, 2016

Thanks for the review, @mitaa! I've pushed a new commit that incorporates your suggestions, things are indeed much cleaner this way.

I had to work out the right lifetime for the &str, since links tend to be longer lived than ids (eg, https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/render.rs#L2507-L2511). After some thought, I realized I could just return a short-lived copy from the inherent method. It's a bit subtle (or maybe this is a rust-ism?), but I wasn't able to think of another way without embedding a String and using mut.

Regarding adding a test, what is actually required to hit this edge case? I'm making these changes with only a partial understanding of the context. 😄 Something like the trait impls you wrote in this test was my first thought, but I guess that's not sufficient?

@mitaa
Copy link
Contributor

mitaa commented Apr 17, 2016

I think that should be ok, we just need to create an id collision on an inherent impl block. (but to not trigger #31925 you should use concrete types for T, like in the revised version of the test you linked to)

Another option would've been to use the same id for a header inside a doc block, but apparently the . get removed for these, leaving just methodfoo.

@caipre
Copy link
Contributor Author

caipre commented Apr 17, 2016

Sorry, I guess I still don't see how the collisions introduced by these methods aren't exactly what we're trying to address here. As a matter of fact, why isn't that test failing right now? I think there must be more to it than just a collision on an inherent impl, but I'm not sure what.

@mitaa
Copy link
Contributor

mitaa commented Apr 17, 2016

The id attributes on the page are correct, which is what that test tests - what's wrong is that links on the very same element have the wrong link fragment when the target id collides with another one. So what we need to check here are the href attributes. (each fn foo should link to itself, but they currently link to the first occuring fn foo instead)

@caipre
Copy link
Contributor Author

caipre commented Apr 17, 2016

Ah, of course. Lost sight of the forest for the trees there. Thanks for the explanation! I'll get a new test up shortly.

@caipre
Copy link
Contributor Author

caipre commented Apr 18, 2016

@mitaa , @alexcrichton : updated commit with test.

@alexcrichton
Copy link
Member

@bors: r+ 894caf8

Thanks @caipre!

@bors
Copy link
Contributor

bors commented Apr 19, 2016

⌛ Testing commit 894caf8 with merge e8c0aeb...

bors added a commit that referenced this pull request Apr 19, 2016
…excrichton

rustdoc: Disambiguate anchors

Closes #32890
@bors bors merged commit 894caf8 into rust-lang:master Apr 19, 2016
@caipre caipre deleted the rustdoc-disambiguate-impl-anchors branch April 19, 2016 16:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants