Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

result_tracing: error return tracing in core #1

Open
wants to merge 3 commits into
base: const-trait-specialize
Choose a base branch
from

Conversation

BGR360
Copy link
Owner

@BGR360 BGR360 commented Mar 29, 2022

What It Does

This PR enables users of Result to be notified of every invocation of the try operator (?) by implementing a new Trace trait on their error type. For any Result::<T, E>::Err(e) where E: Trace, invoking the try operator will call Trace::trace() on e and pass in the code location of the ? invocation.

So the following code example:

#![feature(result_tracing)]
#![feature(min_specialization)]

struct Error;

impl core::result::Trace for Error {
    fn trace(&mut self, location: &'static core::panic::Location<'static>) {
        println!("Tried me @ {location}!");
    }
}

fn foo () -> Result<(), Error> {
    Err(Error)?
}

fn main() {
    foo().ok();
}

Would produce the following output:

Tried me @ main.rs:11:15!

How It Does

  • Introduces a new trait core::result::Trace
  • Specializes FromResidual for Result<T, E> to behave differently when E: Trace.

Why It Does

The primary motivation for this is to enable low-overhead error return tracing, to borrow the term from the Zig language.

A decent argument for why return tracing is desirable over backtraces or other approaches can be found here.

Additional Context

There is a lengthy thread introducing the idea and cataloging its evolution on Zulip: track_caller error crate.

Blockers

@BGR360
Copy link
Owner Author

BGR360 commented Mar 29, 2022

Beep boop I am the CI, here are the UI test failures:

Test output
failures:

---- [ui] ui/inference/cannot-infer-closure-circular.rs stdout ----
diff of stderr:

-       error[E0282]: type annotations needed for `Result<(), E>`
-         --> $DIR/cannot-infer-closure-circular.rs:7:14
+       error[E0283]: type annotations needed
+         --> $DIR/cannot-infer-closure-circular.rs:9:17
3          |
-       LL |     let x = |r| {
-          |              ^ consider giving this closure parameter the explicit type `Result<(), E>`, where the type parameter `E` is specified
+       LL |         let v = r?;
+          |                 ^^ cannot infer type for enum `Result<(), _>`
+          |
+          = note: multiple `impl`s satisfying `Result<(), _>: FromResidual<Result<Infallible, _>>` found in the `core` crate:
+                  - impl<T, E, F> FromResidual<Result<Infallible, E>> for Result<T, F>
+                    where F: From<E>, F: Trace;
+                  - impl<T, E, F> FromResidual<Result<Infallible, E>> for Result<T, F>
+                    where F: From<E>;
6
7       error: aborting due to previous error
8

-       For more information about this error, try `rustc --explain E0282`.
+       For more information about this error, try `rustc --explain E0283`.
10


The actual stderr differed from the expected stderr.
Actual stderr saved to /Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/inference/cannot-infer-closure-circular/cannot-infer-closure-circular.stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args inference/cannot-infer-closure-circular.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/stage1/bin/rustc" "/Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/inference/cannot-infer-closure-circular.rs" "-Zthreads=1" "--target=aarch64-apple-darwin" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/inference/cannot-infer-closure-circular" "-A" "unused" "-Crpath" "-O" "-Cdebuginfo=0" "-Lnative=/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/native/rust-test-helpers" "-L" "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/inference/cannot-infer-closure-circular/auxiliary"
stdout: none
--- stderr -------------------------------
error[E0283]: type annotations needed
  --> /Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/inference/cannot-infer-closure-circular.rs:9:17
   |
LL |         let v = r?;
   |                 ^^ cannot infer type for enum `Result<(), _>`
   |
   = note: multiple `impl`s satisfying `Result<(), _>: FromResidual<Result<Infallible, _>>` found in the `core` crate:
           - impl<T, E, F> FromResidual<Result<Infallible, E>> for Result<T, F>
             where F: From<E>, F: Trace;
           - impl<T, E, F> FromResidual<Result<Infallible, E>> for Result<T, F>
             where F: From<E>;

error: aborting due to previous error

For more information about this error, try `rustc --explain E0283`.
------------------------------------------


---- [ui] ui/inference/cannot-infer-async.rs stdout ----
diff of stderr:

-       error[E0282]: type annotations needed
-         --> $DIR/cannot-infer-async.rs:13:9
+       error[E0283]: type annotations needed
+         --> $DIR/cannot-infer-async.rs:11:20
3          |
-       LL |     let fut = async {
-          |         --- consider giving `fut` a type
-       ...
-       LL |         Ok(())
-          |         ^^ cannot infer type for type parameter `E` declared on the enum `Result`
+       LL |         make_unit()?;
+          |                    ^ cannot infer type for enum `Result<(), _>`
+          |
+          = note: multiple `impl`s satisfying `Result<(), _>: FromResidual<Result<Infallible, std::io::Error>>` found in the `core` crate:
+                  - impl<T, E, F> FromResidual<Result<Infallible, E>> for Result<T, F>
+                    where F: From<E>, F: Trace;
+                  - impl<T, E, F> FromResidual<Result<Infallible, E>> for Result<T, F>
+                    where F: From<E>;
9
10      error: aborting due to previous error
11

-       For more information about this error, try `rustc --explain E0282`.
+       For more information about this error, try `rustc --explain E0283`.
13


The actual stderr differed from the expected stderr.
Actual stderr saved to /Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/inference/cannot-infer-async/cannot-infer-async.stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args inference/cannot-infer-async.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/stage1/bin/rustc" "/Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/inference/cannot-infer-async.rs" "-Zthreads=1" "--target=aarch64-apple-darwin" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/inference/cannot-infer-async" "-A" "unused" "-Crpath" "-O" "-Cdebuginfo=0" "-Lnative=/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/native/rust-test-helpers" "--edition=2018" "-L" "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/inference/cannot-infer-async/auxiliary"
stdout: none
--- stderr -------------------------------
error[E0283]: type annotations needed
  --> /Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/inference/cannot-infer-async.rs:11:20
   |
LL |         make_unit()?;
   |                    ^ cannot infer type for enum `Result<(), _>`
   |
   = note: multiple `impl`s satisfying `Result<(), _>: FromResidual<Result<Infallible, std::io::Error>>` found in the `core` crate:
           - impl<T, E, F> FromResidual<Result<Infallible, E>> for Result<T, F>
             where F: From<E>, F: Trace;
           - impl<T, E, F> FromResidual<Result<Infallible, E>> for Result<T, F>
             where F: From<E>;

error: aborting due to previous error

For more information about this error, try `rustc --explain E0283`.
------------------------------------------


---- [ui] ui/inference/cannot-infer-closure.rs stdout ----
diff of stderr:

-       error[E0282]: type annotations needed for the closure `fn((), ()) -> Result<(), _>`
-         --> $DIR/cannot-infer-closure.rs:4:9
+       error[E0283]: type annotations needed
+         --> $DIR/cannot-infer-closure.rs:3:15
3          |
-       LL |         Ok(b)
-          |         ^^ cannot infer type for type parameter `E` declared on the enum `Result`
+       LL |         Err(a)?;
+          |               ^ cannot infer type for enum `Result<(), _>`
6          |
-       help: give this closure an explicit return type without `_` placeholders
-          |
-       LL |     let x = |a: (), b: ()| -> Result<(), _> {
-          |                            ++++++++++++++++
+          = note: multiple `impl`s satisfying `Result<(), _>: FromResidual<Result<Infallible, ()>>` found in the `core` crate:
+                  - impl<T, E, F> FromResidual<Result<Infallible, E>> for Result<T, F>
+                    where F: From<E>, F: Trace;
+                  - impl<T, E, F> FromResidual<Result<Infallible, E>> for Result<T, F>
+                    where F: From<E>;
11
12      error: aborting due to previous error
13

-       For more information about this error, try `rustc --explain E0282`.
+       For more information about this error, try `rustc --explain E0283`.
15


The actual stderr differed from the expected stderr.
Actual stderr saved to /Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/inference/cannot-infer-closure/cannot-infer-closure.stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args inference/cannot-infer-closure.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/stage1/bin/rustc" "/Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/inference/cannot-infer-closure.rs" "-Zthreads=1" "--target=aarch64-apple-darwin" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/inference/cannot-infer-closure" "-A" "unused" "-Crpath" "-O" "-Cdebuginfo=0" "-Lnative=/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/native/rust-test-helpers" "-L" "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/inference/cannot-infer-closure/auxiliary"
stdout: none
--- stderr -------------------------------
error[E0283]: type annotations needed
  --> /Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/inference/cannot-infer-closure.rs:3:15
   |
LL |         Err(a)?;
   |               ^ cannot infer type for enum `Result<(), _>`
   |
   = note: multiple `impl`s satisfying `Result<(), _>: FromResidual<Result<Infallible, ()>>` found in the `core` crate:
           - impl<T, E, F> FromResidual<Result<Infallible, E>> for Result<T, F>
             where F: From<E>, F: Trace;
           - impl<T, E, F> FromResidual<Result<Infallible, E>> for Result<T, F>
             where F: From<E>;

error: aborting due to previous error

For more information about this error, try `rustc --explain E0283`.
------------------------------------------


---- [ui] ui/issues/issue-32709.rs stdout ----
diff of stderr:

-       error[E0277]: `?` couldn't convert the error to `()`
+       error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result`
2         --> $DIR/issue-32709.rs:4:11
3          |
-       LL | fn a() -> Result<i32, ()> {
-          |           --------------- expected `()` because of this
-       LL |     Err(5)?;
-          |           ^ the trait `From<{integer}>` is not implemented for `()`
+       LL | / fn a() -> Result<i32, ()> {
+       LL | |     Err(5)?;
+          | |           ^ this `?` produces `Result<Infallible, {integer}>`, which is incompatible with `Result<i32, ()>`
+       LL | |     Ok(1)
+       LL | | }
+          | |_- this function returns a `Result`
8          |
-          = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
-          = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, {integer}>>` for `Result<i32, ()>`
+          = help: the trait `FromResidual<Result<Infallible, {integer}>>` is not implemented for `Result<i32, ()>`
11
12      error: aborting due to previous error
13


The actual stderr differed from the expected stderr.
Actual stderr saved to /Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/issues/issue-32709/issue-32709.stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args issues/issue-32709.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/stage1/bin/rustc" "/Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/issues/issue-32709.rs" "-Zthreads=1" "--target=aarch64-apple-darwin" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/issues/issue-32709" "-A" "unused" "-Crpath" "-O" "-Cdebuginfo=0" "-Lnative=/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/native/rust-test-helpers" "-L" "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/issues/issue-32709/auxiliary"
stdout: none
--- stderr -------------------------------
error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result`
  --> /Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/issues/issue-32709.rs:4:11
   |
LL | / fn a() -> Result<i32, ()> {
LL | |     Err(5)?; //~ ERROR
   | |           ^ this `?` produces `Result<Infallible, {integer}>`, which is incompatible with `Result<i32, ()>`
LL | |     Ok(1)
LL | | }
   | |_- this function returns a `Result`
   |
   = help: the trait `FromResidual<Result<Infallible, {integer}>>` is not implemented for `Result<i32, ()>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
------------------------------------------


---- [ui] ui/try-block/try-block-bad-type.rs stdout ----
diff of stderr:

-       error[E0277]: `?` couldn't convert the error to `TryFromSliceError`
+       error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result`
2         --> $DIR/try-block-bad-type.rs:7:16
3          |
-       LL |         Err("")?;
-          |                ^ the trait `From<&str>` is not implemented for `TryFromSliceError`
+       LL | / pub fn main() {
+       LL | |     let res: Result<u32, std::array::TryFromSliceError> = try {
+       LL | |         Err("")?;
+          | |                ^ this `?` produces `Result<Infallible, &str>`, which is incompatible with `Result<u32, TryFromSliceError>`
+       LL | |         5
+       ...  |
+       LL | |     let res: i32 = try { 5 };
+       LL | | }
+          | |_- this function returns a `Result`
6          |
-          = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
-          = help: the following implementations were found:
-                    <TryFromSliceError as From<Infallible>>
-          = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, &str>>` for `Result<u32, TryFromSliceError>`
+          = help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `Result<u32, TryFromSliceError>`
11
12      error[E0271]: type mismatch resolving `<Result<i32, i32> as Try>::Output == &str`
13        --> $DIR/try-block-bad-type.rs:12:9


The actual stderr differed from the expected stderr.
Actual stderr saved to /Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/try-block/try-block-bad-type/try-block-bad-type.stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args try-block/try-block-bad-type.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/stage1/bin/rustc" "/Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/try-block/try-block-bad-type.rs" "-Zthreads=1" "--target=aarch64-apple-darwin" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/try-block/try-block-bad-type" "-A" "unused" "-Crpath" "-O" "-Cdebuginfo=0" "-Lnative=/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/native/rust-test-helpers" "--edition" "2018" "-L" "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/try-block/try-block-bad-type/auxiliary"
stdout: none
--- stderr -------------------------------
error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result`
  --> /Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/try-block/try-block-bad-type.rs:7:16
   |
LL | / pub fn main() {
LL | |     let res: Result<u32, std::array::TryFromSliceError> = try {
LL | |         Err("")?; //~ ERROR `?` couldn't convert the error
   | |                ^ this `?` produces `Result<Infallible, &str>`, which is incompatible with `Result<u32, TryFromSliceError>`
LL | |         5
...  |
LL | |     let res: i32 = try { 5 }; //~ ERROR a `try` block must return `Result` or `Option`
LL | | }
   | |_- this function returns a `Result`
   |
   = help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `Result<u32, TryFromSliceError>`

error[E0271]: type mismatch resolving `<Result<i32, i32> as Try>::Output == &str`
  --> /Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/try-block/try-block-bad-type.rs:12:9
   |
LL |         "" //~ ERROR type mismatch
   |         ^^ expected `i32`, found `&str`

error[E0271]: type mismatch resolving `<Result<i32, i32> as Try>::Output == ()`
  --> /Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/try-block/try-block-bad-type.rs:15:39
   |
LL |     let res: Result<i32, i32> = try { }; //~ ERROR type mismatch
   |                                       ^ expected `i32`, found `()`

error[E0277]: a `try` block must return `Result` or `Option` (or another type that implements `Try`)
  --> /Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/try-block/try-block-bad-type.rs:17:25
   |
LL |     let res: () = try { };
   |                         ^ could not wrap the final value of the block as `()` doesn't implement `Try`
   |
   = help: the trait `Try` is not implemented for `()`

error[E0277]: a `try` block must return `Result` or `Option` (or another type that implements `Try`)
  --> /Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/try-block/try-block-bad-type.rs:20:26
   |
LL |     let res: i32 = try { 5 }; //~ ERROR a `try` block must return `Result` or `Option`
   |                          ^ could not wrap the final value of the block as `i32` doesn't implement `Try`
   |
   = help: the trait `Try` is not implemented for `i32`

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0271, E0277.
For more information about an error, try `rustc --explain E0271`.
------------------------------------------


---- [ui] ui/try-trait/bad-interconversion.rs stdout ----
diff of stderr:

-       error[E0277]: `?` couldn't convert the error to `u8`
+       error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result`
2         --> $DIR/bad-interconversion.rs:6:20
3          |
-       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`
+       LL | / fn result_to_result() -> Result<u64, u8> {
+       LL | |     Ok(Err(123_i32)?)
+          | |                    ^ this `?` produces `Result<Infallible, i32>`, which is incompatible with `Result<u64, u8>`
+       LL | |
+       LL | | }
+          | |_- this function returns a `Result`
8          |
-          = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
-          = help: the following implementations were found:
-                    <u8 as From<NonZeroU8>>
-                    <u8 as From<bool>>
-                    <f32 as From<i16>>
-                    <f32 as From<i8>>
-                  and 71 others
-          = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, i32>>` for `Result<u64, u8>`
+          = help: the trait `FromResidual<Result<Infallible, i32>>` is not implemented for `Result<u64, u8>`
17
18      error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`
19        --> $DIR/bad-interconversion.rs:11:12


The actual stderr differed from the expected stderr.
Actual stderr saved to /Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/try-trait/bad-interconversion/bad-interconversion.stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args try-trait/bad-interconversion.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/stage1/bin/rustc" "/Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/try-trait/bad-interconversion.rs" "-Zthreads=1" "--target=aarch64-apple-darwin" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/try-trait/bad-interconversion" "-A" "unused" "-Crpath" "-O" "-Cdebuginfo=0" "-Lnative=/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/native/rust-test-helpers" "-L" "/Users/ben/Documents/Rust/rust-lang/rust/build/aarch64-apple-darwin/test/ui/try-trait/bad-interconversion/auxiliary"
stdout: none
--- stderr -------------------------------
error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result`
  --> /Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/try-trait/bad-interconversion.rs:6:20
   |
LL | / fn result_to_result() -> Result<u64, u8> {
LL | |     Ok(Err(123_i32)?)
   | |                    ^ this `?` produces `Result<Infallible, i32>`, which is incompatible with `Result<u64, u8>`
LL | |     //~^ ERROR `?` couldn't convert the error to `u8`
LL | | }
   | |_- this function returns a `Result`
   |
   = help: the trait `FromResidual<Result<Infallible, i32>>` is not implemented for `Result<u64, u8>`

error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`
  --> /Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/try-trait/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 | |     //~^ ERROR the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`
LL | |     Ok(10)
LL | | }
   | |_- this function returns a `Result`
   |
   = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<u64, String>`

error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result`
  --> /Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/try-trait/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 | |     //~^ ERROR the `?` operator can only be used on `Result`s in a function that returns `Result`
LL | | }
   | |_- this function returns a `Result`
   |
   = help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Result<u64, String>`

error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option`
  --> /Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/try-trait/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 | |     //~^ ERROR the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option`
LL | | }
   | |_- this function returns an `Option`
   |
   = help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `Option<u16>`

error[E0277]: the `?` operator can only be used on `Option`s in a function that returns `Option`
  --> /Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/try-trait/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 | |     //~^ ERROR the `?` operator can only be used on `Option`s in a function that returns `Option`
LL | | }
   | |_- this function returns an `Option`
   |
   = help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Option<u64>`

error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
  --> /Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/try-trait/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 | |     //~^ ERROR the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
LL | | }
   | |_- this function returns a `ControlFlow`
   |
   = help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `ControlFlow<String>`

error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
  --> /Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/try-trait/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 | |     //~^ ERROR the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
LL | |     ControlFlow::Break(10)
LL | | }
   | |_- this function returns a `ControlFlow`
   |
   = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `ControlFlow<u64>`

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)
  --> /Users/ben/Documents/Rust/rust-lang/rust/src/test/ui/try-trait/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 | |     //~^ ERROR the `?` operator in a function that returns `ControlFlow<B, _>` can only be used on other `ControlFlow<B, _>`s
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`

error: aborting due to 8 previous errors

For more information about this error, try `rustc --explain E0277`.
------------------------------------------



failures:
    [ui] ui/inference/cannot-infer-async.rs
    [ui] ui/inference/cannot-infer-closure-circular.rs
    [ui] ui/inference/cannot-infer-closure.rs
    [ui] ui/issues/issue-32709.rs
    [ui] ui/try-block/try-block-bad-type.rs
    [ui] ui/try-trait/bad-interconversion.rs

test result: FAILED. 12592 passed; 6 failed; 171 ignored; 0 measured; 0 filtered out; finished in 128.58s

}

#[test]
fn try_operator_calls_trace() {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: add const equivalent of this test

Comment on lines +2111 to +2113
// FIXME(bgr360): how to properly add this change that depends on compiler
// functionality that's not yet in the beta?
#[cfg(not(bootstrap))]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you did it right. The release team has a whole process for how they remove cfg(bootstrap) directives

https://forge.rust-lang.org/release/process.html?highlight=bootstrap#master-bootstrap-update-t-2-day-tuesday

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok dope

@BGR360 BGR360 force-pushed the const-trait-specialize branch from d912178 to 92cb72b Compare September 11, 2022 22:06
@BGR360 BGR360 force-pushed the const-trait-specialize branch 2 times, most recently from f380b39 to fe53cac Compare November 10, 2022 18:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants