You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Unexpected behaviour when calling associated async function of a trait with default implementations #107002
#![feature(async_fn_in_trait)]traitAsyncTrait{asyncfndefault_impl() -> &'staticstr{"A"}asyncfncall_default_impl() -> &'staticstr{Self::default_impl().await}}traitSyncTrait{fndefault_impl() -> &'staticstr{"A"}fncall_default_impl() -> &'staticstr{Self::default_impl()}}structAsyncType;implAsyncTraitforAsyncType{asyncfndefault_impl() -> &'staticstr{"B"}}structSyncType;implSyncTraitforSyncType{fndefault_impl() -> &'staticstr{"B"}}#[tokio::main]asyncfnmain(){let a = AsyncType::call_default_impl().await;let b = SyncType::call_default_impl();println!("{a}, {b}");}
I expected to see this happen: SyncType::call_default_impl calls default_impl from impl SyncTrait for SyncType.
My expectation was the same for AsyncType::call_default_impl of the same pattern.
Instead, this happened: AsyncType::call_default_impl calls default_impl from the trait's default implementation,
instead of the one in impl AsyncTrait for AsyncType.
there is more to this, not sure if it's covered by #107013: if the implementations of default_impl vary in their number of await points, then the program can crash with all sorts of errors (segfault, stackoverflow, etc) - example
@compiler-errors#108203 didn't fully fix this. the bug still persists when using polymorphic indirection via specialization:
#![feature(async_fn_in_trait)]#![feature(min_specialization)]structMyStruct;traitMyTrait<T>{asyncfnfoo(_:T);}impl<T>MyTrait<T>forMyStruct{defaultasyncfnfoo(_:T){println!("default");}}implMyTrait<i32>forMyStruct{asyncfnfoo(_:i32){println!("specialized");}}#[tokio::main]asyncfnmain(){MyStruct::foo(42).await;indirection(42).await;}asyncfnindirection<T>(x:T){//explicit type coercion is currently necessary because of https://github.com/rust-lang/rust/issues/67918
<MyStructasMyTrait<T>>::foo(x).await;}
(note that <MyStruct as MyTrait<i32>>::foo(42).await works just fine, so #67918 probably isn't at fault)
Activity
compiler-errors commentedon Jan 17, 2023
I can take a look into this
LastExceed commentedon Jan 29, 2023
there is more to this, not sure if it's covered by #107013: if the implementations of
default_implvary in their number of await points, then the program can crash with all sorts of errors (segfault, stackoverflow, etc) - examplecompiler-errors commentedon Jan 29, 2023
Yea, it should be covered
fasterthanlime commentedon Jan 31, 2023
I've made an MVCE for essentially the same issue, if that can be helpful: https://github.com/fasterthanlime/gh-107528
Add workaround for rust-lang/rust#107002
fasterthanlime commentedon Feb 2, 2023
For anyone hitting this: seems like this a decent workaround for the time being is to go through a freestanding function that takes an
&impl Trait:bearcove/loona@2cae637#diff-b543f39ca4defdc86457f06aaef64e5fdad5fda92c91b4a98f486e7ab7b3b052R81-R87
Rollup merge of rust-lang#108203 - compiler-errors:rpitit-fix-default…
LastExceed commentedon Feb 21, 2023
@compiler-errors #108203 didn't fully fix this. the bug still persists when using polymorphic indirection via specialization:
(note that
<MyStruct as MyTrait<i32>>::foo(42).awaitworks just fine, so #67918 probably isn't at fault)output is
should be