Skip to content

async-std docs no longer build on recent nightlies #75100

Closed

Description

@yoshuawuyts

Original issue surfaced in: async-rs/async-std#845 by @dignifiedquire. It appears that sometime after 2020-05-01 nightlies are no longer able to build async-std docs. #73566 appears to be a likely cause for this regression.

We use a fairly elaborate macro to generate docs, so we're not particularly surprised that a big refactor may have caused issues there. But it'd still be nice if we could get it to work again.

Error

The error message is fairly long and probably not worth posting in full. Luckily it does not appear to be an ICE, just a regression. This is the build that fails: link.

Activity

  1. added
    T-rustdocRelevant to the rustdoc team, which will review and decide on the PR/issue.
    on Aug 3, 2020
  2. jyn514 commented on Aug 3, 2020

    @jyn514
    Member

    The errors are the same ones as for #43348. They show up for async-std because all their functions are async, so rustdoc tries to infer the return type by type-checking the body. This didn't happen before #73566 because rustdoc didn't consider async fn to return an impl Trait.

    #73566 (comment)

  3. added
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Aug 3, 2020
  4. jyn514 commented on Aug 3, 2020

    @jyn514
    Member

    Copy/pasting from the PR:

    There's not a good way to fix this. We could revert, but then we lose the fixes to intra-doc links and they'd be permanently unstable again.

    Maybe we could have a reachability pass for rustdoc that's separate from the one for rustc? #73566 (comment) That's going to require a lot of work though, it's not a quick fix. And I don't know if it would actually do what I want.

  5. lcnr commented on Aug 3, 2020

    @lcnr
    Contributor

    So a minimal repro for this would be something like the following?

    #[cfg(any(windows, doc))]
    fn this() -> u32 {
        3
    }
    
    #[cfg(any(unix, doc))]
    fn this() -> u32 {
        4
    }
    
    pub async fn wow() -> u32 {
        this()
    }
  6. jyn514 commented on Aug 3, 2020

    @jyn514
    Member

    No, that's not right - that errors on the function signatures, not the function bodies:

    error[E0428]: the name `this` is defined multiple times
     --> type_error.rs:7:1
      |
    2 | fn this() -> u32 {
      | ---------------- previous definition of the value `this` here
    ...
    7 | fn this() -> u32 {
      | ^^^^^^^^^^^^^^^^ `this` redefined here
      |
      = note: `this` must be defined only once in the value namespace of this module
    

    This error is because rustdoc is type checking the function bodies.

  7. jyn514 commented on Aug 3, 2020

    @jyn514
    Member

    A minimal repro is

    pub async fn f() {
        content::should::not::matter();
    }
    error[E0433]: failed to resolve: could not resolve path `content::should::not::matter`
     --> body_error.rs:2:5
      |
    2 |     content::should::not::matter();
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ could not resolve path `content::should::not::matter`
      |
      = note: this error was originally ignored because you are running `rustdoc`
      = note: try running again with `rustc` or `cargo check` and you may get a more detailed error
  8. lcnr commented on Aug 3, 2020

    @lcnr
    Contributor

    Ah, and a more realistic example would probably be:

    mod windows {
        pub trait WinFoo {
            fn foo(&self) {}
        }
    
        impl WinFoo for () {}
    }
    
    #[cfg(any(windows, doc))]
    use windows::*;
    
    mod unix {
        pub trait UnixFoo {
            fn foo(&self) {}
        }
    
        impl UnixFoo for () {}
    }
    
    #[cfg(any(unix, doc))]
    use unix::*;
    
    async fn bar() {
        ().foo()
    }

    Thanks ❤️

  9. jyn514 commented on Aug 3, 2020

    @jyn514
    Member

    I'm more in favor of writing a specific pass rather than reverting this, too much benefits came from it and we're getting so close to have the intra-doc links stable! (I'm really excited about this feature!)

    @GuillaumeGomez I'm not sure why

    hir::ItemKind::OpaqueTy(..) => {
    // FIXME: This is some serious pessimization intended to workaround deficiencies
    // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
    // reachable if they are returned via `impl Trait`, even from private functions.
    let exist_level = cmp::max(item_level, Some(AccessLevel::ReachableFromImplTrait));
    self.reach(item.hir_id, exist_level).generics().predicates().ty();
    }
    is there currently so I'm afraid to change it. Maybe this is a hack for some specific call of privacy_access_levels and we can fix it for privacy_access_levels generally and only pessimize that call?

  10. GuillaumeGomez commented on Aug 3, 2020

    @GuillaumeGomez
    Member

    I think it might be interesting to ask the compiler team before doing anything in here. They might have a solution we didn't think about. :)

  11. jyn514 commented on Aug 3, 2020

    @jyn514
    Member

    Ping @rust-lang/compiler - does anyone know why OpaqueTy is special-cased in rustc_privacy? It causes rustdoc to try and type-check function bodies for fn f() -> impl Trait. Backtrace at #73566 (comment).

    The following patch does not fix it, but that might just be because I'm not understanding EmbargoVisitor:

    diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
    index fc00050f405..5855b48c01d 100644
    --- a/src/librustc_privacy/lib.rs
    +++ b/src/librustc_privacy/lib.rs
    @@ -782,8 +782,8 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
                     // FIXME: This is some serious pessimization intended to workaround deficiencies
                     // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
                     // reachable if they are returned via `impl Trait`, even from private functions.
    -                let exist_level = cmp::max(item_level, Some(AccessLevel::ReachableFromImplTrait));
    -                self.reach(item.hir_id, exist_level).generics().predicates().ty();
    +                //let exist_level = cmp::max(item_level, Some(AccessLevel::ReachableFromImplTrait));
    +                self.reach(item.hir_id, item_level).generics().predicates().ty();
                 }
                 // Visit everything.
                 hir::ItemKind::Const(..)

    edit since this is the comment with the ping: there are even more issues than this, see #75100 (comment)

  12. Manishearth commented on Aug 3, 2020

    @Manishearth
    Member

    Worth remembering: rustdoc does not care one bit about what the actual type of an impl Trait is, aside from the trait itself, which should already be known since that's explicitly specified (via trait or via the async keyword). So it should theoretically be possible to make this work without solving item bodies.

  13. Nemo157 commented on Aug 3, 2020

    @Nemo157
    Contributor

    (Though it might be nice if rustdoc indicated leaked auto-traits, which would require knowing the concrete type).

  14. 38 remaining items

  15. yoshuawuyts commented on Aug 12, 2020

    @yoshuawuyts
    MemberAuthor

    @jyn514 just built async-std locally with the latest nightly, and it seems to work! -- thanks so much!

  16. changed the title [-]async-std docs no longer build on recent nightlies[/-] [+]Fix rustdoc hack allowing async-std docs to build[/+] on Aug 25, 2020
  17. added
    C-cleanupCategory: PRs that clean code up or issues documenting cleanup.
    and removed
    C-bugCategory: This is a bug.
    on Aug 27, 2020
  18. added and removed on Sep 6, 2020
  19. jyn514 commented on Jun 4, 2021

    @jyn514
    Member

    I'm going to close this, no one has a suggested any alternative approach and people are continuing to add if ! actually_rustdoc to the codebase.

  20. changed the title [-]Fix rustdoc hack allowing async-std docs to build[/-] [+]`async-std` docs no longer build on recent nightlies[/+] on Apr 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

C-cleanupCategory: PRs that clean code up or issues documenting cleanup.P-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-rustdocRelevant to the rustdoc team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions