Skip to content

async move breaks doc tests #59313

Description

Steps to reproduce:

  1. Create a library project with the following contents in lib.rs:
//! ```
//! #![feature(async_await)]
//!
//! fn foo() {
//!     drop(async move {});
//! }
//! ```
  1. Run tests:
repro master $ cargo --version
cargo 1.35.0-nightly (0e35bd8af 2019-03-13)
repro master $ rustc --version
rustc 1.35.0-nightly (3eb4890df 2019-03-19)
repro master $ cargo test
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running target/debug/deps/repro-0e401502cf52c662

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

   Doc-tests repro

running 1 test
test src/lib.rs -  (line 1) ... FAILED

failures:

failures:
    src/lib.rs -  (line 1)

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

error: test failed, to rerun pass '--doc'
  1. Now delete the move inside async move {}:
//! ```
//! #![feature(async_await)]
//!
//! fn foo() {
//!     drop(async {});
//! }
//! ```
  1. Run tests again:
repro master $ cargo test
   Compiling repro v0.1.0 (/home/stjepan/work/repro)
    Finished dev [unoptimized + debuginfo] target(s) in 0.25s
     Running target/debug/deps/repro-0e401502cf52c662

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

   Doc-tests repro

running 1 test
test src/lib.rs -  (line 1) ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

Activity

  1. added
    T-rustdocRelevant to the rustdoc team, which will review and decide on the PR/issue.
    C-bugCategory: This is a bug.
    A-doctestsArea: Documentation tests, run by rustdoc
    on Mar 20, 2019
  2. nikomatsakis commented on Apr 16, 2019

    @nikomatsakis
    Contributor

    This seems to work outside of rustdoc

  3. nikomatsakis commented on Apr 16, 2019

    @nikomatsakis
    Contributor

    Marking as blocking for async await stabilization pending some investigation.

    cc @rust-lang/rustdoc -- can you all give any tips to try and gain insight into what error is occurring etc?

  4. GuillaumeGomez commented on Apr 17, 2019

    @GuillaumeGomez
    Member

    Can you give a try to:

    //! #![feature(async_await)]
    //!
    //! # fn main() {
    //! fn foo() {
    //!     drop(async move {});
    //! }
    //! # foo();
    //! # }
    

    But beyond that, I'm wondering if it isn't just a missing flag or something along the line?

    Maybe you have other ideas @QuietMisdreavus ?

  5. QuietMisdreavus commented on Apr 17, 2019

    @QuietMisdreavus
    Contributor

    I spent some time yesterday poking at this, and it seems like it's failing somewhere in the pre-parsing of the doctest. Some time around the part where it parses the move keyword, it just... dies. I'm having trouble pinning down exactly where (and how) it fails, since it's not panicking, and setting -Z treat-err-as-bug (which i have to modify the code to do since we usually don't pass that into doctests) makes it fail at an earlier spot.

  6. nikomatsakis commented on Apr 17, 2019

    @nikomatsakis
    Contributor

    I've sometimes seen problems around FatalError.raise()

  7. QuietMisdreavus commented on Apr 17, 2019

    @QuietMisdreavus
    Contributor

    Funny you should say that... It looks like one of those is being hit when processing this sample:

    } else if self.last_unexpected_token_span == Some(self.span) {
    FatalError.raise();

    It doesn't seem to hit this when compiling regularly, though.

  8. QuietMisdreavus commented on Apr 17, 2019

    @QuietMisdreavus
    Contributor

    I think i've figured it out. The "pre-parse" step of doctest execution runs the parser separately from the later execution of it. In this run, the "default edition" is never set, so libsyntax assumes everything is being run under Rust 2015. This causes it to fail when parsing the async move block. What's confusing is how this has never been a problem until now... 🤔

  9. QuietMisdreavus commented on Apr 18, 2019

    @QuietMisdreavus
    Contributor

    I've got a PR posted that should fix this: #60065

  10. Nemo157 commented on Apr 18, 2019

    @Nemo157
    Contributor

    Hmm, I was going to suggest that might be the issue, but I tried a test containing async { let foo = 5; } (which fails to compile on edition 2015) and that works fine (unsurprisingly since futures use a lot of doc-tests containing something similar).

  11. QuietMisdreavus commented on Apr 18, 2019

    @QuietMisdreavus
    Contributor

    Plain async blocks probably pass in the current nightly because they fail after the initial parse, or perhaps they bubble up a single error from parse_item instead of emitting it directly, which causes rustdoc to stop parsing and continue creating the doctest. The difference with async move blocks is that they use a keyword that exists in 2015, which causes it to attempt parsing a closure (instead of a struct expression), so it totally fails to parse instead of just creating a real expression that would fail a later check.

  12. added a commit that references this issue on May 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitA-doctestsArea: Documentation tests, run by rustdocAsyncAwait-PolishAsync-await issues that are part of the "polish" areaC-bugCategory: This is a bug.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