Skip to content

Instantly share code, notes, and snippets.

@Dessix
Created March 20, 2021 15:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Dessix/2d06becd23ff9291d8fab4015d17975b to your computer and use it in GitHub Desktop.
Save Dessix/2d06becd23ff9291d8fab4015d17975b to your computer and use it in GitHub Desktop.
Rust Analyzer inference issues with futures
use futures::{Future, future::BoxFuture};
pub trait InferenceBreaker {
fn trait_boxed_break(&self) -> BoxFuture<Result<(), ()>>;
}
pub struct TraitlessBreaker;
impl TraitlessBreaker {
pub fn struct_boxed_break<'a>() -> BoxFuture<'a, Result<(), ()>> {
todo!()
}
pub fn struct_impl_works() -> impl Future<Output = Result<(), ()>> {
async { todo!() }
}
}
pub struct TraitBreakerImpl;
impl InferenceBreaker for TraitBreakerImpl {
fn trait_boxed_break(&self) -> BoxFuture<Result<(), ()>> {
todo!()
}
}
pub async fn _break_inference(instance: Box<dyn InferenceBreaker + Send + Sync>) {
let _from_trait_boxed = instance.trait_boxed_break().await;
// _from_trait_boxed is inferred to be `<<{unknown} as Deref>::Target as Future>::Output`
let _from_struct_boxed = TraitlessBreaker::struct_boxed_break().await;
// _from_struct_boxed is inferred to be `<<{unknown} as Deref>::Target as Future>::Output`
}
pub async fn _impl_also_breaks(instance: impl InferenceBreaker + Send + Sync) {
let _from_trait_boxed = instance.trait_boxed_break().await;
// _from_trait_boxed is inferred to be `<<{unknown} as Deref>::Target as Future>::Output`
}
pub async fn _struct_traited_breaks() {
let _no_dyn_or_impl = TraitBreakerImpl.trait_boxed_break().await;
// _no_dyn_or_impl is inferred to be `<<{unknown} as Deref>::Target as Future>::Output`
let _no_dyn_or_impl_2 = InferenceBreaker::trait_boxed_break(&TraitBreakerImpl).await;
// _no_dyn_or_impl_2 is inferred to be `<<{unknown} as Deref>::Target as Future>::Output`
}
pub async fn _break_occurs_on_await() {
let fut = TraitBreakerImpl.trait_boxed_break();
// fut is inferred to be `Pin<Box<dyn Future<Output = Result<(), ()>> + Send>>`
let _output = fut.await;
// _output is inferred to be `<<{unknown} as Deref>::Target as Future>::Output`
}
pub async fn _impl_works() {
let _from_struct_impl = TraitlessBreaker::struct_impl_works().await;
// _from_struct_impl infers correctly to `Result<(), ()>`
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment