Skip to content

Commit 3fca10d

Browse files
authored
Unrolled build for rust-lang#128954
Rollup merge of rust-lang#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 rust-lang#99940 / rust-lang#87350 ~~as mentioned in rust-lang#84277 (comment). 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](rust-lang/rfcs#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?
2 parents 0f442e2 + 1b6df71 commit 3fca10d

File tree

6 files changed

+36
-5
lines changed

6 files changed

+36
-5
lines changed

library/core/src/ops/control_flow.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@ impl<B, C> ops::Try for ControlFlow<B, C> {
116116
}
117117

118118
#[unstable(feature = "try_trait_v2", issue = "84277")]
119-
impl<B, C> ops::FromResidual for ControlFlow<B, C> {
119+
// Note: manually specifying the residual type instead of using the default to work around
120+
// https://github.com/rust-lang/rust/issues/99940
121+
impl<B, C> ops::FromResidual<ControlFlow<B, convert::Infallible>> for ControlFlow<B, C> {
120122
#[inline]
121123
fn from_residual(residual: ControlFlow<B, convert::Infallible>) -> Self {
122124
match residual {

library/core/src/option.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -2495,7 +2495,9 @@ impl<T> ops::Try for Option<T> {
24952495
}
24962496

24972497
#[unstable(feature = "try_trait_v2", issue = "84277")]
2498-
impl<T> ops::FromResidual for Option<T> {
2498+
// Note: manually specifying the residual type instead of using the default to work around
2499+
// https://github.com/rust-lang/rust/issues/99940
2500+
impl<T> ops::FromResidual<Option<convert::Infallible>> for Option<T> {
24992501
#[inline]
25002502
fn from_residual(residual: Option<convert::Infallible>) -> Self {
25012503
match residual {

library/core/tests/ops.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod control_flow;
2+
mod from_residual;
23

34
use core::ops::{
45
Bound, Deref, DerefMut, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive,
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//! Regression test that Option and ControlFlow can have downstream FromResidual impls.
2+
//! cc https://github.com/rust-lang/rust/issues/99940,
3+
//! This does NOT test that issue in general; Option and ControlFlow's FromResidual
4+
//! impls in core were changed to not be affected by that issue.
5+
6+
use core::ops::{ControlFlow, FromResidual};
7+
8+
struct Local;
9+
10+
impl<T> FromResidual<Local> for Option<T> {
11+
fn from_residual(_: Local) -> Option<T> {
12+
unimplemented!()
13+
}
14+
}
15+
16+
impl<B, C> FromResidual<Local> for ControlFlow<B, C> {
17+
fn from_residual(_: Local) -> ControlFlow<B, C> {
18+
unimplemented!()
19+
}
20+
}
21+
22+
impl<T, E> FromResidual<Local> for Result<T, E> {
23+
fn from_residual(_: Local) -> Result<T, E> {
24+
unimplemented!()
25+
}
26+
}

tests/ui/try-trait/bad-interconversion.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ LL | Some(Err("hello")?)
4545
| ^ use `.ok()?` if you want to discard the `Result<Infallible, &str>` error information
4646
|
4747
= help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `Option<u16>`
48-
= help: the trait `FromResidual` is implemented for `Option<T>`
48+
= help: the trait `FromResidual<Option<Infallible>>` is implemented for `Option<T>`
4949

5050
error[E0277]: the `?` operator can only be used on `Option`s in a function that returns `Option`
5151
--> $DIR/bad-interconversion.rs:27:33
@@ -56,7 +56,7 @@ LL | Some(ControlFlow::Break(123)?)
5656
| ^ this `?` produces `ControlFlow<{integer}, Infallible>`, which is incompatible with `Option<u64>`
5757
|
5858
= help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Option<u64>`
59-
= help: the trait `FromResidual` is implemented for `Option<T>`
59+
= help: the trait `FromResidual<Option<Infallible>>` is implemented for `Option<T>`
6060

6161
error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
6262
--> $DIR/bad-interconversion.rs:32:39

tests/ui/try-trait/option-to-result.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ LL | a?;
2020
| ^ use `.ok()?` if you want to discard the `Result<Infallible, i32>` error information
2121
|
2222
= help: the trait `FromResidual<Result<Infallible, i32>>` is not implemented for `Option<i32>`
23-
= help: the trait `FromResidual` is implemented for `Option<T>`
23+
= help: the trait `FromResidual<Option<Infallible>>` is implemented for `Option<T>`
2424

2525
error: aborting due to 2 previous errors
2626

0 commit comments

Comments
 (0)