diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs | 71 | ||||
| -rw-r--r-- | tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr | 26 |
2 files changed, 97 insertions, 0 deletions
diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs new file mode 100644 index 00000000000..afd3db5e052 --- /dev/null +++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs @@ -0,0 +1,71 @@ +// edition: 2021 +// known-bug: #108309 + +#![feature(async_fn_in_trait)] +#![feature(min_specialization)] + +struct MyStruct; + +trait MyTrait<T> { + async fn foo(_: T) -> &'static str; +} + +impl<T> MyTrait<T> for MyStruct { + default async fn foo(_: T) -> &'static str { + "default" + } +} + +impl MyTrait<i32> for MyStruct { + async fn foo(_: i32) -> &'static str { + "specialized" + } +} + +async fn async_main() { + assert_eq!(MyStruct::foo(42).await, "specialized"); + assert_eq!(indirection(42).await, "specialized"); +} + +async fn indirection<T>(x: T) -> &'static str { + //explicit type coercion is currently necessary + // because of https://github.com/rust-lang/rust/issues/67918 + <MyStruct as MyTrait<T>>::foo(x).await +} + +// ------------------------------------------------------------------------- // +// Implementation Details Below... + +use std::future::Future; +use std::pin::Pin; +use std::task::*; + +pub fn noop_waker() -> Waker { + let raw = RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE); + + // SAFETY: the contracts for RawWaker and RawWakerVTable are upheld + unsafe { Waker::from_raw(raw) } +} + +const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop); + +unsafe fn noop_clone(_p: *const ()) -> RawWaker { + RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE) +} + +unsafe fn noop(_p: *const ()) {} + +fn main() { + let mut fut = async_main(); + + // Poll loop, just to test the future... + let waker = noop_waker(); + let ctx = &mut Context::from_waker(&waker); + + loop { + match unsafe { Pin::new_unchecked(&mut fut).poll(ctx) } { + Poll::Pending => {} + Poll::Ready(()) => break, + } + } +} diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr new file mode 100644 index 00000000000..371122ea71e --- /dev/null +++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr @@ -0,0 +1,26 @@ +warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/dont-project-to-specializable-projection.rs:4:12 + | +LL | #![feature(async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0053]: method `foo` has an incompatible type for trait + --> $DIR/dont-project-to-specializable-projection.rs:14:35 + | +LL | default async fn foo(_: T) -> &'static str { + | ^^^^^^^^^^^^ expected associated type, found future + | +note: type in trait + --> $DIR/dont-project-to-specializable-projection.rs:10:27 + | +LL | async fn foo(_: T) -> &'static str; + | ^^^^^^^^^^^^ + = note: expected signature `fn(_) -> impl Future<Output = &'static str>` + found signature `fn(_) -> impl Future<Output = &'static str>` + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0053`. |
