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

intra-doc links: crate:: considers the traits in the crate scope, not the current scope #78696

Closed
pitaj opened this issue Nov 3, 2020 · 8 comments · Fixed by #95337
Closed
Labels
A-intra-doc-links Area: Intra-doc links, the ability to link to items in docs by name C-bug Category: This is a bug. E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.

Comments

@pitaj
Copy link
Contributor

pitaj commented Nov 3, 2020

I tried this code:

#![allow(unused_imports, dead_code)]

// Uncomment this and the warning will go away
// use crate::io::Read;

pub mod io {
    pub trait Read {
        fn read(&mut self, buf: &mut [u8]) -> usize;
    }
}

pub mod bufreader {
    use crate::io::Read;

    /// It can be excessively inefficient to work directly with a [`Read`] instance.
    /// For example, every [`Read::read`] call to [`TcpStream::read`] or [`TcpStream::yes`] on [`TcpStream`]
    ///
    /// [`TcpStream::yes`]: crate::net::TcpStream::yes
    /// [`TcpStream::read`]: crate::net::TcpStream::read
    /// [`Read::read`]: Read::read
    /// [`TcpStream`]: crate::net::TcpStream
    pub struct BufReader;
}

pub mod net {
    pub struct TcpStream;

    impl TcpStream {
        fn yes() -> bool {
            true
        }
    }

    impl crate::io::Read for TcpStream {
        fn read(&mut self, buf: &mut [u8]) -> usize {
            buf.len()
        }
    }
}

I expected to see this happen: Rustdoc should complete with no warnings

Instead, this happened:

Only the following warning is output by rustdoc

warning: unresolved link to `self::net::TcpStream::read`
  --> src/main.rs:13:30
   |
13 |     /// [`TcpStream::read`]: crate::net::TcpStream::read
   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the struct `TcpStream` has no field or associated item named `read`
   |
   = note: `#[warn(broken_intra_doc_links)]` on by default

If you uncomment the line as it says, the warning goes away.

Meta

rustc +stage2 --version --verbose:

rustc 1.49.0-dev
binary: rustc
commit-hash: unknown
commit-date: unknown
host: x86_64-unknown-linux-gnu
release: 1.49.0-dev

Commit hash: b202532

Here's a crate that repros this issue: https://github.com/pitaj/rustdoc-78006-repro

@rustbot modify labels: T-doc, A-intra-doc-links

@jyn514 Here's the repro I promised.

First came across this in #78006

@pitaj pitaj added the C-bug Category: This is a bug. label Nov 3, 2020
@rustbot rustbot added A-intra-doc-links Area: Intra-doc links, the ability to link to items in docs by name A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools labels Nov 3, 2020
@jyn514 jyn514 added T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. and removed A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools labels Nov 3, 2020
@jyn514
Copy link
Member

jyn514 commented Nov 3, 2020

Slightly smaller:

// Uncomment this and the warning will go away
// use crate::io::Read;

pub mod io {
    pub trait Read {
        fn read(&mut self);
    }
}

pub mod bufreader {
    //! [`crate::TcpStream::read`]
    use crate::io::Read;
}

pub struct TcpStream;

impl crate::io::Read for TcpStream {
    fn read(&mut self) {
    }
}

@jyn514
Copy link
Member

jyn514 commented Nov 3, 2020

The issue is that rustdoc thinks the trait isn't in scope for some reason:

2:rustcDEBUG rustdoc::passes::collect_intra_doc_links looking for associated item named read for item DefId(0:8 ~ impl[8787]::TcpStream)
2:rustcDEBUG rustdoc::passes::collect_intra_doc_links considering traits {}
2:rustcDEBUG rustdoc::passes::collect_intra_doc_links the candidates were []
2:rustcDEBUG rustdoc::passes::collect_intra_doc_links got associated item kind None
2:rustcDEBUG rustdoc::passes::collect_intra_doc_links self::TcpStream::read resolved to Err(()) in namespace ValueNS

@jyn514
Copy link
Member

jyn514 commented Nov 3, 2020

Because it's resolving the scope of the crate, because of the hack I did to fix crate:: across crates: #77253. If you use super::TcpStream::read instead, it works fine.

@jyn514 jyn514 added the E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. label Nov 3, 2020
@jyn514 jyn514 changed the title Rustdoc intra-doc links fail to resolve sibling-module associated trait impl functions in scope intra-doc links: crate:: considers the traits in the crate scope, not the current scope Nov 3, 2020
@jyn514
Copy link
Member

jyn514 commented Nov 3, 2020

@pitaj you could get #78006 working by using super instead for now.

@jyn514
Copy link
Member

jyn514 commented Nov 5, 2020

@petrochenkov how hard would it be to allow $crate in resolve_str_path_error? Rustdoc has both the original and current scope available, but right now it can only pass one or the other to resolve.

Using $crate would fix this issue and also some other hacks in rustdoc (see #77253).

@petrochenkov
Copy link
Contributor

resolve_str_path_error should already support $crate internally, but rustdoc passing path as a string (without span) will mean that $crate will always resolve to the current crate. Resolve needs correct spans to perform resolution in cases like this.

@jyn514
Copy link
Member

jyn514 commented Nov 5, 2020

Mentoring instructions: everywhere that currently calls resolve_str_path_error with DUMMY_SP needs to instead pass the span of the item. You can get the span from item.source. fn resolve needs to be changed to take the span as a parameter:

match self.resolve(path_str, ns, &current_item, base_node, &extra_fragment) {

There are many different calls to resolve_str_path_error and not all of them go through fn resolve; those will need to be updated as well.

Once you've passed the correct span, change the hack in

// HACK(jynelson): rustc_resolve thinks that `crate` is the crate currently being documented.
// But rustdoc wants it to mean the crate this item was originally present in.
// To work around this, remove it and resolve relative to the crate root instead.
// HACK(jynelson)(2): If we just strip `crate::` then suddenly primitives become ambiguous
// (consider `crate::char`). Instead, change it to `self::`. This works because 'self' is now the crate root.
resolved_self = format!("self::{}", &path_str["crate::".len()..]);
path_str = &resolved_self;
module_id = DefId { krate, index: CRATE_DEF_INDEX };

to instead replace crate:: with $crate::. Also remove the modification of module_id, which is what will actually fix #78696.

@petrochenkov
Copy link
Contributor

Fixed in #95337.

@bors bors closed this as completed in 949b98c Apr 5, 2022
lopopolo added a commit to artichoke/cactusref that referenced this issue Apr 7, 2022
saethlin added a commit to saethlin/rust that referenced this issue Feb 20, 2024
…rieb

Remove an old hack for rustdoc

Since rust-lang#78696 has been resolved
Noratrieb added a commit to Noratrieb/rust that referenced this issue Feb 20, 2024
…rieb

Remove an old hack for rustdoc

Since rust-lang#78696 has been resolved
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Feb 20, 2024
Rollup merge of rust-lang#121310 - GrigorenkoPV:doc-smallfix, r=Nilstrieb

Remove an old hack for rustdoc

Since rust-lang#78696 has been resolved
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 C-bug Category: This is a bug. E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
5 participants