Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion library/core/src/ops/control_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ impl<B, C> ops::Try for ControlFlow<B, C> {
}

#[unstable(feature = "try_trait_v2", issue = "84277")]
impl<B, C> ops::FromResidual for ControlFlow<B, C> {
// Note: manually specifying the residual type instead of using the default to work around
// https://github.com/rust-lang/rust/issues/99940
impl<B, C> ops::FromResidual<ControlFlow<B, convert::Infallible>> for ControlFlow<B, C> {
#[inline]
fn from_residual(residual: ControlFlow<B, convert::Infallible>) -> Self {
match residual {
Expand Down
4 changes: 3 additions & 1 deletion library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2495,7 +2495,9 @@ impl<T> ops::Try for Option<T> {
}

#[unstable(feature = "try_trait_v2", issue = "84277")]
impl<T> ops::FromResidual for Option<T> {
// Note: manually specifying the residual type instead of using the default to work around
// https://github.com/rust-lang/rust/issues/99940
impl<T> ops::FromResidual<Option<convert::Infallible>> for Option<T> {
#[inline]
fn from_residual(residual: Option<convert::Infallible>) -> Self {
match residual {
Expand Down
1 change: 1 addition & 0 deletions library/core/tests/ops.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod control_flow;
mod from_residual;

use core::ops::{
Bound, Deref, DerefMut, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive,
Expand Down
26 changes: 26 additions & 0 deletions library/core/tests/ops/from_residual.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//! Regression test that Option and ControlFlow can have downstream FromResidual impls.
//! cc https://github.com/rust-lang/rust/issues/99940,
//! This does NOT test that issue in general; Option and ControlFlow's FromResidual
//! impls in core were changed to not be affected by that issue.

use core::ops::{ControlFlow, FromResidual};

struct Local;

impl<T> FromResidual<Local> for Option<T> {
fn from_residual(_: Local) -> Option<T> {
unimplemented!()
}
}

impl<B, C> FromResidual<Local> for ControlFlow<B, C> {
fn from_residual(_: Local) -> ControlFlow<B, C> {
unimplemented!()
}
}

impl<T, E> FromResidual<Local> for Result<T, E> {
fn from_residual(_: Local) -> Result<T, E> {
unimplemented!()
}
}
4 changes: 2 additions & 2 deletions tests/ui/try-trait/bad-interconversion.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ 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 trait `FromResidual` is implemented for `Option<T>`
= help: the trait `FromResidual<Option<Infallible>>` is implemented for `Option<T>`

error[E0277]: the `?` operator can only be used on `Option`s in a function that returns `Option`
--> $DIR/bad-interconversion.rs:27:33
Expand All @@ -56,7 +56,7 @@ 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 trait `FromResidual` is implemented for `Option<T>`
= help: the trait `FromResidual<Option<Infallible>>` is implemented for `Option<T>`

error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
--> $DIR/bad-interconversion.rs:32:39
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/try-trait/option-to-result.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ 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 trait `FromResidual` is implemented for `Option<T>`
= help: the trait `FromResidual<Option<Infallible>>` is implemented for `Option<T>`

error: aborting due to 2 previous errors

Expand Down