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

Combine generic parameters from impl block and method #1

Closed
dtolnay opened this issue Jul 23, 2019 · 2 comments · Fixed by #5
Closed

Combine generic parameters from impl block and method #1

dtolnay opened this issue Jul 23, 2019 · 2 comments · Fixed by #5
Labels
bug Something isn't working

Comments

@dtolnay
Copy link
Owner

dtolnay commented Jul 23, 2019

#![feature(async_await)]

use async_trait::async_trait;

#[async_trait]
trait Trait {
    async fn f<U>(&self);
}

#[async_trait]
impl<T> Trait for Vec<T> {
    async fn f<U>(&self) {}
}

Currently this fails to compile because the nested freestanding async fn we generate is missing the T type parameter:

error[E0401]: can't use generic parameters from outer function
  --> src/main.rs:11:23
   |
7  |     async fn f<U>(&self);
   |              - try adding a local generic parameter in this method instead
...
11 | impl<T> Trait for Vec<T> {
   |      -                ^ use of generic parameter from outer function
   |      |
   |      type parameter from outer function

Expanded code:

impl<T> Trait for Vec<T> {
    fn f<'life0, 'async_trait, U>(
        &'life0 self,
    ) -> std::pin::Pin<
        std::boxed::Box<dyn std::future::Future<Output = ()> + std::marker::Send + 'async_trait>,
    >
    where
        U: 'async_trait,
        'life0: 'async_trait,
        Self: 'async_trait,
    {
        async fn __f<'async_trait, U>(_self: &Vec<T>) {}
        std::pin::Pin::from(std::boxed::Box::new(__f::<U>(self)))
    }
}

We need to merge the syn::Generics from the impl block with the syn::Generics on the method to produce the generics that go on the inner function. In this case it should be:

        async fn __f<'async_trait, T, U>(_self: &Vec<T>) {}
@dtolnay dtolnay added the bug Something isn't working label Jul 23, 2019
@withoutboats
Copy link

why dont you use an async move block?

@dtolnay
Copy link
Owner Author

dtolnay commented Jul 24, 2019

@withoutboats for working code it would be fine and the implementation is simpler, but during development the error messages would be worse using async move. For example:

type Elided<'a> = &'a usize;

#[async_trait]
trait Trait {
    async fn f(elided: Elided) {
        println!("{}", *elided);
    }
}

Here is the error when using async move (#3). It only mentions 'static which is probably not the right fix in context.

error[E0621]: explicit lifetime required in the type of `elided`
 --> tests/dev.rs:7:1
  |
7 | #[async_trait]
  | ^^^^^^^^^^^^^^ lifetime `'static` required
8 | trait Trait {
9 |     async fn f(elided: Elided) {
  |                        ------ help: add explicit lifetime `'static` to the type of `elided`: `&'static usize`

Here is the error in the current implementation. Together with the elided lifetimes note in the readme, this should quickly get the author on the right track.

error[E0726]: implicit elided lifetime not allowed here
 --> tests/dev.rs:9:24
  |
9 |     async fn f(elided: Elided) {
  |                        ^^^^^^- help: indicate the anonymous lifetime: `<'_>`

error[E0621]: explicit lifetime required in the type of `elided`
 --> tests/dev.rs:9:16
  |
9 |     async fn f(elided: Elided) {
  |                ^^^^^^  ------ help: add explicit lifetime `'static` to the type of `elided`: `&'static usize`
  |                |
  |                lifetime `'static` required

dtolnay added a commit that referenced this issue Jul 2, 2022
    error: internal compiler error: compiler/rustc_typeck/src/collect.rs:1896:13: to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`

    thread 'rustc' panicked at 'Box<dyn Any>', /rustc/46b8c23f3eb5e4d0e0aa27eb3f20d5b8fc3ed51f/compiler/rustc_errors/src/lib.rs:1391:9
    stack backtrace:
       0: std::panicking::begin_panic::<rustc_errors::ExplicitBug>
       1: std::panic::panic_any::<rustc_errors::ExplicitBug>
       2: <rustc_errors::HandlerInner>::bug::<&alloc::string::String>
       3: <rustc_errors::Handler>::bug::<&alloc::string::String>
       4: rustc_middle::ty::context::tls::with_opt::<rustc_middle::util::bug::opt_span_bug_fmt<rustc_span::span_encoding::Span>::{closure#0}, ()>
       5: rustc_middle::util::bug::opt_span_bug_fmt::<rustc_span::span_encoding::Span>
       6: rustc_middle::util::bug::bug_fmt
       7: rustc_typeck::collect::fn_sig
       8: <rustc_query_system::dep_graph::graph::DepGraph<rustc_middle::dep_graph::dep_node::DepKind>>::with_task::<rustc_middle::ty::context::TyCtxt, rustc_span::def_id::DefId, rustc_middle::ty::sty::Binder<rustc_middle::ty::sty::FnSig>>
       9: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::plumbing::QueryCtxt, rustc_query_system::query::caches::DefaultCache<rustc_span::def_id::DefId, rustc_middle::ty::sty::Binder<rustc_middle::ty::sty::FnSig>>>
      10: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::fn_sig
      11: <&mut clippy_lints::dereference::walk_parents::{closure#0} as core::ops::function::FnMut<(rustc_hir::hir::Node, rustc_hir::hir_id::HirId)>>::call_mut
      12: clippy_utils::walk_to_expr_usage::<clippy_lints::dereference::Position, &mut clippy_lints::dereference::walk_parents::{closure#0}>
      13: <clippy_lints::dereference::Dereferencing as rustc_lint::passes::LateLintPass>::check_expr
      14: <rustc_lint::late::LateLintPassObjects as rustc_lint::passes::LateLintPass>::check_expr
      15: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_expr
      16: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_expr
      17: rustc_hir::intravisit::walk_block::<rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects>>
      18: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_block
      19: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_expr
      20: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_expr
      21: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_block
      22: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_expr
      23: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_nested_body
      24: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_fn
      25: rustc_hir::intravisit::walk_expr::<rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects>>
      26: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_expr
      27: rustc_hir::intravisit::walk_expr::<rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects>>
      28: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_expr
      29: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_nested_body
      30: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_fn
      31: rustc_hir::intravisit::walk_item::<rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects>>
      32: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_nested_item
      33: rustc_hir::intravisit::walk_mod::<rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects>>
      34: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_mod
      35: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_nested_item
      36: rustc_hir::intravisit::walk_mod::<rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects>>
      37: <rustc_lint::late::LateContextAndPass<rustc_lint::late::LateLintPassObjects> as rustc_hir::intravisit::Visitor>::visit_mod
      38: rustc_lint::late::late_lint_pass_crate::<rustc_lint::late::LateLintPassObjects>
      39: rustc_lint::late::late_lint_crate::<rustc_lint::BuiltinCombinedLateLintPass>
      40: rustc_data_structures::sync::join::<rustc_lint::late::check_crate<rustc_lint::BuiltinCombinedLateLintPass, rustc_interface::passes::analysis::{closure#5}::{closure#1}::{closure#2}::{closure#0}::{closure#0}>::{closure#0}, rustc_lint::late::check_crate<rustc_lint::BuiltinCombinedLateLintPass, rustc_interface::passes::analysis::{closure#5}::{closure#1}::{closure#2}::{closure#0}::{closure#0}>::{closure#1}, (), ()>
      41: <rustc_session::session::Session>::time::<(), rustc_interface::passes::analysis::{closure#5}::{closure#1}::{closure#2}::{closure#0}>
      42: <core::panic::unwind_safe::AssertUnwindSafe<rustc_interface::passes::analysis::{closure#5}::{closure#1}> as core::ops::function::FnOnce<()>>::call_once
      43: <rustc_session::session::Session>::time::<(), rustc_interface::passes::analysis::{closure#5}>
      44: rustc_interface::passes::analysis
      45: <rustc_query_system::dep_graph::graph::DepGraph<rustc_middle::dep_graph::dep_node::DepKind>>::with_task::<rustc_middle::ty::context::TyCtxt, (), core::result::Result<(), rustc_errors::ErrorGuaranteed>>
      46: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::plumbing::QueryCtxt, rustc_query_system::query::caches::DefaultCache<(), core::result::Result<(), rustc_errors::ErrorGuaranteed>>>
      47: rustc_query_system::query::plumbing::get_query::<rustc_query_impl::queries::analysis, rustc_query_impl::plumbing::QueryCtxt>
      48: <rustc_interface::passes::QueryContext>::enter::<rustc_driver::run_compiler::{closure#1}::{closure#2}::{closure#3}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>
      49: <rustc_interface::interface::Compiler>::enter::<rustc_driver::run_compiler::{closure#1}::{closure#2}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_errors::ErrorGuaranteed>>
      50: rustc_span::with_source_map::<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_interface::interface::create_compiler_and_run<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_driver::run_compiler::{closure#1}>::{closure#1}>
      51: <scoped_tls::ScopedKey<rustc_span::SessionGlobals>>::set::<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_driver::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

    note: the compiler unexpectedly panicked. this is a bug.

    note: we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new

    note: Clippy version: clippy 0.1.64 (46b8c23 2022-07-01)

    query stack during panic:
    #0 [fn_sig] computing function signature of `issue149::ok::{closure#0}`
    #1 [analysis] running analysis passes on this crate
    end of query stack
    error: could not compile `async-trait`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants