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

Add intra-doc field@ disambiguator #83546

Closed
wants to merge 2 commits into from

Conversation

camelid
Copy link
Member

@camelid camelid commented Mar 27, 2021

This change required some refactoring because fields (1) don't get their
own Res (instead they seem to use the Res of their parent node) and
(2) DefKind::Field::ns() returns None, so rustdoc has to
special-case fields. For some reason, we treat fields as if they're in
the value namespace - I'm not sure why that is.

Fixes #80283.

@camelid camelid added A-intra-doc-links Area: Intra-doc links, the ability to link to items in docs by name T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Mar 27, 2021
@rust-highfive
Copy link
Collaborator

Some changes occurred in intra-doc-links.

cc @jyn514

@rust-highfive
Copy link
Collaborator

r? @jyn514

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 27, 2021
This change required some refactoring because fields (1) don't get their
own `Res` (instead they seem to use the `Res` of their parent node) and
(2) `DefKind::Field::ns()` returns `None`, so rustdoc has to
special-case fields. For some reason, we treat fields as if they're in
the value namespace - I'm not sure why that is.
@rust-log-analyzer

This comment has been minimized.

@camelid camelid marked this pull request as draft March 27, 2021 03:07
Copy link
Member

@jyn514 jyn514 left a comment

Choose a reason for hiding this comment

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

I'm actually kinda iffy on this, I prefer the current behavior and we get to avoid clashes with foo.com.
Yeah I'm just worried about the possibilities of ambiguity. It was listed as an optional extension in the rfc and iirc this was part of why.

@Manishearth are you happy with this now that there's no ambiguity?

Comment on lines +569 to +571
if expect_field {
self.resolve_variant_or_field(item_name, did, ty_res, extra_fragment)
} else {
Copy link
Member

Choose a reason for hiding this comment

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

This function is already super long with lots of indentation - could you change this to a separate match arm? Res::Def(...) if expect_field => { ... }

Alternatively you could turn this whole match into a separate function, which lets you do an early return.

Comment on lines +674 to +675
match self.cx.tcx.type_of(did).kind() {
ty::Adt(def, _) => {
Copy link
Member

Choose a reason for hiding this comment

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

nit: I would make this an early return so you don't have so much indentation.

Suggested change
match self.cx.tcx.type_of(did).kind() {
ty::Adt(def, _) => {
let def = match self.cx.tcx.type_of(did).kind() {
ty::Adt(def, _) => def,
_ => return None,
};

Comment on lines +1178 to +1180
// Fields are resolved to their parent type's Res.
// FIXME: what about DefKind::Variant?
| (DefKind::Struct | DefKind::Enum, Some(Disambiguator::Kind(DefKind::Field)))
Copy link
Member

Choose a reason for hiding this comment

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

This looks suspicious ... I'd have to look into how exactly rustc_resolve behaves here, but I'd rather not allow people to write

/// [field@S]
struct S;

and have it work. Maybe you could add this to yet another side channel? 😅

Copy link
Member Author

Choose a reason for hiding this comment

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

This looks suspicious ... I'd have to look into how exactly rustc_resolve behaves here, but I'd rather not allow people to write

/// [field@S]
struct S;

and have it work.

Your suspicion is correct, because that code works fine....

I don't think it's rustc_resolve behavior; we seem to use rustc_resolve to resolve everything up until the field, and then resolve that manually ourselves somehow. It seems like this code could use some cleanup; I think it would be a good idea for us to have our own Res enum that includes fields. Maybe it would be a good idea to do that first before implementing this feature?

Or, is there some way that rustc_resolve can resolve fields for us?

Copy link
Member

Choose a reason for hiding this comment

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

Or, is there some way that rustc_resolve can resolve fields for us?

I wouldn't expect so, since that needs type information (put another way, it can only resolve things that have a namespace).

I think it would be a good idea for us to have our own Res enum that includes fields.

Ok, there's already a custom Res type you could modify:

. But I'm not sure why that needs a new variant, I would expect using a normal Res::Def(DefKind::Field) to work.

Copy link
Member Author

@camelid camelid Apr 1, 2021

Choose a reason for hiding this comment

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

I think it would be a good idea for us to have our own Res enum that includes fields.

Ok, there's already a custom Res type you could modify:

. But I'm not sure why that needs a new variant, I would expect using a normal Res::Def(DefKind::Field) to work.

Sounds good! I said that because I didn't understand why we didn't just use Res::Def(DefKind::Field) for the field resolution. So I think a good cleanup to do before I add this feature is to use Res::Def(DefKind::Field) to resolve fields instead of resolving them to their parent struct/enum. I think I'll play around with that a bit to see if I can get it working.

Copy link
Member

Choose a reason for hiding this comment

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

So I think a good cleanup to do before I add this feature is to use Res::Def(DefKind::Field) to resolve fields instead of resolving them to their parent struct/enum. I think I'll play around with that a bit to see if I can get it working.

Buyer beware:

// HACK(jynelson): `clean` expects the type, not the associated item
// but the disambiguator logic expects the associated item.
// Store the kind in a side channel so that only the disambiguator logic looks at it.
self.kind_side_channel.set(Some((kind.as_def_kind(), id)));

but if you get it working that would be amazing :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Uh-oh... ;)

Comment on lines +1651 to +1653
// Fields technically don't have a namespace, but we treat
// fields as if they belong to the value namespace.
DefKind::Field => TypeNS,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// Fields technically don't have a namespace, but we treat
// fields as if they belong to the value namespace.
DefKind::Field => TypeNS,
// Fields technically don't have a namespace, but we treat
// fields as if they belong to the value namespace.
DefKind::Field => ValueNS,

Do we need to return a namespace here? Would it be better to return an Option, the same way DefKind::ns does?

Copy link
Member Author

Choose a reason for hiding this comment

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

Oops... I said they belong to the value namespace because I saw that elsewhere, but I think in my mind I thought type namespace fitted better. Need to figure out if it makes sense to update elsewhere to use TypeNS or to switch to using ValueNS here...

@jyn514 jyn514 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 Mar 27, 2021
@Manishearth
Copy link
Member

@jyn514 If this is allowing field@Foo.bar that's still ambiguous, @s have meaning in URLs. field@Foo::bar is fine by me, that was never what my opposition was to.

@jyn514
Copy link
Member

jyn514 commented Mar 27, 2021

field@Foo::bar is fine by me, that was never what my opposition was to.

Ok great, that's what this is :)

@camelid
Copy link
Member Author

camelid commented Mar 28, 2021

field@Foo::bar is fine by me, that was never what my opposition was to.

Great! 👍

I had an idea on how to get this to be like Foo.bar but without the ambiguity: Instead of rendering [`field@Foo::bar`] (and [`Foo::bar`] too if there's no method named bar) as Foo::bar, we render it as Foo.bar. What do you think?

@Manishearth
Copy link
Member

That would be the first time we clean up the displayed text in intra doc links, no? Or do we do that already?

@camelid
Copy link
Member Author

camelid commented Mar 28, 2021

That would be the first time we clean up the displayed text in intra doc links, no? Or do we do that already?

We remove disambiguators from the displayed text, so [`prim@str`] renders as str. This would be like an extension of that.

@jyn514
Copy link
Member

jyn514 commented Mar 29, 2021

I would rather not change the display. Foo.bar is valid syntax and I don't think people will always want it to be changed (as opposed to disambiguators, which are invalid syntax unless we remove them).

@Manishearth
Copy link
Member

Yeah I think I'm aligned with @jyn514 on this one for now

@jyn514
Copy link
Member

jyn514 commented Mar 29, 2021

I had an idea on how to get this to be like Foo.bar but without the ambiguity: Instead of rendering [field@Foo::bar] (and [Foo::bar] too if there's no method named bar) as Foo::bar, we render it as Foo.bar. What do you think?

Actually this is a good point - I think we should only remove the disambiguator if it's not a field, since otherwise it's ambiguous with the method (and Foo::bar isn't valid syntax for a field). People can still add their own titles if they want.

@camelid
Copy link
Member Author

camelid commented Apr 1, 2021

Actually this is a good point - I think we should only remove the disambiguator if it's not a field, since otherwise it's ambiguous with the method (and Foo::bar isn't valid syntax for a field). People can still add their own titles if they want.

I actually meant without the ambiguity that Manish was concerned about re domain names.

I think we should still strip the disambiguator. It's inconsistent and surprising if we strip all disambiguators except just field@. I don't think the ambiguity is a real concern since in some cases the reader can tell from context, and in all cases they can just click the link to find out.

@Manishearth
Copy link
Member

Yeah I'm happy to strip the disambiguator.

@jyn514
Copy link
Member

jyn514 commented Apr 1, 2021

Ok, in that case this is just waiting on questions about the implementation.

@camelid
Copy link
Member Author

camelid commented Apr 1, 2021

I think I would like to talk about #83546 (comment) before I address the review comments, since I don't want to waste time working on things that would be fixed by doing the cleanup.

@camelid camelid added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 1, 2021
@rust-log-analyzer
Copy link
Collaborator

The job mingw-check failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
configure: rust.channel         := nightly
configure: rust.debug-assertions := True
configure: llvm.assertions      := True
configure: dist.missing-tools   := True
configure: build.configure-args := ['--enable-sccache', '--disable-manage-submodu ...
configure: writing `config.toml` in current directory
configure: 
configure: run `python /checkout/x.py --help`
configure: 
---
Checking which error codes lack tests...
Found 435 error codes
Found 0 error codes with no tests
Done!
tidy error: /checkout/src/test/rustdoc/intra-doc/field-disambiguator.rs:10: line longer than 100 chars
tidy error: /checkout/src/test/rustdoc/intra-doc/field-disambiguator.rs:24: line longer than 100 chars
tidy error: /checkout/src/test/rustdoc/intra-doc/field-disambiguator.rs:25: line longer than 100 chars
some tidy checks failed


command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-tidy" "/checkout" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "/checkout/obj/build"


failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test --stage 2 src/tools/tidy
Build completed unsuccessfully in 0:00:14

@jyn514
Copy link
Member

jyn514 commented Apr 1, 2021

I think I would like to talk about #83546 (comment) before I address the review comments, since I don't want to waste time working on things that would be fixed by doing the cleanup.

This link doesn't go anywhere for me - can you summarize what it says so I can find it?

@camelid
Copy link
Member Author

camelid commented Apr 1, 2021

I think I would like to talk about #83546 (comment) before I address the review comments, since I don't want to waste time working on things that would be fixed by doing the cleanup.

This link doesn't go anywhere for me - can you summarize what it says so I can find it?

Hmm, the link doesn't work for me either. It's the comment that you just replied to. Here's a working link: #83546 (comment)

@jyn514 jyn514 removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 2, 2021
@bors
Copy link
Contributor

bors commented Apr 6, 2021

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

@jyn514
Copy link
Member

jyn514 commented Jul 2, 2021

@camelid are you planning to follow up on this?

@camelid
Copy link
Member Author

camelid commented Jul 11, 2021

I'm not sure if I'll have the time soon to do the necessary refactor to get this working. I'm trying to make progress on some smaller PRs that I've had open for a while. I might be able to get to this after those.

@jyn514
Copy link
Member

jyn514 commented Aug 16, 2021

@camelid I'm going to close this so someone else can pick up the issue - feel free to come back to this if you have time :)

@jyn514 jyn514 closed this Aug 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-intra-doc-links Area: Intra-doc links, the ability to link to items in docs by name 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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add an intra-doc link disambiguator for fields
6 participants