@@ -50,6 +50,7 @@ use hir::GenericArg;
50
50
use lint:: builtin:: { self , PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES ,
51
51
ELIDED_LIFETIMES_IN_PATHS } ;
52
52
use middle:: cstore:: CrateStore ;
53
+ use middle:: recursion_limit:: ensure_sufficient_stack;
53
54
use rustc_data_structures:: fx:: FxHashSet ;
54
55
use rustc_data_structures:: indexed_vec:: IndexVec ;
55
56
use rustc_data_structures:: thin_vec:: ThinVec ;
@@ -3659,8 +3660,8 @@ impl<'a> LoweringContext<'a> {
3659
3660
} )
3660
3661
}
3661
3662
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 {
3664
3665
ExprKind :: Box ( ref inner) => hir:: ExprKind :: Box ( P ( self . lower_expr ( inner) ) ) ,
3665
3666
ExprKind :: ObsoleteInPlace ( ..) => {
3666
3667
self . sess . abort_if_errors ( ) ;
@@ -3959,19 +3960,11 @@ impl<'a> LoweringContext<'a> {
3959
3960
let struct_path = self . std_path ( e. span , & struct_path, None , is_unit) ;
3960
3961
let struct_path = hir:: QPath :: Resolved ( None , P ( struct_path) ) ;
3961
3962
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 {
3968
3964
hir:: ExprKind :: Path ( struct_path)
3969
3965
} else {
3970
3966
hir:: ExprKind :: Struct ( struct_path, fields, None )
3971
- } ,
3972
- span : e. span ,
3973
- attrs : e. attrs . clone ( ) ,
3974
- } ;
3967
+ }
3975
3968
}
3976
3969
ExprKind :: Path ( ref qself, ref path) => {
3977
3970
let qpath = self . lower_qpath (
@@ -4050,18 +4043,7 @@ impl<'a> LoweringContext<'a> {
4050
4043
fields. iter ( ) . map ( |x| self . lower_field ( x) ) . collect ( ) ,
4051
4044
maybe_expr. as_ref ( ) . map ( |x| P ( self . lower_expr ( x) ) ) ,
4052
4045
) ,
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`" ) ,
4065
4047
4066
4048
ExprKind :: Yield ( ref opt_expr) => {
4067
4049
self . is_generator = true ;
@@ -4173,6 +4155,128 @@ impl<'a> LoweringContext<'a> {
4173
4155
loop_expr
4174
4156
}
4175
4157
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
+
4176
4280
// Desugar ExprForLoop
4177
4281
// From: `[opt_ident]: for <pat> in <head> <body>`
4178
4282
ExprKind :: ForLoop ( ref pat, ref head, ref body, opt_label) => {
@@ -4341,109 +4445,8 @@ impl<'a> LoweringContext<'a> {
4341
4445
let block = P ( self . block_all ( e. span , hir_vec ! [ let_stmt] , Some ( result) ) ) ;
4342
4446
// add the attributes to the outer returned expr node
4343
4447
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) ) ,
4447
4450
} ;
4448
4451
4449
4452
let LoweredNodeId { node_id, hir_id } = self . lower_node_id ( e. id ) ;
0 commit comments