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

Explicitly specify type parameter on FromResidual for Option and ControlFlow. #128954

Merged
merged 1 commit into from
Aug 14, 2024
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
Loading