-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Tracking issue for unsized tuple coercion #42877
Comments
Triage: no changes |
T-lang discussed this in a backlog bonanza meeting today, and noted several concerns that should be addressed prior to moving forward:
|
I subscribed to this because I wanted to use it once... but didn't because it's unstable and not too hard to work around. I suspect the same goes for many non-trivial projects. Searching GitHub shows 1391 code results, most of which appear to be tests. There are a few uses on the first page: https://github.com/aschaeffer/inexor-rgf-application, https://github.com/aschaeffer/rust-ecs-poc, https://github.com/libdither/disp, https://github.com/icostin/halfbit (feature = "nightly"); everything after that appears to be tests (I checked 10 more pages). In short: some possible utility, but not a priority. |
I wish to use this in safina-executor library. The library currently uses this type for async tasks: Arc<Mutex<dyn Future<Output = ()> + Send + Unpin>> I am modifying it to remember when a task has returned I would like to use the following type, but it depends on this Arc<Mutex<(bool, dyn Future<Output = ()> + Send + Unpin)>> Instead, I will use this type, which requires two allocations per task: Arc<Mutex<Option<Box<dyn Future<Output = ()> + Send + Unpin>>>> This is OK. Async tasks are generally long-lived data structures. Therefore, the extra allocation is a very small added cost. This |
To use |
@SimonSapin A struct works! struct Task<T: ?Sized> {
completed: bool,
fut: T,
}
impl<T> Task<T> {
pub fn new(fut: T) -> Arc<Mutex<Self>> {
Arc::new(Mutex::new(Task {
completed: false,
fut,
}))
}
}
impl Executor {
//...
pub fn spawn_unpin(self: &Arc<Self>, fut: impl (Future<Output = ()>) + Send + Unpin + 'static) {
let task = Task::new(fut);
let weak_self = Arc::downgrade(self);
self.async_pool.schedule(move || poll_task(task, weak_self));
}
} I think I'm going to keep the enum Task<T: ?Sized> {
None,
Some(T),
}
// error[E0277]: the size for values of type `T` cannot be known at compilation time |
I just realized that the |
There's an argument to be made for consistency. You can unsize coerce, deconstruct, and otherwise match against custom tuple types already. You can also do all these things on stable with built-in tuples too, given a touch of Footnotes
|
@QuineDot no you can't. You are merely using references to unsized types. However, this edited version works (avoids deconstruction of the unsized parameter, or more precisely merely avoids creating a |
This is a part of #18469. This is currently feature-gated behind
#![feature(unsized_tuple_coercion)]
to avoid insta-stability.Related issues/PRs: #18469, #32702, #34451, #37685, #42527
This is needed for unsizing the last field in a tuple:
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=5f93d1d7c6ee0e969df53c13e1aa941a
The text was updated successfully, but these errors were encountered: