Open
Description
Tested on nightly 2022-07-21.
Illustrating as a edit-compile cycle:
#![feature(generic_associated_types)]
use core::future::Future;
trait Task {
type Output<'a>: 'a + Future<Output = ()>
where
Self: 'a;
fn call(&mut self) -> Self::Output<'_>;
}
type DynTask = dyn Task<Output = Box<dyn Future<Output = ()>>>;
error[E0107]: missing generics for associated type `Task::Output`
--> src/lib.rs:12:25
|
12 | type DynTask = dyn Task<Output = Box<dyn Future<Output = ()>>>;
| ^^^^^^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
--> src/lib.rs:6:10
|
6 | type Output<'a>: 'a + Future<Output = ()>
| ^^^^^^ --
help: add missing lifetime argument
|
12 | type DynTask = dyn Task<Output<'a> = Box<dyn Future<Output = ()>>>;
| ~~~~~~~~~~
Apply the suggestion.
type DynTask = dyn Task<Output<'a> = Box<dyn Future<Output = ()>>>;
error[E0261]: use of undeclared lifetime name `'a`
--> src/lib.rs:12:32
|
12 | type DynTask = dyn Task<Output<'a> = Box<dyn Future<Output = ()>>>;
| ^^ undeclared lifetime
|
= note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
help: consider making the bound lifetime-generic with a new `'a` lifetime
|
12 | type DynTask = dyn for<'a> Task<Output<'a> = Box<dyn Future<Output = ()>>>;
| +++++++
help: consider introducing lifetime `'a` here
|
12 | type DynTask<'a> = dyn Task<Output<'a> = Box<dyn Future<Output = ()>>>;
| ++++
That looks wrong, let me try:
type DynTask = dyn Task<for<'a> Output<'a> = Box<dyn Future<Output = ()>>>;
error: `for<...>` is not allowed on associated type bounds
--> src/lib.rs:12:25
|
12 | type DynTask = dyn Task<for<'a> Output<'a> = Box<dyn Future<Output = ()>>>;
| ^^^^^^^^^^^^^^^^^^
Okay, let's do what the compiler suggested
type DynTask = dyn for<'a> Task<Output<'a> = Box<dyn Future<Output = ()>>>;
warning: type alias `DynTask` is never used
--> src/lib.rs:12:6
|
12 | type DynTask = dyn for<'a> Task<Output<'a> = Box<dyn Future<Output = ()>>>;
| ^^^^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: `playground` (lib) generated 1 warning
Success! Time to use it...
error[E0038]: the trait `Task` cannot be made into an object
--> src/lib.rs:14:18
|
14 | fn takes(_: &mut DynTask) {}
| ^^^^^^^ `Task` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> src/lib.rs:6:10
|
5 | trait Task {
| ---- this trait cannot be made into an object...
6 | type Output<'a>: 'a + Future<Output = ()>
| ^^^^^^ ...because it contains the generic associated type `Output`
= help: consider moving `Output` to another trait
🙃