Rollup merge of #128954 - zachs18:fromresidual-no-default, r=scottmcm

Explicitly specify type parameter on FromResidual for Option and ControlFlow.

~~Remove type parameter default `R = <Self as Try>::Residual` from `FromResidual`~~ _Specify default type parameter on `FromResidual` impls in the stdlib_ to work around https://github.com/rust-lang/rust/issues/99940 / https://github.com/rust-lang/rust/issues/87350 ~~as mentioned in https://github.com/rust-lang/rust/issues/84277#issuecomment-1773259264~~.

This does not completely fix the issue, but works around it for `Option` and `ControlFlow` specifically (`Result` does not have the issue since it already did not use the default parameter of `FromResidual`).

~~(Does this need an ACP or similar?)~~ ~~This probably needs at least an FCP since it changes the API described in [the RFC](https://github.com/rust-lang/rfcs/pull/3058). Not sure if T-lang, T-libs-api, T-libs, or some combination (The tracking issue is tagged T-lang, T-libs-api).~~ This probably doesn't need T-lang input, since it is not changing the API of `FromResidual` from the RFC? Maybe needs T-libs-api FCP?
This commit is contained in:
许杰友 Jieyou Xu (Joe) 2024-08-14 21:43:08 +08:00 committed by GitHub
commit 049b3e549e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 36 additions and 5 deletions

View File

@ -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 {

View File

@ -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 {

View File

@ -1,4 +1,5 @@
mod control_flow;
mod from_residual;
use core::ops::{
Bound, Deref, DerefMut, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive,

View File

@ -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!()
}
}

View File

@ -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
@ -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

View File

@ -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