@@ -7,7 +7,7 @@ use rustc_data_structures::thin_vec::ThinVec;
7
7
use syntax:: attr;
8
8
use syntax:: ptr:: P as AstP ;
9
9
use syntax:: ast:: * ;
10
- use syntax:: source_map:: { respan, DesugaringKind } ;
10
+ use syntax:: source_map:: { respan, DesugaringKind , Span } ;
11
11
use syntax:: symbol:: { sym, Symbol } ;
12
12
13
13
impl LoweringContext < ' _ > {
@@ -691,115 +691,7 @@ impl LoweringContext<'_> {
691
691
return self . expr_drop_temps ( head_sp, match_expr, e. attrs . clone ( ) )
692
692
}
693
693
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) ,
803
695
ExprKind :: Mac ( _) => panic ! ( "Shouldn't exist here" ) ,
804
696
} ;
805
697
@@ -810,4 +702,107 @@ impl LoweringContext<'_> {
810
702
attrs : e. attrs . clone ( ) ,
811
703
}
812
704
}
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
+ }
813
808
}
0 commit comments