diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/try-trait | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/try-trait')
-rw-r--r-- | src/test/ui/try-trait/bad-interconversion.rs | 48 | ||||
-rw-r--r-- | src/test/ui/try-trait/bad-interconversion.stderr | 127 | ||||
-rw-r--r-- | src/test/ui/try-trait/option-to-result.rs | 13 | ||||
-rw-r--r-- | src/test/ui/try-trait/option-to-result.stderr | 35 | ||||
-rw-r--r-- | src/test/ui/try-trait/try-as-monad.rs | 24 | ||||
-rw-r--r-- | src/test/ui/try-trait/try-on-option-diagnostics.rs | 47 | ||||
-rw-r--r-- | src/test/ui/try-trait/try-on-option-diagnostics.stderr | 54 | ||||
-rw-r--r-- | src/test/ui/try-trait/try-on-option.rs | 13 | ||||
-rw-r--r-- | src/test/ui/try-trait/try-on-option.stderr | 32 | ||||
-rw-r--r-- | src/test/ui/try-trait/try-operator-custom.rs | 91 | ||||
-rw-r--r-- | src/test/ui/try-trait/try-operator-on-main.rs | 22 | ||||
-rw-r--r-- | src/test/ui/try-trait/try-operator-on-main.stderr | 63 | ||||
-rw-r--r-- | src/test/ui/try-trait/try-poll.rs | 50 | ||||
-rw-r--r-- | src/test/ui/try-trait/yeet-for-option.rs | 11 | ||||
-rw-r--r-- | src/test/ui/try-trait/yeet-for-result.rs | 11 |
15 files changed, 641 insertions, 0 deletions
diff --git a/src/test/ui/try-trait/bad-interconversion.rs b/src/test/ui/try-trait/bad-interconversion.rs new file mode 100644 index 000000000..385f5510f --- /dev/null +++ b/src/test/ui/try-trait/bad-interconversion.rs @@ -0,0 +1,48 @@ +#![feature(control_flow_enum)] + +use std::ops::ControlFlow; + +fn result_to_result() -> Result<u64, u8> { + Ok(Err(123_i32)?) + //~^ ERROR `?` couldn't convert the error to `u8` +} + +fn option_to_result() -> Result<u64, String> { + Some(3)?; + //~^ ERROR the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result` + Ok(10) +} + +fn control_flow_to_result() -> Result<u64, String> { + Ok(ControlFlow::Break(123)?) + //~^ ERROR the `?` operator can only be used on `Result`s in a function that returns `Result` +} + +fn result_to_option() -> Option<u16> { + Some(Err("hello")?) + //~^ ERROR the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option` +} + +fn control_flow_to_option() -> Option<u64> { + Some(ControlFlow::Break(123)?) + //~^ ERROR the `?` operator can only be used on `Option`s in a function that returns `Option` +} + +fn result_to_control_flow() -> ControlFlow<String> { + ControlFlow::Continue(Err("hello")?) + //~^ ERROR the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow` +} + +fn option_to_control_flow() -> ControlFlow<u64> { + Some(3)?; + //~^ ERROR the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow` + ControlFlow::Break(10) +} + +fn control_flow_to_control_flow() -> ControlFlow<i64> { + ControlFlow::Break(4_u8)?; + //~^ ERROR the `?` operator in a function that returns `ControlFlow<B, _>` can only be used on other `ControlFlow<B, _>`s + ControlFlow::Continue(()) +} + +fn main() {} diff --git a/src/test/ui/try-trait/bad-interconversion.stderr b/src/test/ui/try-trait/bad-interconversion.stderr new file mode 100644 index 000000000..1dbf3ebdf --- /dev/null +++ b/src/test/ui/try-trait/bad-interconversion.stderr @@ -0,0 +1,127 @@ +error[E0277]: `?` couldn't convert the error to `u8` + --> $DIR/bad-interconversion.rs:6:20 + | +LL | fn result_to_result() -> Result<u64, u8> { + | --------------- expected `u8` because of this +LL | Ok(Err(123_i32)?) + | ^ the trait `From<i32>` is not implemented for `u8` + | + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait + = help: the following other types implement trait `From<T>`: + <f32 as From<i16>> + <f32 as From<i8>> + <f32 as From<u16>> + <f32 as From<u8>> + <f64 as From<f32>> + <f64 as From<i16>> + <f64 as From<i32>> + <f64 as From<i8>> + and 67 others + = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, i32>>` for `Result<u64, u8>` + +error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result` + --> $DIR/bad-interconversion.rs:11:12 + | +LL | / fn option_to_result() -> Result<u64, String> { +LL | | Some(3)?; + | | ^ use `.ok_or(...)?` to provide an error compatible with `Result<u64, String>` +LL | | +LL | | Ok(10) +LL | | } + | |_- this function returns a `Result` + | + = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<u64, String>` + = help: the following other types implement trait `FromResidual<R>`: + <Result<T, F> as FromResidual<Result<Infallible, E>>> + <Result<T, F> as FromResidual<Yeet<E>>> + +error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result` + --> $DIR/bad-interconversion.rs:17:31 + | +LL | / fn control_flow_to_result() -> Result<u64, String> { +LL | | Ok(ControlFlow::Break(123)?) + | | ^ this `?` produces `ControlFlow<{integer}, Infallible>`, which is incompatible with `Result<u64, String>` +LL | | +LL | | } + | |_- this function returns a `Result` + | + = help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Result<u64, String>` + = help: the following other types implement trait `FromResidual<R>`: + <Result<T, F> as FromResidual<Result<Infallible, E>>> + <Result<T, F> as FromResidual<Yeet<E>>> + +error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option` + --> $DIR/bad-interconversion.rs:22:22 + | +LL | / fn result_to_option() -> Option<u16> { +LL | | Some(Err("hello")?) + | | ^ use `.ok()?` if you want to discard the `Result<Infallible, &str>` error information +LL | | +LL | | } + | |_- this function returns an `Option` + | + = help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `Option<u16>` + = help: the following other types implement trait `FromResidual<R>`: + <Option<T> as FromResidual<Yeet<()>>> + <Option<T> as FromResidual> + +error[E0277]: the `?` operator can only be used on `Option`s in a function that returns `Option` + --> $DIR/bad-interconversion.rs:27:33 + | +LL | / fn control_flow_to_option() -> Option<u64> { +LL | | Some(ControlFlow::Break(123)?) + | | ^ this `?` produces `ControlFlow<{integer}, Infallible>`, which is incompatible with `Option<u64>` +LL | | +LL | | } + | |_- this function returns an `Option` + | + = help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Option<u64>` + = help: the following other types implement trait `FromResidual<R>`: + <Option<T> as FromResidual<Yeet<()>>> + <Option<T> as FromResidual> + +error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow` + --> $DIR/bad-interconversion.rs:32:39 + | +LL | / fn result_to_control_flow() -> ControlFlow<String> { +LL | | ControlFlow::Continue(Err("hello")?) + | | ^ this `?` produces `Result<Infallible, &str>`, which is incompatible with `ControlFlow<String>` +LL | | +LL | | } + | |_- this function returns a `ControlFlow` + | + = help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `ControlFlow<String>` + = help: the trait `FromResidual` is implemented for `ControlFlow<B, C>` + +error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow` + --> $DIR/bad-interconversion.rs:37:12 + | +LL | / fn option_to_control_flow() -> ControlFlow<u64> { +LL | | Some(3)?; + | | ^ this `?` produces `Option<Infallible>`, which is incompatible with `ControlFlow<u64>` +LL | | +LL | | ControlFlow::Break(10) +LL | | } + | |_- this function returns a `ControlFlow` + | + = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `ControlFlow<u64>` + = help: the trait `FromResidual` is implemented for `ControlFlow<B, C>` + +error[E0277]: the `?` operator in a function that returns `ControlFlow<B, _>` can only be used on other `ControlFlow<B, _>`s (with the same Break type) + --> $DIR/bad-interconversion.rs:43:29 + | +LL | / fn control_flow_to_control_flow() -> ControlFlow<i64> { +LL | | ControlFlow::Break(4_u8)?; + | | ^ this `?` produces `ControlFlow<u8, Infallible>`, which is incompatible with `ControlFlow<i64>` +LL | | +LL | | ControlFlow::Continue(()) +LL | | } + | |_- this function returns a `ControlFlow` + | + = help: the trait `FromResidual<ControlFlow<u8, Infallible>>` is not implemented for `ControlFlow<i64>` + = note: unlike `Result`, there's no `From`-conversion performed for `ControlFlow` + = help: the trait `FromResidual` is implemented for `ControlFlow<B, C>` + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/try-trait/option-to-result.rs b/src/test/ui/try-trait/option-to-result.rs new file mode 100644 index 000000000..45aaf361a --- /dev/null +++ b/src/test/ui/try-trait/option-to-result.rs @@ -0,0 +1,13 @@ +fn main(){ } + +fn test_result() -> Result<(),()> { + let a:Option<()> = Some(()); + a?;//~ ERROR the `?` operator can only be used + Ok(()) +} + +fn test_option() -> Option<i32>{ + let a:Result<i32, i32> = Ok(5); + a?;//~ ERROR the `?` operator can only be used + Some(5) +} diff --git a/src/test/ui/try-trait/option-to-result.stderr b/src/test/ui/try-trait/option-to-result.stderr new file mode 100644 index 000000000..ae5c3ad62 --- /dev/null +++ b/src/test/ui/try-trait/option-to-result.stderr @@ -0,0 +1,35 @@ +error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result` + --> $DIR/option-to-result.rs:5:6 + | +LL | / fn test_result() -> Result<(),()> { +LL | | let a:Option<()> = Some(()); +LL | | a?; + | | ^ use `.ok_or(...)?` to provide an error compatible with `Result<(), ()>` +LL | | Ok(()) +LL | | } + | |_- this function returns a `Result` + | + = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<(), ()>` + = help: the following other types implement trait `FromResidual<R>`: + <Result<T, F> as FromResidual<Result<Infallible, E>>> + <Result<T, F> as FromResidual<Yeet<E>>> + +error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option` + --> $DIR/option-to-result.rs:11:6 + | +LL | / fn test_option() -> Option<i32>{ +LL | | let a:Result<i32, i32> = Ok(5); +LL | | a?; + | | ^ use `.ok()?` if you want to discard the `Result<Infallible, i32>` error information +LL | | Some(5) +LL | | } + | |_- this function returns an `Option` + | + = help: the trait `FromResidual<Result<Infallible, i32>>` is not implemented for `Option<i32>` + = help: the following other types implement trait `FromResidual<R>`: + <Option<T> as FromResidual<Yeet<()>>> + <Option<T> as FromResidual> + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/try-trait/try-as-monad.rs b/src/test/ui/try-trait/try-as-monad.rs new file mode 100644 index 000000000..cf09838b3 --- /dev/null +++ b/src/test/ui/try-trait/try-as-monad.rs @@ -0,0 +1,24 @@ +// run-pass + +#![feature(try_trait_v2)] + +use std::ops::Try; + +fn monad_unit<T: Try>(x: <T as Try>::Output) -> T { + T::from_output(x) +} + +fn monad_bind<T1: Try<Residual = R>, T2: Try<Residual = R>, R>( + mx: T1, + f: impl FnOnce(<T1 as Try>::Output) -> T2) +-> T2 { + let x = mx?; + f(x) +} + +fn main() { + let mx: Option<i32> = monad_unit(1); + let my = monad_bind(mx, |x| Some(x + 1)); + let mz = monad_bind(my, |x| Some(-x)); + assert_eq!(mz, Some(-2)); +} diff --git a/src/test/ui/try-trait/try-on-option-diagnostics.rs b/src/test/ui/try-trait/try-on-option-diagnostics.rs new file mode 100644 index 000000000..7ffa0de6c --- /dev/null +++ b/src/test/ui/try-trait/try-on-option-diagnostics.rs @@ -0,0 +1,47 @@ +// edition:2018 + +fn main() {} + +fn a_function() -> u32 { + let x: Option<u32> = None; + x?; //~ ERROR the `?` operator + 22 +} + +fn a_closure() -> u32 { + let a_closure = || { + let x: Option<u32> = None; + x?; //~ ERROR the `?` operator + 22 + }; + a_closure() +} + +fn a_method() -> u32 { + struct S; + + impl S { + fn a_method() { + let x: Option<u32> = None; + x?; //~ ERROR the `?` operator + } + } + + S::a_method(); + 22 +} + +fn a_trait_method() -> u32 { + struct S; + trait T { + fn a_trait_method() { + let x: Option<u32> = None; + x?; //~ ERROR the `?` operator + } + } + + impl T for S { } + + S::a_trait_method(); + 22 +} diff --git a/src/test/ui/try-trait/try-on-option-diagnostics.stderr b/src/test/ui/try-trait/try-on-option-diagnostics.stderr new file mode 100644 index 000000000..a6badd190 --- /dev/null +++ b/src/test/ui/try-trait/try-on-option-diagnostics.stderr @@ -0,0 +1,54 @@ +error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) + --> $DIR/try-on-option-diagnostics.rs:7:6 + | +LL | / fn a_function() -> u32 { +LL | | let x: Option<u32> = None; +LL | | x?; + | | ^ cannot use the `?` operator in a function that returns `u32` +LL | | 22 +LL | | } + | |_- this function should return `Result` or `Option` to accept `?` + | + = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `u32` + +error[E0277]: the `?` operator can only be used in a closure that returns `Result` or `Option` (or another type that implements `FromResidual`) + --> $DIR/try-on-option-diagnostics.rs:14:10 + | +LL | let a_closure = || { + | _____________________- +LL | | let x: Option<u32> = None; +LL | | x?; + | | ^ cannot use the `?` operator in a closure that returns `{integer}` +LL | | 22 +LL | | }; + | |_____- this function should return `Result` or `Option` to accept `?` + | + = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `{integer}` + +error[E0277]: the `?` operator can only be used in a method that returns `Result` or `Option` (or another type that implements `FromResidual`) + --> $DIR/try-on-option-diagnostics.rs:26:14 + | +LL | / fn a_method() { +LL | | let x: Option<u32> = None; +LL | | x?; + | | ^ cannot use the `?` operator in a method that returns `()` +LL | | } + | |_________- this function should return `Result` or `Option` to accept `?` + | + = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `()` + +error[E0277]: the `?` operator can only be used in a trait method that returns `Result` or `Option` (or another type that implements `FromResidual`) + --> $DIR/try-on-option-diagnostics.rs:39:14 + | +LL | / fn a_trait_method() { +LL | | let x: Option<u32> = None; +LL | | x?; + | | ^ cannot use the `?` operator in a trait method that returns `()` +LL | | } + | |_________- this function should return `Result` or `Option` to accept `?` + | + = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `()` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/try-trait/try-on-option.rs b/src/test/ui/try-trait/try-on-option.rs new file mode 100644 index 000000000..8519932a6 --- /dev/null +++ b/src/test/ui/try-trait/try-on-option.rs @@ -0,0 +1,13 @@ +fn main() {} + +fn foo() -> Result<u32, ()> { + let x: Option<u32> = None; + x?; //~ ERROR the `?` operator + Ok(22) +} + +fn bar() -> u32 { + let x: Option<u32> = None; + x?; //~ ERROR the `?` operator + 22 +} diff --git a/src/test/ui/try-trait/try-on-option.stderr b/src/test/ui/try-trait/try-on-option.stderr new file mode 100644 index 000000000..ba85a7cad --- /dev/null +++ b/src/test/ui/try-trait/try-on-option.stderr @@ -0,0 +1,32 @@ +error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result` + --> $DIR/try-on-option.rs:5:6 + | +LL | / fn foo() -> Result<u32, ()> { +LL | | let x: Option<u32> = None; +LL | | x?; + | | ^ use `.ok_or(...)?` to provide an error compatible with `Result<u32, ()>` +LL | | Ok(22) +LL | | } + | |_- this function returns a `Result` + | + = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<u32, ()>` + = help: the following other types implement trait `FromResidual<R>`: + <Result<T, F> as FromResidual<Result<Infallible, E>>> + <Result<T, F> as FromResidual<Yeet<E>>> + +error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) + --> $DIR/try-on-option.rs:11:6 + | +LL | / fn bar() -> u32 { +LL | | let x: Option<u32> = None; +LL | | x?; + | | ^ cannot use the `?` operator in a function that returns `u32` +LL | | 22 +LL | | } + | |_- this function should return `Result` or `Option` to accept `?` + | + = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `u32` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/try-trait/try-operator-custom.rs b/src/test/ui/try-trait/try-operator-custom.rs new file mode 100644 index 000000000..45636a7fc --- /dev/null +++ b/src/test/ui/try-trait/try-operator-custom.rs @@ -0,0 +1,91 @@ +// run-pass + +#![feature(control_flow_enum)] +#![feature(try_trait_v2)] + +use std::ops::{ControlFlow, FromResidual, Try}; + +enum MyResult<T, U> { + Awesome(T), + Terrible(U) +} + +enum Never {} + +impl<U, V> Try for MyResult<U, V> { + type Output = U; + type Residual = MyResult<Never, V>; + + fn from_output(u: U) -> MyResult<U, V> { + MyResult::Awesome(u) + } + + fn branch(self) -> ControlFlow<Self::Residual, Self::Output> { + match self { + MyResult::Awesome(u) => ControlFlow::Continue(u), + MyResult::Terrible(e) => ControlFlow::Break(MyResult::Terrible(e)), + } + } +} + +impl<U, V, W> FromResidual<MyResult<Never, V>> for MyResult<U, W> where V: Into<W> { + fn from_residual(x: MyResult<Never, V>) -> Self { + match x { + MyResult::Awesome(u) => match u {}, + MyResult::Terrible(e) => MyResult::Terrible(e.into()), + } + } +} + +type ResultResidual<E> = Result<std::convert::Infallible, E>; + +impl<U, V, W> FromResidual<ResultResidual<V>> for MyResult<U, W> where V: Into<W> { + fn from_residual(x: ResultResidual<V>) -> Self { + match x { + Ok(v) => match v {} + Err(e) => MyResult::Terrible(e.into()), + } + } +} + +impl<U, V, W> FromResidual<MyResult<Never, V>> for Result<U, W> where V: Into<W> { + fn from_residual(x: MyResult<Never, V>) -> Self { + match x { + MyResult::Awesome(u) => match u {}, + MyResult::Terrible(e) => Err(e.into()), + } + } +} + +fn f(x: i32) -> Result<i32, String> { + if x == 0 { + Ok(42) + } else { + let y = g(x)?; + Ok(y) + } +} + +fn g(x: i32) -> MyResult<i32, String> { + let _y = f(x - 1)?; + MyResult::Terrible("Hello".to_owned()) +} + +fn h() -> MyResult<i32, String> { + let a: Result<i32, &'static str> = Err("Hello"); + let b = a?; + MyResult::Awesome(b) +} + +fn i() -> MyResult<i32, String> { + let a: MyResult<i32, &'static str> = MyResult::Terrible("Hello"); + let b = a?; + MyResult::Awesome(b) +} + +fn main() { + assert!(f(0) == Ok(42)); + assert!(f(10) == Err("Hello".to_owned())); + let _ = h(); + let _ = i(); +} diff --git a/src/test/ui/try-trait/try-operator-on-main.rs b/src/test/ui/try-trait/try-operator-on-main.rs new file mode 100644 index 000000000..3b364f7e7 --- /dev/null +++ b/src/test/ui/try-trait/try-operator-on-main.rs @@ -0,0 +1,22 @@ +#![feature(try_trait_v2)] + +use std::ops::Try; + +fn main() { + // error for a `Try` type on a non-`Try` fn + std::fs::File::open("foo")?; //~ ERROR the `?` operator can only + + // a non-`Try` type on a non-`Try` fn + ()?; //~ ERROR the `?` operator can only be applied to + //~^ ERROR the `?` operator can only be used in a function that + + // an unrelated use of `Try` + try_trait_generic::<()>(); //~ ERROR the trait bound +} + +fn try_trait_generic<T: Try>() -> T { + // and a non-`Try` object on a `Try` fn. + ()?; //~ ERROR the `?` operator can only be applied to values that implement `Try` + + loop {} +} diff --git a/src/test/ui/try-trait/try-operator-on-main.stderr b/src/test/ui/try-trait/try-operator-on-main.stderr new file mode 100644 index 000000000..ad55f40b5 --- /dev/null +++ b/src/test/ui/try-trait/try-operator-on-main.stderr @@ -0,0 +1,63 @@ +error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) + --> $DIR/try-operator-on-main.rs:7:31 + | +LL | / fn main() { +LL | | // error for a `Try` type on a non-`Try` fn +LL | | std::fs::File::open("foo")?; + | | ^ cannot use the `?` operator in a function that returns `()` +LL | | +... | +LL | | try_trait_generic::<()>(); +LL | | } + | |_- this function should return `Result` or `Option` to accept `?` + | + = help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()` + +error[E0277]: the `?` operator can only be applied to values that implement `Try` + --> $DIR/try-operator-on-main.rs:10:5 + | +LL | ()?; + | ^^^ the `?` operator cannot be applied to type `()` + | + = help: the trait `Try` is not implemented for `()` + +error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) + --> $DIR/try-operator-on-main.rs:10:7 + | +LL | / fn main() { +LL | | // error for a `Try` type on a non-`Try` fn +LL | | std::fs::File::open("foo")?; +LL | | +LL | | // a non-`Try` type on a non-`Try` fn +LL | | ()?; + | | ^ cannot use the `?` operator in a function that returns `()` +... | +LL | | try_trait_generic::<()>(); +LL | | } + | |_- this function should return `Result` or `Option` to accept `?` + | + = help: the trait `FromResidual<_>` is not implemented for `()` + +error[E0277]: the trait bound `(): Try` is not satisfied + --> $DIR/try-operator-on-main.rs:14:25 + | +LL | try_trait_generic::<()>(); + | ^^ the trait `Try` is not implemented for `()` + | +note: required by a bound in `try_trait_generic` + --> $DIR/try-operator-on-main.rs:17:25 + | +LL | fn try_trait_generic<T: Try>() -> T { + | ^^^ required by this bound in `try_trait_generic` + +error[E0277]: the `?` operator can only be applied to values that implement `Try` + --> $DIR/try-operator-on-main.rs:19:5 + | +LL | ()?; + | ^^^ the `?` operator cannot be applied to type `()` + | + = help: the trait `Try` is not implemented for `()` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/try-trait/try-poll.rs b/src/test/ui/try-trait/try-poll.rs new file mode 100644 index 000000000..d42e51c74 --- /dev/null +++ b/src/test/ui/try-trait/try-poll.rs @@ -0,0 +1,50 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![allow(dead_code, unused)] + +use std::task::Poll; + +struct K; +struct E; + +fn as_result() -> Result<(), E> { + // From Result + let K = Ok::<K, E>(K)?; + + // From Poll<Result> + let _: Poll<K> = Poll::Ready::<Result<K, E>>(Ok(K))?; + + // From Poll<Option<Result>> + let _: Poll<Option<K>> = Poll::Ready::<Option<Result<K, E>>>(None)?; + + Ok(()) +} + +fn as_poll_result() -> Poll<Result<(), E>> { + // From Result + let K = Ok::<K, E>(K)?; + + // From Poll<Result> + let _: Poll<K> = Poll::Ready::<Result<K, E>>(Ok(K))?; + + // From Poll<Option<Result>> + let _: Poll<Option<K>> = Poll::Ready::<Option<Result<K, E>>>(None)?; + + Poll::Ready(Ok(())) +} + +fn as_poll_option_result() -> Poll<Option<Result<(), E>>> { + // From Result + let K = Ok::<K, E>(K)?; + + // From Poll<Result> + let _: Poll<K> = Poll::Ready::<Result<K, E>>(Ok(K))?; + + // From Poll<Option<Result>> + let _: Poll<Option<K>> = Poll::Ready::<Option<Result<K, E>>>(None)?; + + Poll::Ready(Some(Ok(()))) +} + +fn main() { +} diff --git a/src/test/ui/try-trait/yeet-for-option.rs b/src/test/ui/try-trait/yeet-for-option.rs new file mode 100644 index 000000000..753fbc1de --- /dev/null +++ b/src/test/ui/try-trait/yeet-for-option.rs @@ -0,0 +1,11 @@ +// run-pass + +#![feature(yeet_expr)] + +fn always_yeet() -> Option<String> { + do yeet; +} + +fn main() { + assert_eq!(always_yeet(), None); +} diff --git a/src/test/ui/try-trait/yeet-for-result.rs b/src/test/ui/try-trait/yeet-for-result.rs new file mode 100644 index 000000000..b7b113797 --- /dev/null +++ b/src/test/ui/try-trait/yeet-for-result.rs @@ -0,0 +1,11 @@ +// run-pass + +#![feature(yeet_expr)] + +fn always_yeet() -> Result<i32, String> { + do yeet "hello"; +} + +fn main() { + assert_eq!(always_yeet(), Err("hello".to_string())); +} |