@@ -50,6 +50,7 @@ use hir::GenericArg;
5050use lint:: builtin:: { self , PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES ,
5151 ELIDED_LIFETIMES_IN_PATHS } ;
5252use middle:: cstore:: CrateStore ;
53+ use middle:: recursion_limit:: ensure_sufficient_stack;
5354use rustc_data_structures:: fx:: FxHashSet ;
5455use rustc_data_structures:: indexed_vec:: IndexVec ;
5556use rustc_data_structures:: thin_vec:: ThinVec ;
@@ -3659,8 +3660,8 @@ impl<'a> LoweringContext<'a> {
36593660 } )
36603661 }
36613662
3662- fn lower_expr ( & mut self , e : & Expr ) -> hir:: Expr {
3663- let kind = match e. node {
3663+ fn lower_expr_kind ( & mut self , e : & Expr ) -> hir:: ExprKind {
3664+ match e. node {
36643665 ExprKind :: Box ( ref inner) => hir:: ExprKind :: Box ( P ( self . lower_expr ( inner) ) ) ,
36653666 ExprKind :: ObsoleteInPlace ( ..) => {
36663667 self . sess . abort_if_errors ( ) ;
@@ -3959,19 +3960,11 @@ impl<'a> LoweringContext<'a> {
39593960 let struct_path = self . std_path ( e. span , & struct_path, None , is_unit) ;
39603961 let struct_path = hir:: QPath :: Resolved ( None , P ( struct_path) ) ;
39613962
3962- let LoweredNodeId { node_id, hir_id } = self . lower_node_id ( e. id ) ;
3963-
3964- return hir:: Expr {
3965- id : node_id,
3966- hir_id,
3967- node : if is_unit {
3963+ if is_unit {
39683964 hir:: ExprKind :: Path ( struct_path)
39693965 } else {
39703966 hir:: ExprKind :: Struct ( struct_path, fields, None )
3971- } ,
3972- span : e. span ,
3973- attrs : e. attrs . clone ( ) ,
3974- } ;
3967+ }
39753968 }
39763969 ExprKind :: Path ( ref qself, ref path) => {
39773970 let qpath = self . lower_qpath (
@@ -4050,18 +4043,7 @@ impl<'a> LoweringContext<'a> {
40504043 fields. iter ( ) . map ( |x| self . lower_field ( x) ) . collect ( ) ,
40514044 maybe_expr. as_ref ( ) . map ( |x| P ( self . lower_expr ( x) ) ) ,
40524045 ) ,
4053- ExprKind :: Paren ( ref ex) => {
4054- let mut ex = self . lower_expr ( ex) ;
4055- // include parens in span, but only if it is a super-span.
4056- if e. span . contains ( ex. span ) {
4057- ex. span = e. span ;
4058- }
4059- // merge attributes into the inner expression.
4060- let mut attrs = e. attrs . clone ( ) ;
4061- attrs. extend :: < Vec < _ > > ( ex. attrs . into ( ) ) ;
4062- ex. attrs = attrs;
4063- return ex;
4064- }
4046+ ExprKind :: Paren ( _) => bug ! ( "parens are handled in `lower_expr`" ) ,
40654047
40664048 ExprKind :: Yield ( ref opt_expr) => {
40674049 self . is_generator = true ;
@@ -4173,6 +4155,128 @@ impl<'a> LoweringContext<'a> {
41734155 loop_expr
41744156 }
41754157
4158+ ExprKind :: ForLoop ( ..) => bug ! ( ) ,
4159+
4160+ // Desugar ExprKind::Try
4161+ // From: `<expr>?`
4162+ ExprKind :: Try ( ref sub_expr) => {
4163+ // to:
4164+ //
4165+ // match Try::into_result(<expr>) {
4166+ // Ok(val) => #[allow(unreachable_code)] val,
4167+ // Err(err) => #[allow(unreachable_code)]
4168+ // // If there is an enclosing `catch {...}`
4169+ // break 'catch_target Try::from_error(From::from(err)),
4170+ // // Otherwise
4171+ // return Try::from_error(From::from(err)),
4172+ // }
4173+
4174+ let unstable_span =
4175+ self . allow_internal_unstable ( CompilerDesugaringKind :: QuestionMark , e. span ) ;
4176+
4177+ // Try::into_result(<expr>)
4178+ let discr = {
4179+ // expand <expr>
4180+ let sub_expr = self . lower_expr ( sub_expr) ;
4181+
4182+ let path = & [ "ops" , "Try" , "into_result" ] ;
4183+ let path = P ( self . expr_std_path (
4184+ unstable_span, path, None , ThinVec :: new ( ) ) ) ;
4185+ P ( self . expr_call ( e. span , path, hir_vec ! [ sub_expr] ) )
4186+ } ;
4187+
4188+ // #[allow(unreachable_code)]
4189+ let attr = {
4190+ // allow(unreachable_code)
4191+ let allow = {
4192+ let allow_ident = Ident :: from_str ( "allow" ) . with_span_pos ( e. span ) ;
4193+ let uc_ident = Ident :: from_str ( "unreachable_code" ) . with_span_pos ( e. span ) ;
4194+ let uc_nested = attr:: mk_nested_word_item ( uc_ident) ;
4195+ attr:: mk_list_item ( e. span , allow_ident, vec ! [ uc_nested] )
4196+ } ;
4197+ attr:: mk_spanned_attr_outer ( e. span , attr:: mk_attr_id ( ) , allow)
4198+ } ;
4199+ let attrs = vec ! [ attr] ;
4200+
4201+ // Ok(val) => #[allow(unreachable_code)] val,
4202+ let ok_arm = {
4203+ let val_ident = self . str_to_ident ( "val" ) ;
4204+ let val_pat = self . pat_ident ( e. span , val_ident) ;
4205+ let val_expr = P ( self . expr_ident_with_attrs (
4206+ e. span ,
4207+ val_ident,
4208+ val_pat. id ,
4209+ ThinVec :: from ( attrs. clone ( ) ) ,
4210+ ) ) ;
4211+ let ok_pat = self . pat_ok ( e. span , val_pat) ;
4212+
4213+ self . arm ( hir_vec ! [ ok_pat] , val_expr)
4214+ } ;
4215+
4216+ // Err(err) => #[allow(unreachable_code)]
4217+ // return Try::from_error(From::from(err)),
4218+ let err_arm = {
4219+ let err_ident = self . str_to_ident ( "err" ) ;
4220+ let err_local = self . pat_ident ( e. span , err_ident) ;
4221+ let from_expr = {
4222+ let path = & [ "convert" , "From" , "from" ] ;
4223+ let from = P ( self . expr_std_path (
4224+ e. span , path, None , ThinVec :: new ( ) ) ) ;
4225+ let err_expr = self . expr_ident ( e. span , err_ident, err_local. id ) ;
4226+
4227+ self . expr_call ( e. span , from, hir_vec ! [ err_expr] )
4228+ } ;
4229+ let from_err_expr =
4230+ self . wrap_in_try_constructor ( "from_error" , from_expr, unstable_span) ;
4231+ let thin_attrs = ThinVec :: from ( attrs) ;
4232+ let catch_scope = self . catch_scopes . last ( ) . map ( |x| * x) ;
4233+ let ret_expr = if let Some ( catch_node) = catch_scope {
4234+ P ( self . expr (
4235+ e. span ,
4236+ hir:: ExprKind :: Break (
4237+ hir:: Destination {
4238+ label : None ,
4239+ target_id : Ok ( catch_node) ,
4240+ } ,
4241+ Some ( from_err_expr) ,
4242+ ) ,
4243+ thin_attrs,
4244+ ) )
4245+ } else {
4246+ P ( self . expr ( e. span , hir:: ExprKind :: Ret ( Some ( from_err_expr) ) , thin_attrs) )
4247+ } ;
4248+
4249+ let err_pat = self . pat_err ( e. span , err_local) ;
4250+ self . arm ( hir_vec ! [ err_pat] , ret_expr)
4251+ } ;
4252+
4253+ hir:: ExprKind :: Match (
4254+ discr,
4255+ hir_vec ! [ err_arm, ok_arm] ,
4256+ hir:: MatchSource :: TryDesugar ,
4257+ )
4258+ }
4259+
4260+ ExprKind :: Mac ( _) => panic ! ( "Shouldn't exist here" ) ,
4261+ }
4262+ }
4263+
4264+
4265+ fn lower_expr ( & mut self , e : & Expr ) -> hir:: Expr {
4266+ // parens and for loops have some custom desugaring going on where the node ids aren't
4267+ // just lowered from the expression
4268+ let kind = match e. node {
4269+ ExprKind :: Paren ( ref ex) => {
4270+ let mut ex = ensure_sufficient_stack ( || self . lower_expr ( ex) ) ;
4271+ // include parens in span, but only if it is a super-span.
4272+ if e. span . contains ( ex. span ) {
4273+ ex. span = e. span ;
4274+ }
4275+ // merge attributes into the inner expression.
4276+ ex. attrs . extend ( e. attrs . iter ( ) . cloned ( ) ) ;
4277+ return ex;
4278+ } ,
4279+
41764280 // Desugar ExprForLoop
41774281 // From: `[opt_ident]: for <pat> in <head> <body>`
41784282 ExprKind :: ForLoop ( ref pat, ref head, ref body, opt_label) => {
@@ -4341,109 +4445,8 @@ impl<'a> LoweringContext<'a> {
43414445 let block = P ( self . block_all ( e. span , hir_vec ! [ let_stmt] , Some ( result) ) ) ;
43424446 // add the attributes to the outer returned expr node
43434447 return self . expr_block ( block, e. attrs . clone ( ) ) ;
4344- }
4345-
4346- // Desugar ExprKind::Try
4347- // From: `<expr>?`
4348- ExprKind :: Try ( ref sub_expr) => {
4349- // to:
4350- //
4351- // match Try::into_result(<expr>) {
4352- // Ok(val) => #[allow(unreachable_code)] val,
4353- // Err(err) => #[allow(unreachable_code)]
4354- // // If there is an enclosing `catch {...}`
4355- // break 'catch_target Try::from_error(From::from(err)),
4356- // // Otherwise
4357- // return Try::from_error(From::from(err)),
4358- // }
4359-
4360- let unstable_span =
4361- self . allow_internal_unstable ( CompilerDesugaringKind :: QuestionMark , e. span ) ;
4362-
4363- // Try::into_result(<expr>)
4364- let discr = {
4365- // expand <expr>
4366- let sub_expr = self . lower_expr ( sub_expr) ;
4367-
4368- let path = & [ "ops" , "Try" , "into_result" ] ;
4369- let path = P ( self . expr_std_path (
4370- unstable_span, path, None , ThinVec :: new ( ) ) ) ;
4371- P ( self . expr_call ( e. span , path, hir_vec ! [ sub_expr] ) )
4372- } ;
4373-
4374- // #[allow(unreachable_code)]
4375- let attr = {
4376- // allow(unreachable_code)
4377- let allow = {
4378- let allow_ident = Ident :: from_str ( "allow" ) . with_span_pos ( e. span ) ;
4379- let uc_ident = Ident :: from_str ( "unreachable_code" ) . with_span_pos ( e. span ) ;
4380- let uc_nested = attr:: mk_nested_word_item ( uc_ident) ;
4381- attr:: mk_list_item ( e. span , allow_ident, vec ! [ uc_nested] )
4382- } ;
4383- attr:: mk_spanned_attr_outer ( e. span , attr:: mk_attr_id ( ) , allow)
4384- } ;
4385- let attrs = vec ! [ attr] ;
4386-
4387- // Ok(val) => #[allow(unreachable_code)] val,
4388- let ok_arm = {
4389- let val_ident = self . str_to_ident ( "val" ) ;
4390- let val_pat = self . pat_ident ( e. span , val_ident) ;
4391- let val_expr = P ( self . expr_ident_with_attrs (
4392- e. span ,
4393- val_ident,
4394- val_pat. id ,
4395- ThinVec :: from ( attrs. clone ( ) ) ,
4396- ) ) ;
4397- let ok_pat = self . pat_ok ( e. span , val_pat) ;
4398-
4399- self . arm ( hir_vec ! [ ok_pat] , val_expr)
4400- } ;
4401-
4402- // Err(err) => #[allow(unreachable_code)]
4403- // return Try::from_error(From::from(err)),
4404- let err_arm = {
4405- let err_ident = self . str_to_ident ( "err" ) ;
4406- let err_local = self . pat_ident ( e. span , err_ident) ;
4407- let from_expr = {
4408- let path = & [ "convert" , "From" , "from" ] ;
4409- let from = P ( self . expr_std_path (
4410- e. span , path, None , ThinVec :: new ( ) ) ) ;
4411- let err_expr = self . expr_ident ( e. span , err_ident, err_local. id ) ;
4412-
4413- self . expr_call ( e. span , from, hir_vec ! [ err_expr] )
4414- } ;
4415- let from_err_expr =
4416- self . wrap_in_try_constructor ( "from_error" , from_expr, unstable_span) ;
4417- let thin_attrs = ThinVec :: from ( attrs) ;
4418- let catch_scope = self . catch_scopes . last ( ) . map ( |x| * x) ;
4419- let ret_expr = if let Some ( catch_node) = catch_scope {
4420- P ( self . expr (
4421- e. span ,
4422- hir:: ExprKind :: Break (
4423- hir:: Destination {
4424- label : None ,
4425- target_id : Ok ( catch_node) ,
4426- } ,
4427- Some ( from_err_expr) ,
4428- ) ,
4429- thin_attrs,
4430- ) )
4431- } else {
4432- P ( self . expr ( e. span , hir:: ExprKind :: Ret ( Some ( from_err_expr) ) , thin_attrs) )
4433- } ;
4434-
4435- let err_pat = self . pat_err ( e. span , err_local) ;
4436- self . arm ( hir_vec ! [ err_pat] , ret_expr)
4437- } ;
4438-
4439- hir:: ExprKind :: Match (
4440- discr,
4441- hir_vec ! [ err_arm, ok_arm] ,
4442- hir:: MatchSource :: TryDesugar ,
4443- )
4444- }
4445-
4446- ExprKind :: Mac ( _) => panic ! ( "Shouldn't exist here" ) ,
4448+ } ,
4449+ _ => ensure_sufficient_stack ( || self . lower_expr_kind ( e) ) ,
44474450 } ;
44484451
44494452 let LoweredNodeId { node_id, hir_id } = self . lower_node_id ( e. id ) ;
0 commit comments