summaryrefslogtreecommitdiffstats
path: root/tests/ui/try-trait
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
commit218caa410aa38c29984be31a5229b9fa717560ee (patch)
treec54bd55eeb6e4c508940a30e94c0032fbd45d677 /tests/ui/try-trait
parentReleasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz
rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/try-trait')
-rw-r--r--tests/ui/try-trait/bad-interconversion.rs48
-rw-r--r--tests/ui/try-trait/bad-interconversion.stderr103
-rw-r--r--tests/ui/try-trait/option-to-result.rs13
-rw-r--r--tests/ui/try-trait/option-to-result.stderr31
-rw-r--r--tests/ui/try-trait/try-as-monad.rs24
-rw-r--r--tests/ui/try-trait/try-on-option-diagnostics.rs47
-rw-r--r--tests/ui/try-trait/try-on-option-diagnostics.stderr47
-rw-r--r--tests/ui/try-trait/try-on-option.rs13
-rw-r--r--tests/ui/try-trait/try-on-option.stderr28
-rw-r--r--tests/ui/try-trait/try-operator-custom.rs91
-rw-r--r--tests/ui/try-trait/try-operator-on-main.rs22
-rw-r--r--tests/ui/try-trait/try-operator-on-main.stderr53
-rw-r--r--tests/ui/try-trait/try-poll.rs50
-rw-r--r--tests/ui/try-trait/yeet-for-option.rs11
-rw-r--r--tests/ui/try-trait/yeet-for-result.rs11
15 files changed, 592 insertions, 0 deletions
diff --git a/tests/ui/try-trait/bad-interconversion.rs b/tests/ui/try-trait/bad-interconversion.rs
new file mode 100644
index 000000000..385f5510f
--- /dev/null
+++ b/tests/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/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr
new file mode 100644
index 000000000..a49630adb
--- /dev/null
+++ b/tests/ui/try-trait/bad-interconversion.stderr
@@ -0,0 +1,103 @@
+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>`:
+ <u8 as From<NonZeroU8>>
+ <u8 as From<bool>>
+ = note: required for `Result<u64, u8>` to implement `FromResidual<Result<Infallible, i32>>`
+
+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> {
+ | -------------------------------------------- this function returns a `Result`
+LL | Some(3)?;
+ | ^ use `.ok_or(...)?` to provide an error compatible with `Result<u64, String>`
+ |
+ = 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> {
+ | -------------------------------------------------- this function returns a `Result`
+LL | Ok(ControlFlow::Break(123)?)
+ | ^ this `?` produces `ControlFlow<{integer}, Infallible>`, which is incompatible with `Result<u64, String>`
+ |
+ = 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> {
+ | ------------------------------------ this function returns an `Option`
+LL | Some(Err("hello")?)
+ | ^ use `.ok()?` if you want to discard the `Result<Infallible, &str>` error information
+ |
+ = 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> {
+ | ------------------------------------------ this function returns an `Option`
+LL | Some(ControlFlow::Break(123)?)
+ | ^ this `?` produces `ControlFlow<{integer}, Infallible>`, which is incompatible with `Option<u64>`
+ |
+ = 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> {
+ | -------------------------------------------------- this function returns a `ControlFlow`
+LL | ControlFlow::Continue(Err("hello")?)
+ | ^ this `?` produces `Result<Infallible, &str>`, which is incompatible with `ControlFlow<String>`
+ |
+ = 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> {
+ | ----------------------------------------------- this function returns a `ControlFlow`
+LL | Some(3)?;
+ | ^ this `?` produces `Option<Infallible>`, which is incompatible with `ControlFlow<u64>`
+ |
+ = 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> {
+ | ----------------------------------------------------- this function returns a `ControlFlow`
+LL | ControlFlow::Break(4_u8)?;
+ | ^ this `?` produces `ControlFlow<u8, Infallible>`, which is incompatible with `ControlFlow<i64>`
+ |
+ = 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/tests/ui/try-trait/option-to-result.rs b/tests/ui/try-trait/option-to-result.rs
new file mode 100644
index 000000000..45aaf361a
--- /dev/null
+++ b/tests/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/tests/ui/try-trait/option-to-result.stderr b/tests/ui/try-trait/option-to-result.stderr
new file mode 100644
index 000000000..fabc1ff2c
--- /dev/null
+++ b/tests/ui/try-trait/option-to-result.stderr
@@ -0,0 +1,31 @@
+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<(),()> {
+ | --------------------------------- this function returns a `Result`
+LL | let a:Option<()> = Some(());
+LL | a?;
+ | ^ use `.ok_or(...)?` to provide an error compatible with `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>{
+ | ------------------------------- this function returns an `Option`
+LL | let a:Result<i32, i32> = Ok(5);
+LL | a?;
+ | ^ use `.ok()?` if you want to discard the `Result<Infallible, i32>` error information
+ |
+ = 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/tests/ui/try-trait/try-as-monad.rs b/tests/ui/try-trait/try-as-monad.rs
new file mode 100644
index 000000000..cf09838b3
--- /dev/null
+++ b/tests/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/tests/ui/try-trait/try-on-option-diagnostics.rs b/tests/ui/try-trait/try-on-option-diagnostics.rs
new file mode 100644
index 000000000..7ffa0de6c
--- /dev/null
+++ b/tests/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/tests/ui/try-trait/try-on-option-diagnostics.stderr b/tests/ui/try-trait/try-on-option-diagnostics.stderr
new file mode 100644
index 000000000..9ee540c79
--- /dev/null
+++ b/tests/ui/try-trait/try-on-option-diagnostics.stderr
@@ -0,0 +1,47 @@
+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 {
+ | ---------------------- this function should return `Result` or `Option` to accept `?`
+LL | let x: Option<u32> = None;
+LL | x?;
+ | ^ cannot use the `?` operator in a function that returns `u32`
+ |
+ = 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 = || {
+ | -- this function should return `Result` or `Option` to accept `?`
+LL | let x: Option<u32> = None;
+LL | x?;
+ | ^ cannot use the `?` operator in a closure that returns `{integer}`
+ |
+ = 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() {
+ | ------------- this function should return `Result` or `Option` to accept `?`
+LL | let x: Option<u32> = None;
+LL | x?;
+ | ^ cannot use the `?` operator in a method that returns `()`
+ |
+ = 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() {
+ | ------------------- this function should return `Result` or `Option` to accept `?`
+LL | let x: Option<u32> = None;
+LL | x?;
+ | ^ cannot use the `?` operator in a trait method that returns `()`
+ |
+ = 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/tests/ui/try-trait/try-on-option.rs b/tests/ui/try-trait/try-on-option.rs
new file mode 100644
index 000000000..8519932a6
--- /dev/null
+++ b/tests/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/tests/ui/try-trait/try-on-option.stderr b/tests/ui/try-trait/try-on-option.stderr
new file mode 100644
index 000000000..fad6a1fe8
--- /dev/null
+++ b/tests/ui/try-trait/try-on-option.stderr
@@ -0,0 +1,28 @@
+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, ()> {
+ | --------------------------- this function returns a `Result`
+LL | let x: Option<u32> = None;
+LL | x?;
+ | ^ use `.ok_or(...)?` to provide an error compatible with `Result<u32, ()>`
+ |
+ = 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 {
+ | --------------- this function should return `Result` or `Option` to accept `?`
+LL | let x: Option<u32> = None;
+LL | x?;
+ | ^ cannot use the `?` operator in a function that returns `u32`
+ |
+ = 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/tests/ui/try-trait/try-operator-custom.rs b/tests/ui/try-trait/try-operator-custom.rs
new file mode 100644
index 000000000..45636a7fc
--- /dev/null
+++ b/tests/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/tests/ui/try-trait/try-operator-on-main.rs b/tests/ui/try-trait/try-operator-on-main.rs
new file mode 100644
index 000000000..3b364f7e7
--- /dev/null
+++ b/tests/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/tests/ui/try-trait/try-operator-on-main.stderr b/tests/ui/try-trait/try-operator-on-main.stderr
new file mode 100644
index 000000000..7cd38e0cf
--- /dev/null
+++ b/tests/ui/try-trait/try-operator-on-main.stderr
@@ -0,0 +1,53 @@
+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() {
+ | --------- this function should return `Result` or `Option` to accept `?`
+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 `()`
+ |
+ = 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() {
+ | --------- this function should return `Result` or `Option` to accept `?`
+...
+LL | ()?;
+ | ^ cannot use the `?` operator in a function that returns `()`
+ |
+ = 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/tests/ui/try-trait/try-poll.rs b/tests/ui/try-trait/try-poll.rs
new file mode 100644
index 000000000..d42e51c74
--- /dev/null
+++ b/tests/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/tests/ui/try-trait/yeet-for-option.rs b/tests/ui/try-trait/yeet-for-option.rs
new file mode 100644
index 000000000..753fbc1de
--- /dev/null
+++ b/tests/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/tests/ui/try-trait/yeet-for-result.rs b/tests/ui/try-trait/yeet-for-result.rs
new file mode 100644
index 000000000..b7b113797
--- /dev/null
+++ b/tests/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()));
+}