Skip to content

Commit 74f9771

Browse files
committed
Simplify the approach
- Make the non-generic trait be the subtrait, for simplicity - Move `BreakHolder` to future work (not required for just `?`/`try {}`)
1 parent 53db8a8 commit 74f9771

36 files changed

+383
-273
lines changed

library/core/src/iter/adapters/peekable.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,9 @@ where
164164
Some(None) => try { init },
165165
Some(Some(v)) => match self.iter.try_rfold(init, &mut f).branch() {
166166
ControlFlow::Continue(acc) => f(acc, v),
167-
ControlFlow::Break(h) => {
167+
ControlFlow::Break(r) => {
168168
self.peeked = Some(Some(v));
169-
R::from_holder(h)
169+
R::from_residual(r)
170170
}
171171
},
172172
None => self.iter.try_rfold(init, f),

library/core/src/iter/traits/iterator.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use crate::cmp::{self, Ordering};
66
use crate::ops::{self, Add, ControlFlow, Try};
7+
#[cfg(not(bootstrap))]
8+
use crate::ops::FromTryResidual;
79

810
use super::super::TrustedRandomAccess;
911
use super::super::{Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse};
@@ -2439,30 +2441,30 @@ pub trait Iterator {
24392441
fn try_find<F, R>(
24402442
&mut self,
24412443
f: F,
2442-
) -> <R::Holder as ops::BreakHolder<Option<Self::Item>>>::Output
2444+
) -> <R::Residual as ops::GetCorrespondingTryType<Option<Self::Item>>>::Output
24432445
where
24442446
Self: Sized,
24452447
F: FnMut(&Self::Item) -> R,
24462448
R: ops::Try<Ok = bool>,
2447-
R::Holder: ops::BreakHolder<Option<Self::Item>>,
2449+
R::Residual: ops::GetCorrespondingTryType<Option<Self::Item>>,
24482450
{
24492451
#[inline]
2450-
fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> ControlFlow<Result<T, R::Holder>>
2452+
fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> ControlFlow<Result<T, R::Residual>>
24512453
where
24522454
F: FnMut(&T) -> R,
24532455
R: Try<Ok = bool>,
24542456
{
24552457
move |(), x| match f(&x).branch() {
24562458
ControlFlow::Continue(false) => ControlFlow::CONTINUE,
24572459
ControlFlow::Continue(true) => ControlFlow::Break(Ok(x)),
2458-
ControlFlow::Break(h) => ControlFlow::Break(Err(h)),
2460+
ControlFlow::Break(r) => ControlFlow::Break(Err(r)),
24592461
}
24602462
}
24612463

24622464
match self.try_fold((), check(f)) {
2463-
ControlFlow::Continue(()) => ops::Bubble::continue_with(None),
2464-
ControlFlow::Break(Ok(x)) => ops::Bubble::continue_with(Some(x)),
2465-
ControlFlow::Break(Err(h)) => Try::from_holder(h),
2465+
ControlFlow::Continue(()) => Try::from_output(None),
2466+
ControlFlow::Break(Ok(x)) => Try::from_output(Some(x)),
2467+
ControlFlow::Break(Err(r)) => <_>::from_residual(r),
24662468
}
24672469
}
24682470

library/core/src/ops/control_flow.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,18 @@ impl<B, C> ops::Try2015 for ControlFlow<B, C> {
8484
}
8585

8686
#[unstable(feature = "try_trait_v2", issue = "42327")]
87-
impl<B, C> ops::Bubble for ControlFlow<B, C> {
88-
//type Continue = C;
87+
impl<B, C> ops::Try2021 for ControlFlow<B, C> {
88+
//type Output = C;
8989
type Ok = C;
90-
type Holder = ControlFlow<B, !>;
90+
type Residual = ControlFlow<B, !>;
91+
9192
#[inline]
92-
fn continue_with(c: C) -> Self {
93+
fn from_output(c: C) -> Self {
9394
ControlFlow::Continue(c)
9495
}
96+
9597
#[inline]
96-
fn branch(self) -> ControlFlow<Self::Holder, C> {
98+
fn branch(self) -> ControlFlow<Self::Residual, C> {
9799
match self {
98100
ControlFlow::Continue(c) => ControlFlow::Continue(c),
99101
ControlFlow::Break(b) => ControlFlow::Break(ControlFlow::Break(b)),
@@ -102,7 +104,7 @@ impl<B, C> ops::Bubble for ControlFlow<B, C> {
102104
}
103105

104106
#[unstable(feature = "try_trait_v2", issue = "42327")]
105-
impl<C, B> ops::BreakHolder<C> for ControlFlow<B, !> {
107+
impl<C, B> ops::GetCorrespondingTryType<C> for ControlFlow<B, !> {
106108
type Output = ControlFlow<B, C>;
107109
// fn expand(x: Self) -> Self::Output {
108110
// match x {
@@ -112,10 +114,10 @@ impl<C, B> ops::BreakHolder<C> for ControlFlow<B, !> {
112114
}
113115

114116
#[unstable(feature = "try_trait_v2", issue = "42327")]
115-
impl<B, C> ops::Try2021 for ControlFlow<B, C> {
116-
fn from_holder(x: Self::Holder) -> Self {
117+
impl<B, C> ops::FromTryResidual for ControlFlow<B, C> {
118+
fn from_residual(x: <Self as ops::Try2021>::Residual) -> Self {
117119
match x {
118-
ControlFlow::Break(b) => ControlFlow::Break(b),
120+
ControlFlow::Break(r) => ControlFlow::Break(r),
119121
}
120122
}
121123
}
@@ -222,7 +224,7 @@ impl<R: Try> ControlFlow<R, R::Ok> {
222224
pub fn from_try(r: R) -> Self {
223225
match r.branch() {
224226
ControlFlow::Continue(v) => ControlFlow::Continue(v),
225-
ControlFlow::Break(h) => ControlFlow::Break(R::from_holder(h)),
227+
ControlFlow::Break(r) => ControlFlow::Break(R::from_residual(r)),
226228
}
227229
}
228230

@@ -231,7 +233,7 @@ impl<R: Try> ControlFlow<R, R::Ok> {
231233
#[inline]
232234
pub fn into_try(self) -> R {
233235
match self {
234-
ControlFlow::Continue(v) => R::continue_with(v),
236+
ControlFlow::Continue(v) => R::from_output(v),
235237
ControlFlow::Break(v) => v,
236238
}
237239
}

library/core/src/ops/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ pub use self::range::{Bound, RangeBounds, RangeInclusive, RangeToInclusive};
185185
pub use self::r#try::Try2015;
186186

187187
#[unstable(feature = "try_trait_v2", issue = "42327")]
188-
pub use self::r#try::{BreakHolder, Try2021, Bubble};
188+
pub use self::r#try::{GetCorrespondingTryType, FromTryResidual, Try2021};
189189

190190
#[cfg(bootstrap)]
191191
#[unstable(feature = "try_trait_v2", issue = "42327")]

library/core/src/ops/try.rs

Lines changed: 26 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -73,96 +73,82 @@ pub trait Try2015 {
7373
all(from_method = "continue_with", from_desugaring = "QuestionMark"),
7474
message = "the `?` operator can only be used in {ItemContext} \
7575
that returns `Result` or `Option` \
76-
(or another type that implements `{Bubble}`)",
76+
(or another type that implements `{Try2021}`)",
7777
label = "cannot use the `?` operator in {ItemContext} that returns `{Self}`",
7878
enclosing_scope = "this function should return `Result` or `Option` to accept `?`"
7979
),
8080
on(
8181
all(from_method = "branch", from_desugaring = "QuestionMark"),
8282
message = "the `?` operator can only be applied to values \
83-
that implement `{Bubble}`",
83+
that implement `{Try2021}`",
8484
label = "the `?` operator cannot be applied to type `{Self}`"
8585
)
8686
)]
8787
#[unstable(feature = "try_trait_v2", issue = "42327")]
88-
pub trait Bubble {
88+
pub trait Try2021: FromTryResidual {
8989
/// The type of the value consumed or produced when not short-circuiting.
9090
#[unstable(feature = "try_trait_v2", issue = "42327")]
9191
// Temporarily using `Ok` still so I don't need to change the bounds in the library
92-
//type Continue;
92+
//type Output;
9393
type Ok;
9494

9595
/// A type that "colours" the short-circuit value so it can stay associated
9696
/// with the type constructor from which it came.
9797
#[unstable(feature = "try_trait_v2", issue = "42327")]
98-
// This could have required that we can get back here via the holder,
99-
// but that means that every type needs a distinct holder. It was removed
100-
// so that the Poll impls can use Result's Holder.
101-
//type Holder: BreakHolder<Self::Continue, Output = Self>;
102-
type Holder: BreakHolder<Self::Ok>;
98+
type Residual;
10399

104100
/// Used in `try{}` blocks to wrap the result of the block.
105101
#[cfg_attr(not(bootstrap), lang = "continue_with")]
106102
#[unstable(feature = "try_trait_v2", issue = "42327")]
107-
fn continue_with(x: Self::Ok) -> Self;
103+
fn from_output(x: Self::Ok) -> Self;
108104

109105
/// Determine whether to short-circuit (by returning `ControlFlow::Break`)
110106
/// or continue executing (by returning `ControlFlow::Continue`).
111107
#[cfg_attr(not(bootstrap), lang = "branch")]
112108
#[unstable(feature = "try_trait_v2", issue = "42327")]
113-
fn branch(self) -> ControlFlow<Self::Holder, Self::Ok>;
109+
fn branch(self) -> ControlFlow<Self::Residual, Self::Ok>;
114110

115111
/// Demonstration that this is usable for different-return-type scenarios (like `Iterator::try_find`).
116112
#[unstable(feature = "try_trait_v2", issue = "42327")]
117-
fn map<T>(self, f: impl FnOnce(Self::Ok) -> T) -> <Self::Holder as BreakHolder<T>>::Output
113+
fn map<T>(self, f: impl FnOnce(Self::Ok) -> T) -> <Self::Residual as GetCorrespondingTryType<T>>::Output
118114
where
119115
Self: Try2021,
120-
Self::Holder: BreakHolder<T>,
116+
Self::Residual: GetCorrespondingTryType<T>,
121117
{
122-
match Bubble::branch(self) {
123-
ControlFlow::Continue(c) => Bubble::continue_with(f(c)),
124-
//ControlFlow::Break(h) => BreakHolder::<T>::expand(h),
125-
ControlFlow::Break(h) => Try2021::from_holder(h),
118+
match self.branch() {
119+
ControlFlow::Continue(c) => Try2021::from_output(f(c)),
120+
ControlFlow::Break(r) => FromTryResidual::from_residual(r),
126121
}
127122
}
128123
}
129124

130-
/// The bound on a `<T as Try>::Holder` type that allows getting back to the original.
131-
#[unstable(feature = "try_trait_v2", issue = "42327")]
132-
pub trait BreakHolder<T>: Sized {
133-
/// The type from the original type constructor that also has this holder type,
134-
/// but has the specified Continue type.
135-
#[unstable(feature = "try_trait_v2", issue = "42327")]
136-
type Output: Try2021<Ok = T, Holder = Self>;
137-
138-
/* Superfluous now that `FromHolder` exists
139-
/// Rebuild the associated `impl Try` type from this holder.
140-
#[unstable(feature = "try_trait_v2", issue = "42327")]
141-
fn expand(x: Self) -> Self::Output;
142-
*/
143-
}
144-
145125
/// Allows you to pick with other types can be converted into your `Try` type.
146126
///
147127
/// With the default type argument, this functions as a bound for a "normal"
148128
/// `Try` type: one that can be split apart and put back together in either way.
149129
///
150130
/// For more complicated scenarios you'll likely need to bound on more than just this.
151131
#[rustc_on_unimplemented(on(
152-
all(from_method = "from_holder", from_desugaring = "QuestionMark"),
132+
all(from_method = "from_residual", from_desugaring = "QuestionMark"),
153133
message = "the `?` operator can only be used in {ItemContext} \
154134
that returns `Result` or `Option` \
155-
(or another type that implements `{Try2021}`)",
135+
(or another type that implements `{FromTryResidual}`)",
156136
label = "cannot use the `?` operator in {ItemContext} that returns `{Self}`",
157137
enclosing_scope = "this function should return `Result` or `Option` to accept `?`"
158138
))]
159139
#[unstable(feature = "try_trait_v2", issue = "42327")]
160-
pub trait Try2021<T = <Self as Bubble>::Holder>: Bubble
161-
where
162-
T: BreakHolder<Self::Ok>,
163-
{
164-
/// Perform conversion on this holder
140+
pub trait FromTryResidual<Residual = <Self as Try2021>::Residual> {
141+
/// Recreate the `Try` type from a related residual
165142
#[cfg_attr(not(bootstrap), lang = "from_holder")]
166143
#[unstable(feature = "try_trait_v2", issue = "42327")]
167-
fn from_holder(x: T) -> Self;
144+
fn from_residual(x: Residual) -> Self;
145+
}
146+
147+
/// The bound on a `<T as Try>::Residual` type that allows getting back to the original.
148+
#[unstable(feature = "try_trait_v2", issue = "42327")]
149+
pub trait GetCorrespondingTryType<TryOutputType>: Sized {
150+
/// The type from the original type constructor that also has this residual type,
151+
/// but has the specified Output type.
152+
#[unstable(feature = "try_trait_v2", issue = "42327")]
153+
type Output: Try2021<Ok = TryOutputType, Residual = Self>;
168154
}

library/core/src/option.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,18 +1724,18 @@ impl<T> ops::Try2015 for Option<T> {
17241724
}
17251725

17261726
#[unstable(feature = "try_trait_v2", issue = "42327")]
1727-
impl<T> ops::Bubble for Option<T> {
1728-
//type Continue = T;
1727+
impl<T> ops::Try2021 for Option<T> {
1728+
//type Output = T;
17291729
type Ok = T;
1730-
type Holder = Option<!>;
1730+
type Residual = Option<!>;
17311731

17321732
#[inline]
1733-
fn continue_with(c: T) -> Self {
1733+
fn from_output(c: T) -> Self {
17341734
Some(c)
17351735
}
17361736

17371737
#[inline]
1738-
fn branch(self) -> ControlFlow<Self::Holder, T> {
1738+
fn branch(self) -> ControlFlow<Self::Residual, T> {
17391739
match self {
17401740
Some(c) => ControlFlow::Continue(c),
17411741
None => ControlFlow::Break(None),
@@ -1744,7 +1744,7 @@ impl<T> ops::Bubble for Option<T> {
17441744
}
17451745

17461746
#[unstable(feature = "try_trait_v2", issue = "42327")]
1747-
impl<T> ops::BreakHolder<T> for Option<!> {
1747+
impl<T> ops::GetCorrespondingTryType<T> for Option<!> {
17481748
type Output = Option<T>;
17491749

17501750
// fn expand(x: Self) -> Self::Output {
@@ -1755,8 +1755,8 @@ impl<T> ops::BreakHolder<T> for Option<!> {
17551755
}
17561756

17571757
#[unstable(feature = "try_trait_v2", issue = "42327")]
1758-
impl<T> ops::Try2021<Option<!>> for Option<T> {
1759-
fn from_holder(x: Self::Holder) -> Self {
1758+
impl<T> ops::FromTryResidual for Option<T> {
1759+
fn from_residual(x: <Self as ops::Try2021>::Residual) -> Self {
17601760
match x {
17611761
None => None,
17621762
}

library/core/src/result.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,18 +1612,18 @@ impl<T, E> ops::Try2015 for Result<T, E> {
16121612
}
16131613

16141614
#[unstable(feature = "try_trait_v2", issue = "42327")]
1615-
impl<T, E> ops::Bubble for Result<T, E> {
1616-
//type Continue = T;
1615+
impl<T, E> ops::Try2021 for Result<T, E> {
1616+
//type Output = T;
16171617
type Ok = T;
1618-
type Holder = Result<!, E>;
1618+
type Residual = Result<!, E>;
16191619

16201620
#[inline]
1621-
fn continue_with(c: T) -> Self {
1621+
fn from_output(c: T) -> Self {
16221622
Ok(c)
16231623
}
16241624

16251625
#[inline]
1626-
fn branch(self) -> ControlFlow<Self::Holder, T> {
1626+
fn branch(self) -> ControlFlow<Self::Residual, T> {
16271627
match self {
16281628
Ok(c) => ControlFlow::Continue(c),
16291629
Err(e) => ControlFlow::Break(Err(e)),
@@ -1632,7 +1632,7 @@ impl<T, E> ops::Bubble for Result<T, E> {
16321632
}
16331633

16341634
#[unstable(feature = "try_trait_v2", issue = "42327")]
1635-
impl<T, E> ops::BreakHolder<T> for Result<!, E> {
1635+
impl<T, E> ops::GetCorrespondingTryType<T> for Result<!, E> {
16361636
type Output = Result<T, E>;
16371637

16381638
// fn expand(x: Self) -> Self::Output {
@@ -1643,8 +1643,8 @@ impl<T, E> ops::BreakHolder<T> for Result<!, E> {
16431643
}
16441644

16451645
#[unstable(feature = "try_trait_v2", issue = "42327")]
1646-
impl<T, E, F: From<E>> ops::Try2021<Result<!, E>> for Result<T, F> {
1647-
fn from_holder(x: Result<!, E>) -> Self {
1646+
impl<T, E, F: From<E>> ops::FromTryResidual<Result<!, E>> for Result<T, F> {
1647+
fn from_residual(x: Result<!, E>) -> Self {
16481648
match x {
16491649
Err(e) => Err(From::from(e)),
16501650
}
@@ -1662,11 +1662,11 @@ mod sadness {
16621662
pub struct PleaseCallTheOkOrMethodToUseQuestionMarkOnOptionsInAMethodThatReturnsResult;
16631663

16641664
#[unstable(feature = "try_trait_v2", issue = "42327")]
1665-
impl<T, E> ops::Try2021<Option<!>> for Result<T, E>
1665+
impl<T, E> ops::FromTryResidual<Option<!>> for Result<T, E>
16661666
where
16671667
E: From<PleaseCallTheOkOrMethodToUseQuestionMarkOnOptionsInAMethodThatReturnsResult>,
16681668
{
1669-
fn from_holder(x: Option<!>) -> Self {
1669+
fn from_residual(x: Option<!>) -> Self {
16701670
match x {
16711671
None => Err(From::from(
16721672
PleaseCallTheOkOrMethodToUseQuestionMarkOnOptionsInAMethodThatReturnsResult,

0 commit comments

Comments
 (0)