When you use impl SomeTrait in the type of a function parameter, the caller of the function gets to choose the type. In other words, it is shorthand for:
async fn bar<T>(mut sender: mpsc::Sender<(T, String)>) where T: SomeTrait
However, your function body expects a Sender<(Foo, String)>, and won't work with any other type of Sender. So it will only compile if you require the caller to pass a Sender<(Foo, String)>:
If SomeTrait were implemented for i32, and someone sent in an mpsc::Sender<(i32, String)>, your function would not be able to handle it, because the sender is given a (Foo, String) instead. Therefore this doesn't work.
Note, impl Trait doesn't give you trait objects. You may be looking for dyn Trait instead. Trait objects are unsized, so they need to be passed behind some form of pointer. Generally a Box is a good choice. So you could try:
async fn bar(mut sender: mpsc::sender<(Box<dyn SomeTrait>, String)>){
if let Some(foo, some_string) = baz().await{
let _ = sender.send((Box::new(foo), some_string));
}
}
Alright I guess I'll have to go for Box then. I knew that would probably work, but didn't want to use it because that impl Trait is used all over my code. I'll have to go around changing all of them now