Skip to content

Conversation

@usbalbin
Copy link

@usbalbin usbalbin commented Oct 20, 2025

This is an alternative to #1108 for solving #1107 that does not require the local_task attribute.

Breaking change

Note this is a breaking change.

Inference will no longer accept

task1::spawn(Default::default()).unwrap();

So that would have to be changed to

task1::spawn(MyArgType::default()).unwrap();

// or

ctx.local_spawner.task1(Default::default()).unwrap();

Similarly with &mut T for task argument no longer auto converted into &T.

let x: &mut u8 = ctx.local.x;
task1_taking_shared_ref::spawn(x).unwrap();

instead do

let x: &mut u8 = ctx.local.x;
task1_taking_shared_ref::spawn(&*x).unwrap();

// or 

ctx.local_spawner.task1_taking_shared_ref(x).unwrap();
@usbalbin usbalbin changed the title Spawn local without attributes Oct 20, 2025
@usbalbin usbalbin force-pushed the spawn-local-no-attrib branch from 9feaf99 to 623d8b1 Compare October 20, 2025 19:43
@usbalbin
Copy link
Author

Well this breaks a lot of inference stuff, so probably not a great solution...

@usbalbin usbalbin force-pushed the spawn-local-no-attrib branch from 623d8b1 to 669a362 Compare November 12, 2025 20:11
Comment on lines -31 to +32
incrementer::spawn(cx.local.wait_queue).ok().unwrap();
waiter::spawn(cx.local.wait_queue).ok().unwrap();
incrementer::spawn(&*cx.local.wait_queue).ok().unwrap();
waiter::spawn(&*cx.local.wait_queue).ok().unwrap();
Copy link
Author

Choose a reason for hiding this comment

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

This is a breaking change. For some reason the compiler can not auto demote &mut T to &T when generics are involved (not sure of the rules here).

Without the above fix, we get

error[E0271]: type mismatch resolving `<&mut DoublyLinkedList<Waker> as Dummy>::T == &DoublyLinkedList<Waker>`
  --> examples/wait-queue.rs:31:28
   |
31 |         incrementer::spawn(cx.local.wait_queue).ok().unwrap();
   |         ------------------ ^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<&mut DoublyLinkedList<Waker> as Dummy>::T == &DoublyLinkedList<Waker>`
   |         |
   |         required by a bound introduced by this call
   |
note: expected this to be `&'static DoublyLinkedList<Waker>`
  --> examples/wait-queue.rs:11:1
Copy link
Author

Choose a reason for hiding this comment

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

@usbalbin usbalbin force-pushed the spawn-local-no-attrib branch from 7809d1a to 6296126 Compare November 13, 2025 00:38
@usbalbin usbalbin force-pushed the spawn-local-no-attrib branch from 6296126 to d241893 Compare November 13, 2025 00:48
@usbalbin usbalbin marked this pull request as ready for review November 13, 2025 00:56
Comment on lines 1 to 4
// TODO: What should we name this?

/// Dummy trait which will only ever be implemented where type T is Self
pub trait Dummy {
Copy link
Author

Choose a reason for hiding this comment

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

Any suggestions for what to call this?

Copy link
Author

Choose a reason for hiding this comment

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

This is used because we can not have a function with a where clause which requires a concrete type to be Send if that type is not Send. The compiler will error out on us.
However hiding that behind a dummy trait which is only implemented for that same type then we defer the error to when the user tries to call the function

Copy link
Author

Choose a reason for hiding this comment

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

I went with TaskArg for now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant