Skip to content

Commit c817596

Browse files
committed
lowering: extract lower_expr_try
1 parent cf20d8c commit c817596

File tree

1 file changed

+105
-110
lines changed

1 file changed

+105
-110
lines changed

src/librustc/hir/lowering/expr.rs

Lines changed: 105 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_data_structures::thin_vec::ThinVec;
77
use syntax::attr;
88
use syntax::ptr::P as AstP;
99
use syntax::ast::*;
10-
use syntax::source_map::{respan, DesugaringKind};
10+
use syntax::source_map::{respan, DesugaringKind, Span};
1111
use syntax::symbol::{sym, Symbol};
1212

1313
impl LoweringContext<'_> {
@@ -691,115 +691,7 @@ impl LoweringContext<'_> {
691691
return self.expr_drop_temps(head_sp, match_expr, e.attrs.clone())
692692
}
693693

694-
// Desugar `ExprKind::Try`
695-
// from: `<expr>?`
696-
ExprKind::Try(ref sub_expr) => {
697-
// into:
698-
//
699-
// match Try::into_result(<expr>) {
700-
// Ok(val) => #[allow(unreachable_code)] val,
701-
// Err(err) => #[allow(unreachable_code)]
702-
// // If there is an enclosing `catch {...}`
703-
// break 'catch_target Try::from_error(From::from(err)),
704-
// // Otherwise
705-
// return Try::from_error(From::from(err)),
706-
// }
707-
708-
let unstable_span = self.mark_span_with_reason(
709-
DesugaringKind::QuestionMark,
710-
e.span,
711-
self.allow_try_trait.clone(),
712-
);
713-
let try_span = self.sess.source_map().end_point(e.span);
714-
let try_span = self.mark_span_with_reason(
715-
DesugaringKind::QuestionMark,
716-
try_span,
717-
self.allow_try_trait.clone(),
718-
);
719-
720-
// `Try::into_result(<expr>)`
721-
let discr = {
722-
// expand <expr>
723-
let sub_expr = self.lower_expr(sub_expr);
724-
725-
let path = &[sym::ops, sym::Try, sym::into_result];
726-
P(self.expr_call_std_path(
727-
unstable_span,
728-
path,
729-
hir_vec![sub_expr],
730-
))
731-
};
732-
733-
// `#[allow(unreachable_code)]`
734-
let attr = {
735-
// `allow(unreachable_code)`
736-
let allow = {
737-
let allow_ident = Ident::new(sym::allow, e.span);
738-
let uc_ident = Ident::new(sym::unreachable_code, e.span);
739-
let uc_nested = attr::mk_nested_word_item(uc_ident);
740-
attr::mk_list_item(allow_ident, vec![uc_nested])
741-
};
742-
attr::mk_attr_outer(allow)
743-
};
744-
let attrs = vec![attr];
745-
746-
// `Ok(val) => #[allow(unreachable_code)] val,`
747-
let ok_arm = {
748-
let val_ident = Ident::with_empty_ctxt(sym::val);
749-
let (val_pat, val_pat_nid) = self.pat_ident(e.span, val_ident);
750-
let val_expr = P(self.expr_ident_with_attrs(
751-
e.span,
752-
val_ident,
753-
val_pat_nid,
754-
ThinVec::from(attrs.clone()),
755-
));
756-
let ok_pat = self.pat_ok(e.span, val_pat);
757-
758-
self.arm(hir_vec![ok_pat], val_expr)
759-
};
760-
761-
// `Err(err) => #[allow(unreachable_code)]
762-
// return Try::from_error(From::from(err)),`
763-
let err_arm = {
764-
let err_ident = Ident::with_empty_ctxt(sym::err);
765-
let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident);
766-
let from_expr = {
767-
let from_path = &[sym::convert, sym::From, sym::from];
768-
let err_expr = self.expr_ident(try_span, err_ident, err_local_nid);
769-
self.expr_call_std_path(try_span, from_path, hir_vec![err_expr])
770-
};
771-
let from_err_expr =
772-
self.wrap_in_try_constructor(sym::from_error, from_expr, unstable_span);
773-
let thin_attrs = ThinVec::from(attrs);
774-
let catch_scope = self.catch_scopes.last().map(|x| *x);
775-
let ret_expr = if let Some(catch_node) = catch_scope {
776-
let target_id = Ok(self.lower_node_id(catch_node));
777-
P(self.expr(
778-
try_span,
779-
hir::ExprKind::Break(
780-
hir::Destination {
781-
label: None,
782-
target_id,
783-
},
784-
Some(from_err_expr),
785-
),
786-
thin_attrs,
787-
))
788-
} else {
789-
P(self.expr(try_span, hir::ExprKind::Ret(Some(from_err_expr)), thin_attrs))
790-
};
791-
792-
let err_pat = self.pat_err(try_span, err_local);
793-
self.arm(hir_vec![err_pat], ret_expr)
794-
};
795-
796-
hir::ExprKind::Match(
797-
discr,
798-
hir_vec![err_arm, ok_arm],
799-
hir::MatchSource::TryDesugar,
800-
)
801-
}
802-
694+
ExprKind::Try(ref sub_expr) => self.lower_expr_try(e.span, sub_expr),
803695
ExprKind::Mac(_) => panic!("Shouldn't exist here"),
804696
};
805697

@@ -810,4 +702,107 @@ impl LoweringContext<'_> {
810702
attrs: e.attrs.clone(),
811703
}
812704
}
705+
706+
/// Desugar `ExprKind::Try` from: `<expr>?` into:
707+
/// ```rust
708+
/// match Try::into_result(<expr>) {
709+
/// Ok(val) => #[allow(unreachable_code)] val,
710+
/// Err(err) => #[allow(unreachable_code)]
711+
/// // If there is an enclosing `try {...}`:
712+
/// break 'catch_target Try::from_error(From::from(err)),
713+
/// // Otherwise:
714+
/// return Try::from_error(From::from(err)),
715+
/// }
716+
/// ```
717+
fn lower_expr_try(&mut self, span: Span, sub_expr: &Expr) -> hir::ExprKind {
718+
let unstable_span = self.mark_span_with_reason(
719+
DesugaringKind::QuestionMark,
720+
span,
721+
self.allow_try_trait.clone(),
722+
);
723+
let try_span = self.sess.source_map().end_point(span);
724+
let try_span = self.mark_span_with_reason(
725+
DesugaringKind::QuestionMark,
726+
try_span,
727+
self.allow_try_trait.clone(),
728+
);
729+
730+
// `Try::into_result(<expr>)`
731+
let scrutinee = {
732+
// expand <expr>
733+
let sub_expr = self.lower_expr(sub_expr);
734+
735+
let path = &[sym::ops, sym::Try, sym::into_result];
736+
P(self.expr_call_std_path(unstable_span, path, hir_vec![sub_expr]))
737+
};
738+
739+
// `#[allow(unreachable_code)]`
740+
let attr = {
741+
// `allow(unreachable_code)`
742+
let allow = {
743+
let allow_ident = Ident::new(sym::allow, span);
744+
let uc_ident = Ident::new(sym::unreachable_code, span);
745+
let uc_nested = attr::mk_nested_word_item(uc_ident);
746+
attr::mk_list_item(allow_ident, vec![uc_nested])
747+
};
748+
attr::mk_attr_outer(allow)
749+
};
750+
let attrs = vec![attr];
751+
752+
// `Ok(val) => #[allow(unreachable_code)] val,`
753+
let ok_arm = {
754+
let val_ident = Ident::with_empty_ctxt(sym::val);
755+
let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident);
756+
let val_expr = P(self.expr_ident_with_attrs(
757+
span,
758+
val_ident,
759+
val_pat_nid,
760+
ThinVec::from(attrs.clone()),
761+
));
762+
let ok_pat = self.pat_ok(span, val_pat);
763+
764+
self.arm(hir_vec![ok_pat], val_expr)
765+
};
766+
767+
// `Err(err) => #[allow(unreachable_code)]
768+
// return Try::from_error(From::from(err)),`
769+
let err_arm = {
770+
let err_ident = Ident::with_empty_ctxt(sym::err);
771+
let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident);
772+
let from_expr = {
773+
let from_path = &[sym::convert, sym::From, sym::from];
774+
let err_expr = self.expr_ident(try_span, err_ident, err_local_nid);
775+
self.expr_call_std_path(try_span, from_path, hir_vec![err_expr])
776+
};
777+
let from_err_expr =
778+
self.wrap_in_try_constructor(sym::from_error, from_expr, unstable_span);
779+
let thin_attrs = ThinVec::from(attrs);
780+
let catch_scope = self.catch_scopes.last().map(|x| *x);
781+
let ret_expr = if let Some(catch_node) = catch_scope {
782+
let target_id = Ok(self.lower_node_id(catch_node));
783+
P(self.expr(
784+
try_span,
785+
hir::ExprKind::Break(
786+
hir::Destination {
787+
label: None,
788+
target_id,
789+
},
790+
Some(from_err_expr),
791+
),
792+
thin_attrs,
793+
))
794+
} else {
795+
P(self.expr(try_span, hir::ExprKind::Ret(Some(from_err_expr)), thin_attrs))
796+
};
797+
798+
let err_pat = self.pat_err(try_span, err_local);
799+
self.arm(hir_vec![err_pat], ret_expr)
800+
};
801+
802+
hir::ExprKind::Match(
803+
scrutinee,
804+
hir_vec![err_arm, ok_arm],
805+
hir::MatchSource::TryDesugar,
806+
)
807+
}
813808
}

0 commit comments

Comments
 (0)