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

Implement the new desugaring from try_trait_v2 #84767

Merged
merged 11 commits into from
May 18, 2021
58 changes: 26 additions & 32 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,8 +562,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
)
}

/// Desugar `try { <stmts>; <expr> }` into `{ <stmts>; ::std::ops::Try::from_ok(<expr>) }`,
/// `try { <stmts>; }` into `{ <stmts>; ::std::ops::Try::from_ok(()) }`
/// Desugar `try { <stmts>; <expr> }` into `{ <stmts>; ::std::ops::Try::from_output(<expr>) }`,
/// `try { <stmts>; }` into `{ <stmts>; ::std::ops::Try::from_output(()) }`
/// and save the block id to use it as a break target for desugaring of the `?` operator.
fn lower_expr_try_block(&mut self, body: &Block) -> hir::ExprKind<'hir> {
self.with_catch_scope(body.id, |this| {
Expand Down Expand Up @@ -592,9 +592,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
let ok_wrapped_span =
this.mark_span_with_reason(DesugaringKind::TryBlock, tail_expr.span, None);

// `::std::ops::Try::from_ok($tail_expr)`
// `::std::ops::Try::from_output($tail_expr)`
block.expr = Some(this.wrap_in_try_constructor(
hir::LangItem::TryFromOk,
hir::LangItem::TryTraitFromOutput,
try_span,
tail_expr,
ok_wrapped_span,
Expand Down Expand Up @@ -1896,14 +1896,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.allow_try_trait.clone(),
);

// `Try::into_result(<expr>)`
// `Try::branch(<expr>)`
let scrutinee = {
// expand <expr>
let sub_expr = self.lower_expr_mut(sub_expr);

self.expr_call_lang_item_fn(
unstable_span,
hir::LangItem::TryIntoResult,
hir::LangItem::TryTraitBranch,
arena_vec![self; sub_expr],
)
};
Expand All @@ -1921,8 +1921,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
};
let attrs = vec![attr];

// `Ok(val) => #[allow(unreachable_code)] val,`
let ok_arm = {
// `ControlFlow::Continue(val) => #[allow(unreachable_code)] val,`
let continue_arm = {
let val_ident = Ident::with_dummy_span(sym::val);
let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident);
let val_expr = self.arena.alloc(self.expr_ident_with_attrs(
Expand All @@ -1931,27 +1931,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
val_pat_nid,
ThinVec::from(attrs.clone()),
));
let ok_pat = self.pat_ok(span, val_pat);
self.arm(ok_pat, val_expr)
let continue_pat = self.pat_cf_continue(unstable_span, val_pat);
self.arm(continue_pat, val_expr)
};

// `Err(err) => #[allow(unreachable_code)]
// return Try::from_error(From::from(err)),`
let err_arm = {
let err_ident = Ident::with_dummy_span(sym::err);
let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident);
let from_expr = {
let err_expr = self.expr_ident_mut(try_span, err_ident, err_local_nid);
self.expr_call_lang_item_fn(
try_span,
hir::LangItem::FromFrom,
arena_vec![self; err_expr],
)
};
let from_err_expr = self.wrap_in_try_constructor(
hir::LangItem::TryFromError,
unstable_span,
from_expr,
// `ControlFlow::Break(residual) =>
// #[allow(unreachable_code)]
// return Try::from_residual(residual),`
let break_arm = {
let residual_ident = Ident::with_dummy_span(sym::residual);
let (residual_local, residual_local_nid) = self.pat_ident(try_span, residual_ident);
let residual_expr = self.expr_ident_mut(try_span, residual_ident, residual_local_nid);
let from_residual_expr = self.wrap_in_try_constructor(
hir::LangItem::TryTraitFromResidual,
try_span,
self.arena.alloc(residual_expr),
unstable_span,
);
let thin_attrs = ThinVec::from(attrs);
Expand All @@ -1962,25 +1956,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
try_span,
hir::ExprKind::Break(
hir::Destination { label: None, target_id },
Some(from_err_expr),
Some(from_residual_expr),
),
thin_attrs,
))
} else {
self.arena.alloc(self.expr(
try_span,
hir::ExprKind::Ret(Some(from_err_expr)),
hir::ExprKind::Ret(Some(from_residual_expr)),
thin_attrs,
))
};

let err_pat = self.pat_err(try_span, err_local);
self.arm(err_pat, ret_expr)
let break_pat = self.pat_cf_break(try_span, residual_local);
self.arm(break_pat, ret_expr)
};

hir::ExprKind::Match(
scrutinee,
arena_vec![self; err_arm, ok_arm],
arena_vec![self; break_arm, continue_arm],
hir::MatchSource::TryDesugar,
)
}
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ pub fn lower_crate<'a, 'hir>(
lifetimes_to_define: Vec::new(),
is_collecting_in_band_lifetimes: false,
in_scope_lifetimes: Vec::new(),
allow_try_trait: Some([sym::try_trait][..].into()),
allow_try_trait: Some([sym::control_flow_enum, sym::try_trait_v2][..].into()),
allow_gen_future: Some([sym::gen_future][..].into()),
}
.lower_crate(krate)
Expand Down Expand Up @@ -2479,14 +2479,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.pat(span, hir::PatKind::Lit(expr))
}

fn pat_ok(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
let field = self.single_pat_field(span, pat);
self.pat_lang_item_variant(span, hir::LangItem::ResultOk, field)
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
}

fn pat_err(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
let field = self.single_pat_field(span, pat);
self.pat_lang_item_variant(span, hir::LangItem::ResultErr, field)
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
}

fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
Expand Down
11 changes: 7 additions & 4 deletions compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,12 +308,12 @@ language_item_table! {

Termination, sym::termination, termination, Target::Trait;

Try, kw::Try, try_trait, Target::Trait;
Try, sym::Try, try_trait, Target::Trait;

// Language items from AST lowering
TryFromError, sym::from_error, from_error_fn, Target::Method(MethodKind::Trait { body: false });
TryFromOk, sym::from_ok, from_ok_fn, Target::Method(MethodKind::Trait { body: false });
TryIntoResult, sym::into_result, into_result_fn, Target::Method(MethodKind::Trait { body: false });
TryTraitFromResidual, sym::from_residual, from_residual_fn, Target::Method(MethodKind::Trait { body: false });
TryTraitFromOutput, sym::from_output, from_output_fn, Target::Method(MethodKind::Trait { body: false });
TryTraitBranch, sym::branch, branch_fn, Target::Method(MethodKind::Trait { body: false });

PollReady, sym::Ready, poll_ready_variant, Target::Variant;
PollPending, sym::Pending, poll_pending_variant, Target::Variant;
Expand All @@ -331,6 +331,9 @@ language_item_table! {
ResultOk, sym::Ok, result_ok_variant, Target::Variant;
ResultErr, sym::Err, result_err_variant, Target::Variant;

ControlFlowContinue, sym::Continue, cf_continue_variant, Target::Variant;
ControlFlowBreak, sym::Break, cf_break_variant, Target::Variant;

IntoIterIntoIter, sym::into_iter, into_iter_fn, Target::Method(MethodKind::Trait { body: false });
IteratorNext, sym::next, next_fn, Target::Method(MethodKind::Trait { body: false});

Expand Down
13 changes: 8 additions & 5 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,12 @@ symbols! {
BTreeSet,
BinaryHeap,
Borrow,
Break,
C,
CString,
Center,
Clone,
Continue,
Copy,
Count,
Debug,
Expand Down Expand Up @@ -326,6 +328,7 @@ symbols! {
box_patterns,
box_syntax,
braced_empty_structs,
branch,
breakpoint,
bridge,
bswap,
Expand Down Expand Up @@ -410,6 +413,7 @@ symbols! {
constructor,
contents,
context,
control_flow_enum,
convert,
copy,
copy_closures,
Expand Down Expand Up @@ -510,7 +514,6 @@ symbols! {
env,
eq,
ermsb_target_feature,
err,
exact_div,
except,
exchange_malloc,
Expand Down Expand Up @@ -580,10 +583,10 @@ symbols! {
frem_fast,
from,
from_desugaring,
from_error,
from_generator,
from_method,
from_ok,
from_output,
from_residual,
from_size_align_unchecked,
from_trait,
from_usize,
Expand Down Expand Up @@ -652,7 +655,6 @@ symbols! {
instruction_set,
intel,
into_iter,
into_result,
into_trait,
intra_doc_pointers,
intrinsics,
Expand Down Expand Up @@ -962,6 +964,7 @@ symbols! {
repr_packed,
repr_simd,
repr_transparent,
residual,
result,
result_type,
rhs,
Expand Down Expand Up @@ -1227,7 +1230,7 @@ symbols! {
try_blocks,
try_from_trait,
try_into_trait,
try_trait,
try_trait_v2,
tt,
tuple,
tuple_from_req,
Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/collections/vec_deque/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl<'a, T> Iterator for Iter<'a, T> {
where
Self: Sized,
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
R: Try<Output = B>,
{
let (mut iter, final_res);
if self.tail <= self.head {
Expand Down Expand Up @@ -140,7 +140,7 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
where
Self: Sized,
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
R: Try<Output = B>,
{
let (mut iter, final_res);
if self.tail <= self.head {
Expand Down
3 changes: 2 additions & 1 deletion library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@
#![feature(maybe_uninit_extra, maybe_uninit_slice, maybe_uninit_uninit_array)]
#![feature(alloc_layout_extra)]
#![feature(trusted_random_access)]
#![feature(try_trait)]
#![cfg_attr(bootstrap, feature(try_trait))]
#![cfg_attr(not(bootstrap), feature(try_trait_v2))]
#![feature(min_type_alias_impl_trait)]
#![feature(associated_type_bounds)]
#![feature(slice_group_by)]
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/iter/adapters/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ where
where
Self: Sized,
F: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
R: Try<Output = Acc>,
{
if let Some(ref mut a) = self.a {
acc = a.try_fold(acc, &mut f)?;
Expand Down Expand Up @@ -281,7 +281,7 @@ where
where
Self: Sized,
F: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
R: Try<Output = Acc>,
{
if let Some(ref mut b) = self.b {
acc = b.try_rfold(acc, &mut f)?;
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/iter/adapters/cloned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ where
where
Self: Sized,
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
R: Try<Output = B>,
{
self.it.try_fold(init, clone_try_fold(f))
}
Expand Down Expand Up @@ -82,7 +82,7 @@ where
where
Self: Sized,
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
R: Try<Output = B>,
{
self.it.try_rfold(init, clone_try_fold(f))
}
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/iter/adapters/copied.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ where
where
Self: Sized,
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
R: Try<Output = B>,
{
self.it.try_fold(init, copy_try_fold(f))
}
Expand Down Expand Up @@ -98,7 +98,7 @@ where
where
Self: Sized,
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
R: Try<Output = B>,
{
self.it.try_rfold(init, copy_try_fold(f))
}
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/iter/adapters/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ where
fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
where
F: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
R: Try<Output = Acc>,
{
// fully iterate the current iterator. this is necessary because
// `self.iter` may be empty even when `self.orig` isn't
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/iter/adapters/enumerate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ where
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
R: Try<Output = Acc>,
{
#[inline]
fn enumerate<'a, T, Acc, R>(
Expand Down Expand Up @@ -150,7 +150,7 @@ where
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
R: Try<Output = Acc>,
{
// Can safely add and subtract the count, as `ExactSizeIterator` promises
// that the number of elements fits into a `usize`.
Expand Down
6 changes: 3 additions & 3 deletions library/core/src/iter/adapters/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ fn filter_fold<T, Acc>(
move |acc, item| if predicate(&item) { fold(acc, item) } else { acc }
}

fn filter_try_fold<'a, T, Acc, R: Try<Ok = Acc>>(
fn filter_try_fold<'a, T, Acc, R: Try<Output = Acc>>(
predicate: &'a mut impl FnMut(&T) -> bool,
mut fold: impl FnMut(Acc, T) -> R + 'a,
) -> impl FnMut(Acc, T) -> R + 'a {
Expand Down Expand Up @@ -88,7 +88,7 @@ where
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
R: Try<Output = Acc>,
{
self.iter.try_fold(init, filter_try_fold(&mut self.predicate, fold))
}
Expand Down Expand Up @@ -117,7 +117,7 @@ where
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
R: Try<Output = Acc>,
{
self.iter.try_rfold(init, filter_try_fold(&mut self.predicate, fold))
}
Expand Down
Loading