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

[wg-async-await] Drop async fn arguments in async block #59135

Closed
wants to merge 7 commits into from

Conversation

davidtwco
Copy link
Member

Fixes #54716.

This PR modifies the HIR lowering (and some other places to make this work) so that unused arguments to a async function are always dropped inside the async move block and not at the end of the function body.

async fn foo(<pattern>: <type>) {
  async move {
  }
} // <-- dropped as you "exit" the fn

// ...becomes...
fn foo(__arg0: <ty>) {
  async move {
    let <pattern>: <ty> = __arg0;
  } // <-- dropped as you "exit" the async block
}

However, the exact ordering of drops is not the same as a regular function, as visible in this playground example - I believe this to be an unrelated issue. There is a Zulip topic for this.

r? @cramertj
cc @nikomatsakis

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 12, 2019
@davidtwco
Copy link
Member Author

I'm not completely happy with the way this works, but I couldn't work out anything better. Happy to make any changes or completely rethink the approach if preferred.

@rust-highfive

This comment has been minimized.

@rust-highfive

This comment has been minimized.

@rust-highfive

This comment has been minimized.

@bors

This comment has been minimized.

@rust-highfive

This comment has been minimized.

@davidtwco
Copy link
Member Author

There's a summary of the current state of this PR on Zulip.

@bors

This comment has been minimized.

@rust-highfive

This comment has been minimized.

src/test/run-pass/issue-54716.rs Show resolved Hide resolved
));
let _ = fut.as_mut().poll(&waker);
assert_eq!(*af.borrow(), &[
Function, Val("_y"), Val("_c"), Val("a"), Val("x"), Val("_"), Val("_"),
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe we should name these _1 etc?

Copy link
Member Author

Choose a reason for hiding this comment

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

I wanted to have the names here match the function arguments as I found that was easier to reason about when there was a failure. So, _1 could be used for the argument names, but I'd still need to use something non-numeric for the bindings that don't start with _ which would be inconsistent.

@bors

This comment has been minimized.

@rust-highfive

This comment has been minimized.

@bors

This comment has been minimized.

@rust-highfive

This comment has been minimized.

@bors

This comment has been minimized.

This tests that async functions drop parameters in the same order as
regular functions.
This will be used to keep track of the origin of a local in the AST. In
particular, it will be used by `async fn` lowering for the locals in
`let <pat>: <ty> = __arg0;` statements.
This commit adds an `AsyncArgument` struct to the AST that contains the
generated argument and statement that will be used in HIR lowering, name
resolution and def collection.
This commit takes advantage of `AsyncArgument` type that was added in a
previous commit to replace the arguments of the `async fn` in the HIR
and add statements to move the bindings from the new arguments to the
pattern from the old argument.

For example, the async function `foo` below:

    async fn foo((x, _y): (T, V)) {
        async move {
        }
    }

becomes:

    async fn foo(__arg0: (T, V)) {
        async move {
            let (x, _y) = __arg0;
        }
    }
This commit extends the previous commit to apply to trait methods as
well as free functions.
This avoids issues with `impl_trait_in_bindings` as the type from the
argument is normally used as the let binding, but `impl Trait` is
unstable in binding position.
This commit introduces an `ArgSource` enum that is lowered into the HIR
so that diagnostics can correctly refer to the argument pattern's
original name rather than the generated pattern.
@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:0b4850ec:start=1553464575008922127,finish=1553464577389884674,duration=2380962547
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
$ export GCP_CACHE_BUCKET=rust-lang-ci-cache
Setting environment variables from .travis.yml
---
Check compiletest suite=ui mode=ui (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[01:13:04] 
[01:13:04] running 5486 tests
[01:13:07] .................................................................................................... 100/5486
[01:13:10] ..................................F................................................................. 200/5486
[01:13:16] .................................................................................................... 400/5486
[01:13:20] .................................................................................................... 500/5486
[01:13:24] ..........................................i......................................................... 600/5486
[01:13:28] .................................................................................................... 700/5486
---
[01:16:31] ---- [ui] ui/async-fn-multiple-lifetimes.rs stdout ----
[01:16:31] diff of stderr:
[01:16:31] 
[01:16:31] 26    |
[01:16:31] 27    = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_` or `_`
[01:16:31] - error: aborting due to 3 previous errors
[01:16:31] + error[E0623]: lifetime mismatch
[01:16:31] +   --> $DIR/async-fn-multiple-lifetimes.rs:7:65
[01:16:31] +    |
[01:16:31] +    |
[01:16:31] + LL | async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}
[01:16:31] +    |                                                         ------  ^
[01:16:31] +    |                                                         |       ...but data is returned here
[01:16:31] +    |                                                         this parameter and the return type are declared with different lifetimes...
[01:16:31] 30 
[01:16:31] - Some errors occurred: E0106, E0707, E0709.
[01:16:31] - Some errors occurred: E0106, E0707, E0709.
[01:16:31] + error[E0309]: the parameter type `impl for<'b> Add<&'b u8>` may not live long enough
[01:16:31] +    |
[01:16:31] + LL | ) {}
[01:16:31] +    |   ^
[01:16:31] +    |
[01:16:31] +    |
[01:16:31] + note: ...so that the type `impl std::future::Future` will meet its required lifetime bounds
[01:16:31] +    |
[01:16:31] + LL | ) {}
[01:16:31] +    |   ^
[01:16:31] +    |   ^
[01:16:31] + help: consider adding an explicit lifetime bound  `'c` to `impl for<'b> Add<&'b u8>`...
[01:16:31] +    |
[01:16:31] + LL |     _: impl for<'b> Add<&'b u8> + 'c,
[01:16:31] + 
[01:16:31] + 
[01:16:31] + error[E0309]: the parameter type `impl for<'a> Add<&'a u8>` may not live long enough
[01:16:31] +    |
[01:16:31] + LL | ) {}
[01:16:31] +    |   ^
[01:16:31] +    |
[01:16:31] +    |
[01:16:31] + note: ...so that the type `impl std::future::Future` will meet its required lifetime bounds
[01:16:31] +    |
[01:16:31] + LL | ) {}
[01:16:31] +    |   ^
[01:16:31] +    |   ^
[01:16:31] + help: consider adding an explicit lifetime bound  `'c` to `impl for<'a> Add<&'a u8>`...
[01:16:31] +    |
[01:16:31] + LL |     _: impl for<'a> Add<&'a u8> + 'c,
[01:16:31] + 
[01:16:31] + error[E0621]: explicit lifetime required in parameter type
[01:16:31] +   --> $DIR/async-fn-multiple-lifetimes.rs:16:52
[01:16:31] +    |
[01:16:31] +    |
[01:16:31] + LL | async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}
[01:16:31] +    |                                               ---  ^ lifetime `'static` required
[01:16:31] +    |                                               help: add explicit lifetime `'static` to type: `&'static u8`
[01:16:31] + 
[01:16:31] + error[E0621]: explicit lifetime required in parameter type
[01:16:31] +   --> $DIR/async-fn-multiple-lifetimes.rs:16:52
[01:16:31] +   --> $DIR/async-fn-multiple-lifetimes.rs:16:52
[01:16:31] +    |
[01:16:31] + LL | async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}
[01:16:31] +    |                                       ---          ^ lifetime `'static` required
[01:16:31] +    |                                       help: add explicit lifetime `'static` to type: `&'static u8`
[01:16:31] + 
[01:16:31] + error: aborting due to 8 previous errors
[01:16:31] + 
[01:16:31] + 
[01:16:31] + Some errors occurred: E0106, E0309, E0621, E0623, E0707, E0709.
[01:16:31] 32 For more information about an error, try `rustc --explain E0106`.
[01:16:31] 33 
[01:16:31] 
[01:16:31] 
[01:16:31] The actual stderr differed from the expected stderr.
[01:16:31] Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/async-fn-multiple-lifetimes/async-fn-multiple-lifetimes.stderr
[01:16:31] To update references, rerun the tests and pass the `--bless` flag
[01:16:31] To only update this specific test, also pass `--test-args async-fn-multiple-lifetimes.rs`
[01:16:31] error: 1 errors occurred comparing output.
[01:16:31] status: exit code: 1
[01:16:31] status: exit code: 1
[01:16:31] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/async-fn-multiple-lifetimes.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/async-fn-multiple-lifetimes/a" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--edition=2018" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/async-fn-multiple-lifetimes/auxiliary" "-A" "unused"
[01:16:31] ------------------------------------------
[01:16:31] 
[01:16:31] ------------------------------------------
[01:16:31] stderr:
[01:16:31] stderr:
[01:16:31] ------------------------------------------
[01:16:31] {"message":"multiple different lifetimes used in arguments of `async fn`","code":{"code":"E0709","explanation":null},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":162,"byte_end":164,"line_start":7,"line_end":7,"column_start":47,"column_end":49,"is_primary":true,"text":[{"text":"async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}","highlight_start":47,"highlight_end":49}],"label":"first lifetime here","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":173,"byte_end":175,"line_start":7,"line_end":7,"column_start":58,"column_end":60,"is_primary":true,"text":[{"text":"async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}","highlight_start":58,"highlight_end":60}],"label":"different lifetime here","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`async fn` can only accept borrowed values with identical lifetimes","code":null,"level":"help","spans":[],"children":[],"rendered":null}],"rendered":"error[E0709]: multiple different lifetimes used in arguments of `async fn`\n  --> /checkout/src/test/ui/async-fn-multiple-lifetimes.rs:7:47\n   |\nLL | async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}\n   |                                               ^^         ^^ different lifetime here\n   |                                               |\n   |                                               first lifetime here\n   |\n   = help: `async fn` can only accept borrowed values with identical lifetimes\n\n"}
[01:16:31] {"message":"multiple elided lifetimes used in arguments of `async fn`","code":{"code":"E0707","explanation":null},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":438,"byte_end":439,"line_start":16,"line_end":16,"column_start":39,"column_end":40,"is_primary":true,"text":[{"text":"async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}","highlight_start":39,"highlight_end":40}],"label":"first lifetime here","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":446,"byte_end":447,"line_start":16,"line_end":16,"column_start":47,"column_end":48,"is_primary":true,"text":[{"text":"async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}","highlight_start":47,"highlight_end":48}],"label":"different lifetime here","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"consider giving these arguments named lifetimes","code":null,"level":"help","spans":[],"children":[],"rendered":null}],"rendered":"error[E0707]: multiple elided lifetimes used in arguments of `async fn`\n  --> /checkout/src/test/ui/async-fn-multiple-lifetimes.rs:16:39\n   |\nLL | async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}\n   |                                       ^       ^ different lifetime here\n   |                                       |\n   |                                       first lifetime here\n   |\n   = help: consider giving these arguments named lifetimes\n\n"}
[01:16:31] {"message":"missing lifetime specifier","code":{"code":"E0106","explanation":"\nThis error indicates that a lifetime is missing from a type. If it is an error\ninside a function signature, the problem may be with failing to adhere to the\nlifetime elision rules (see below).\n\nHere are some simple examples of where you'll run into this error:\n\n```compile_fail,E0106\nstruct Foo1 { x: &bool }\n              // ^ expected lifetime parameter\nstruct Foo2<'a> { x: &'a bool } // correct\n\nimpl Foo2 {}\n  // ^^^^ expected lifetime parameter\nimpl<'a> Foo2<'a> {} // correct\n\nstruct Bar1 { x: Foo2 }\n              // ^^^^ expected lifetime parameter\nstruct Bar2<'a> { x: Foo2<'a> } // correct\n\nenum Baz1 { A(u8), B(&bool), }\n                  // ^ expected lifetime parameter\nenum Baz2<'a> { A(u8), B(&'a bool), } // correct\n\ntype MyStr1 = &str;\n           // ^ expected lifetime parameter\ntype MyStr2<'a> = &'a str; // correct\n```\n\nLifetime elision is a special, limited kind of inference for lifetimes in\nfunction signatures which allows you to leave out lifetimes in certain cases.\nFor more background on lifetime elision see [the book][book-le].\n\nThe lifetime elision rules require that any function signature with an elided\noutput lifetime must either have\n\n - exactly one input lifetime\n - or, multiple input lifetimes, but the function must also be a method with a\n   `&self` or `&mut self` receiver\n\nIn the first case, the output lifetime is inferred to be the same as the unique\ninput lifetime. In the second case, the lifetime is instead inferred to be the\nsame as the lifetime on `&self` or `&mut self`.\n\nHere are some examples of elision errors:\n\n```compile_fail,E0106\n// error, no input lifetimes\nfn foo() -> &str { }\n\n// error, `x` and `y` have distinct lifetimes inferred\nfn bar(x: &str, y: &str) -> &str { }\n\n// error, `y`'s lifetime is inferred to be distinct from `x`'s\nfn baz<'a>(x: &'a str, y: &str) -> &str { }\n```\n\n[book-le]: https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#lifetime-elision\n"},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":438,"byte_end":439,"line_start":16,"line_end":16,"column_start":39,"column_end":40,"is_primary":true,"text":[{"text":"async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}","highlight_start":39,"highlight_end":40}],"label":"expected lifetime parameter","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_` or `_`","code":null,"level":"help","spans":[],"children":[],"rendered":null}],"rendered":"error[E0106]: missing lifetime specifier\n  --> /checkout/src/test/ui/async-fn-multiple-lifetimes.rs:16:39\n   |\nLL | async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}\n   |                                       ^ expected lifetime parameter\n   |\n   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_` or `_`\n\n"}
[01:16:31] {"message":"lifetime mismatch","code":{"code":"E0623","explanation":null},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":172,"byte_end":178,"line_start":7,"line_end":7,"column_start":57,"column_end":63,"is_primary":false,"text":[{"text":"async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}","highlight_start":57,"highlight_end":63}],"label":"this parameter and the return type are declared with different lifetimes...","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":180,"byte_end":180,"line_start":7,"line_end":7,"column_start":65,"column_end":65,"is_primary":false,"text":[{"text":"async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}","highlight_start":65,"highlight_end":65}],"label":"","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":180,"byte_end":180,"line_start":7,"line_end":7,"column_start":65,"column_end":65,"is_primary":true,"text":[{"text":"async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}","highlight_start":65,"highlight_end":65}],"label":"...but data is returned here","suggested_replacement":null,"suggestion_applicability":null,"expansion":{"span":{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":180,"byte_end":180,"line_start":7,"line_end":7,"column_start":65,"column_end":65,"is_primary":false,"text":[{"text":"async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}","highlight_start":65,"highlight_end":65}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},"macro_decl_name":"desugaring of `existential type`","def_site_span":{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":180,"byte_end":180,"line_start":7,"line_end":7,"column_start":65,"column_end":65,"is_primary":false,"text":[{"text":"async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}","highlight_start":65,"highlight_end":65}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}}}],"children":[],"rendered":"error[E0623]: lifetime mismatch\n  --> /checkout/src/test/ui/async-fn-multiple-lifetimes.rs:7:65\n   |\nLL | async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}\n   |                                                         ------  ^\n   |                                                         |       |\n   |                                                         |       ...but data is returned here\n   |                                                         this parameter and the return type are declared with different lifetimes...\n\n"}
[01:16:31] {"message":"the parameter type `impl for<'b> Add<&'b u8>` may not live long enough","code":{"code":"E0309","explanation":"\nThe type definition contains some field whose type\nrequires an outlives annotation. Outlives annotations\n(e.g., `T: 'a`) are used to guarantee that all the data in T is valid\nfor at least the lifetime `'a`. This scenario most commonly\narises when the type contains an associated type reference\nlike `<T as SomeTrait<'a>>::Output`, as shown in this example:\n\n```compile_fail,E0309\n// This won't compile because the applicable impl of\n// `SomeTrait` (below) requires that `T: 'a`, but the struct does\n// not have a matching where-clause.\nstruct Foo<'a, T> {\n    foo: <T as SomeTrait<'a>>::Output,\n}\n\ntrait SomeTrait<'a> {\n    type Output;\n}\n\nimpl<'a, T> SomeTrait<'a> for T\nwhere\n    T: 'a,\n{\n    type Output = u32;\n}\n```\n\nHere, the where clause `T: 'a` that appears on the impl is not known to be\nsatisfied on the struct. To make this example compile, you have to add\na where-clause like `T: 'a` to the struct definition:\n\n```\nstruct Foo<'a, T>\nwhere\n    T: 'a,\n{\n    foo: <T as SomeTrait<'a>>::Output\n}\n\ntrait SomeTrait<'a> {\n    type Output;\n}\n\nimpl<'a, T> SomeTrait<'a> for T\nwhere\n    T: 'a,\n{\n    type Output = u32;\n}\n```\n"},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":396,"byte_end":396,"line_start":14,"line_end":14,"column_start":3,"column_end":3,"is_primary":true,"text":[{"text":") {}","highlight_start":3,"highlight_end":3}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":{"span":{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":396,"byte_end":396,"line_start":14,"line_end":14,"column_start":3,"column_end":3,"is_primary":false,"text":[{"text":") {}","highlight_start":3,"highlight_end":3}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},"macro_decl_name":"desugaring of `existential type`","def_site_span":{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":396,"byte_end":396,"line_start":14,"line_end":14,"column_start":3,"column_end":3,"is_primary":false,"text":[{"text":") {}","highlight_start":3,"highlight_end":3}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}}}],"children":[{"message":"...so that the type `impl std::future::Future` will meet its required lifetime bounds","code":null,"level":"note","spans":[{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":396,"byte_end":396,"line_start":14,"line_end":14,"column_start":3,"column_end":3,"is_primary":true,"text":[{"text":") {}","highlight_start":3,"highlight_end":3}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":{"span":{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":396,"byte_end":396,"line_start":14,"line_end":14,"column_start":3,"column_end":3,"is_primary":false,"text":[{"text":") {}","highlight_start":3,"highlight_end":3}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},"macro_decl_name":"desugaring of `existential type`","def_site_span":{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":396,"byte_end":396,"line_start":14,"line_end":14,"column_start":3,"column_end":3,"is_primary":false,"text":[{"text":") {}","highlight_start":3,"highlight_end":3}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}}}],"children":[],"rendered":null},{"message":"consider adding an explicit lifetime bound  `'c` to `impl for<'b> Add<&'b u8>`...","code":null,"level":"help","spans":[{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":353,"byte_end":377,"line_start":12,"line_end":12,"column_start":8,"column_end":32,"is_primary":true,"text":[{"text":"    _: impl for<'b> Add<&'b u8>,","highlight_start":8,"highlight_end":32}],"label":null,"suggested_replacement":"impl for<'b> Add<&'b u8> + 'c","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"error[E0309]: the parameter type `impl for<'b> Add<&'b u8>` may not live long enough\n  --> /checkout/src/test/ui/async-fn-multiple-lifetimes.rs:14:3\n   |\nLL | ) {}\n   |   ^\n   |\nnote: ...so that the type `impl std::future::Future` will meet its required lifetime bounds\n  --> /checkout/src/test/ui/async-fn-multiple-lifetimes.rs:14:3\n   |\nLL | ) {}\n   |   ^\nhelp: consider adding an explicit lifetime bound  `'c` to `impl for<'b> Add<&'b u8>`...\n   |\nLL |     _: impl for<'b> Add<&'b u8> + 'c,\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n"}
[01:16:31] {"message":"the parameter type `impl for<'a> Add<&'a u8>` may not live long enough","code":{"code":"E0309","explanation":"\nThe type definition contains some field whose type\nrequires an outlives annotation. Outlives annotations\n(e.g., `T: 'a`) are used to guarantee that all the data in T is valid\nfor at least the lifetime `'a`. This scenario most commonly\narises when the type contains an associated type reference\nlike `<T as SomeTrait<'a>>::Output`, as shown in this example:\n\n```compile_fail,E0309\n// This won't compile because the applicable impl of\n// `SomeTrait` (below) requires that `T: 'a`, but the struct does\n// not have a matching where-clause.\nstruct Foo<'a, T> {\n    foo: <T as SomeTrait<'a>>::Output,\n}\n\ntrait SomeTrait<'a> {\n    type Output;\n}\n\nimpl<'a, T> SomeTrait<'a> for T\nwhere\n    T: 'a,\n{\n    type Output = u32;\n}\n```\n\nHere, the where clause `T: 'a` that appears on the impl is not known to be\nsatisfied on the struct. To make this example compile, you have to add\na where-clause like `T: 'a` to the struct definition:\n\n```\nstruct Foo<'a, T>\nwhere\n    T: 'a,\n{\n    foo: <T as SomeTrait<'a>>::Output\n}\n\ntrait SomeTrait<'a> {\n    type Output;\n}\n\nimpl<'a, T> SomeTrait<'a> for T\nwhere\n    T: 'a,\n{\n    type Output = u32;\n}\n```\n"},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":396,"byte_end":396,"line_start":14,"line_end":14,"column_start":3,"column_end":3,"is_primary":true,"text":[{"text":") {}","highlight_start":3,"highlight_end":3}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":{"span":{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":396,"byte_end":396,"line_start":14,"line_end":14,"column_start":3,"column_end":3,"is_primary":false,"text":[{"text":") {}","highlight_start":3,"highlight_end":3}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},"macro_decl_name":"desugaring of `existential type`","def_site_span":{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":396,"byte_end":396,"line_start":14,"line_end":14,"column_start":3,"column_end":3,"is_primary":false,"text":[{"text":") {}","highlight_start":3,"highlight_end":3}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}}}],"children":[{"message":"...so that the type `impl std::future::Future` will meet its required lifetime bounds","code":null,"level":"note","spans":[{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":396,"byte_end":396,"line_start":14,"line_end":14,"column_start":3,"column_end":3,"is_primary":true,"text":[{"text":") {}","highlight_start":3,"highlight_end":3}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":{"span":{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":396,"byte_end":396,"line_start":14,"line_end":14,"column_start":3,"column_end":3,"is_primary":false,"text":[{"text":") {}","highlight_start":3,"highlight_end":3}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},"macro_decl_name":"desugaring of `existential type`","def_site_span":{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":396,"byte_end":396,"line_start":14,"line_end":14,"column_start":3,"column_end":3,"is_primary":false,"text":[{"text":") {}","highlight_start":3,"highlight_end":3}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}}}],"children":[],"rendered":null},{"message":"consider adding an explicit lifetime bound  `'c` to `impl for<'a> Add<&'a u8>`...","code":null,"level":"help","spans":[{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":320,"byte_end":344,"line_start":11,"line_end":11,"column_start":8,"column_end":32,"is_primary":true,"text":[{"text":"    _: impl for<'a> Add<&'a u8>,","highlight_start":8,"highlight_end":32}],"label":null,"suggested_replacement":"impl for<'a> Add<&'a u8> + 'c","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"error[E0309]: the parameter type `impl for<'a> Add<&'a u8>` may not live long enough\n  --> /checkout/src/test/ui/async-fn-multiple-lifetimes.rs:14:3\n   |\nLL | ) {}\n   |   ^\n   |\nnote: ...so that the type `impl std::future::Future` will meet its required lifetime bounds\n  --> /checkout/src/test/ui/async-fn-multiple-lifetimes.rs:14:3\n   |\nLL | ) {}\n   |   ^\nhelp: consider adding an explicit lifetime bound  `'c` to `impl for<'a> Add<&'a u8>`...\n   |\nLL |     _: impl for<'a> Add<&'a u8> + 'c,\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n"}
[01:16:31] {"message":"explicit lifetime required in parameter type","code":{"code":"E0621","explanation":"\nThis error code indicates a mismatch between the lifetimes appearing in the\nfunction signature (i.e., the parameter types and the return type) and the\ndata-flow found in the function body.\n\nErroneous code example:\n\n```compile_fail,E0621\nfn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { // error: explicit lifetime\n                                             //        required in the type of\n                                             //        `y`\n    if x > y { x } else { y }\n}\n```\n\nIn the code above, the function is returning data borrowed from either `x` or\n`y`, but the `'a` annotation indicates that it is returning data only from `x`.\nTo fix the error, the signature and the body must be made to match. Typically,\nthis is done by updating the function signature. So, in this case, we change\nthe type of `y` to `&'a i32`, like so:\n\n```\nfn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {\n    if x > y { x } else { y }\n}\n```\n\nNow the signature indicates that the function data borrowed from either `x` or\n`y`. Alternatively, you could change the body to not return data from `y`:\n\n```\nfn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 {\n    x\n}\n```\n"},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":451,"byte_end":451,"line_start":16,"line_end":16,"column_start":52,"column_end":52,"is_primary":true,"text":[{"text":"async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}","highlight_start":52,"highlight_end":52}],"label":"lifetime `'static` required","suggested_replacement":null,"suggestion_applicability":null,"expansion":{"span":{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":451,"byte_end":451,"line_start":16,"line_end":16,"column_start":52,"column_end":52,"is_primary":false,"text":[{"text":"async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}","highlight_start":52,"highlight_end":52}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},"macro_decl_name":"desugaring of `existential type`","def_site_span":{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":451,"byte_end":451,"line_start":16,"line_end":16,"column_start":52,"column_end":52,"is_primary":false,"text":[{"text":"async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}","highlight_start":52,"highlight_end":52}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}}}],"children":[{"message":"add explicit lifetime `'static` to type","code":null,"level":"help","spans":[{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":446,"byte_end":449,"line_start":16,"line_end":16,"column_start":47,"column_end":50,"is_primary":true,"text":[{"text":"async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}","highlight_start":47,"highlight_end":50}],"label":null,"suggested_replacement":"&'static u8","suggestion_applicability":"Unspecified","expansion":null}],"children":[],"rendered":null}],"rendered":"error[E0621]: explicit lifetime required in parameter type\n  --> /checkout/src/test/ui/async-fn-multiple-lifetimes.rs:16:52\n   |\nLL | async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}\n   |                                               ---  ^ lifetime `'static` required\n   |                                               |\n   |                                               help: add explicit lifetime `'static` to type: `&'static u8`\n\n"}
[01:16:31] {"message":"explicit lifetime required in parameter type","code":{"code":"E0621","explanation":"\nThis error code indicates a mismatch between the lifetimes appearing in the\nfunction signature (i.e., the parameter types and the return type) and the\ndata-flow found in the function body.\n\nErroneous code example:\n\n```compile_fail,E0621\nfn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { // error: explicit lifetime\n                                             //        required in the type of\n                                             //        `y`\n    if x > y { x } else { y }\n}\n```\n\nIn the code above, the function is returning data borrowed from either `x` or\n`y`, but the `'a` annotation indicates that it is returning data only from `x`.\nTo fix the error, the signature and the body must be made to match. Typically,\nthis is done by updating the function signature. So, in this case, we change\nthe type of `y` to `&'a i32`, like so:\n\n```\nfn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {\n    if x > y { x } else { y }\n}\n```\n\nNow the signature indicates that the function data borrowed from either `x` or\n`y`. Alternatively, you could change the body to not return data from `y`:\n\n```\nfn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 {\n    x\n}\n```\n"},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":451,"byte_end":451,"line_start":16,"line_end":16,"column_start":52,"column_end":52,"is_primary":true,"text":[{"text":"async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}","highlight_start":52,"highlight_end":52}],"label":"lifetime `'static` required","suggested_replacement":null,"suggestion_applicability":null,"expansion":{"span":{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":451,"byte_end":451,"line_start":16,"line_end":16,"column_start":52,"column_end":52,"is_primary":false,"text":[{"text":"async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}","highlight_start":52,"highlight_end":52}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},"macro_decl_name":"desugaring of `existential type`","def_site_span":{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":451,"byte_end":451,"line_start":16,"line_end":16,"column_start":52,"column_end":52,"is_primary":false,"text":[{"text":"async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}","highlight_start":52,"highlight_end":52}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}}}],"children":[{"message":"add explicit lifetime `'static` to type","code":null,"level":"help","spans":[{"file_name":"/checkout/src/test/ui/async-fn-multiple-lifetimes.rs","byte_start":438,"byte_end":441,"line_start":16,"line_end":16,"column_start":39,"column_end":42,"is_primary":true,"text":[{"text":"async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}","highlight_start":39,"highlight_end":42}],"label":null,"suggested_replacement":"&'static u8","suggestion_applicability":"Unspecified","expansion":null}],"children":[],"rendered":null}],"rendered":"error[E0621]: explicit lifetime required in parameter type\n  --> /checkout/src/test/ui/async-fn-multiple-lifetimes.rs:16:52\n   |\nLL | async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}\n   |                                       ---          ^ lifetime `'static` required\n   |                                       |\n   |                                       help: add explicit lifetime `'static` to type: `&'static u8`\n\n"}
[01:16:31] {"message":"aborting due to 8 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 8 previous errors\n\n"}
[01:16:31] {"message":"Some errors occurred: E0106, E0309, E0621, E0623, E0707, E0709.","code":null,"level":"","spans":[],"children":[],"rendered":"Some errors occurred: E0106, E0309, E0621, E0623, E0707, E0709.\n"}
[01:16:31] 
[01:16:31] ------------------------------------------
[01:16:31] 
[01:16:31] thread '[ui] ui/async-fn-multiple-lifetimes.rs' panicked at 'explicit panic', src/tools/compiletest/src/runtest.rs:3369:9
---
[01:16:31] 
[01:16:31] thread 'main' panicked at 'Some tests failed', src/tools/compiletest/src/main.rs:496:22
[01:16:31] 
[01:16:31] 
[01:16:31] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/ui" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "ui" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-6.0/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--target-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "6.0.0\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
[01:16:31] 
[01:16:31] 
[01:16:31] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:16:31] Build completed unsuccessfully in 0:04:28
[01:16:31] Build completed unsuccessfully in 0:04:28
[01:16:31] make: *** [check] Error 1
[01:16:31] Makefile:48: recipe for target 'check' failed
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:12027940
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Sun Mar 24 23:12:59 UTC 2019
---
travis_time:end:0306bfa0:start=1553469180930509126,finish=1553469180938310801,duration=7801675
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:0fdb9070
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:119adb05
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@Centril Centril 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 30, 2019
@Centril
Copy link
Contributor

Centril commented Mar 30, 2019

Ping from triage, @davidtwco, you have some test failures.

@davidtwco
Copy link
Member Author

Thanks @Centril, I noticed, this PR is currently waiting on some feedback from wg-async-await about the approach and some pointers on fixing the current test failures.

@davidtwco
Copy link
Member Author

Closing this until there is bandwidth to review.

@davidtwco davidtwco closed this Apr 2, 2019
@davidtwco
Copy link
Member Author

Re-opening as #59823 after wg-async-await weekly meeting - apparently you can't re-open PRs that you've force-pushed too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants