@@ -96,7 +96,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
9696 let generics = self . lower_delegation_generics ( span) ;
9797 DelegationResults { body_id, sig, ident, generics }
9898 }
99- Err ( err) => self . generate_delegation_error ( err, span) ,
99+ Err ( err) => self . generate_delegation_error ( err, span, delegation ) ,
100100 }
101101 }
102102
@@ -404,6 +404,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
404404 & mut self ,
405405 err : ErrorGuaranteed ,
406406 span : Span ,
407+ delegation : & Delegation ,
407408 ) -> DelegationResults < ' hir > {
408409 let generics = self . lower_delegation_generics ( span) ;
409410
@@ -418,11 +419,47 @@ impl<'hir> LoweringContext<'_, 'hir> {
418419 let header = self . generate_header_error ( ) ;
419420 let sig = hir:: FnSig { decl, header, span } ;
420421
421- let ident = Ident :: dummy ( ) ;
422- let body_id = self . lower_body ( |this| ( & [ ] , this. mk_expr ( hir:: ExprKind :: Err ( err) , span) ) ) ;
422+ let ident = self . lower_ident ( delegation. ident ) ;
423+
424+ let body_id = self . lower_body ( |this| {
425+ let body_expr = match delegation. body . as_ref ( ) {
426+ Some ( box block) => {
427+ hir:: ExprKind :: Block ( this. generate_delegation_error_block ( block, span) , None )
428+ }
429+ None => hir:: ExprKind :: Err ( err) ,
430+ } ;
431+
432+ ( & [ ] , this. mk_expr ( body_expr, span) )
433+ } ) ;
434+
423435 DelegationResults { ident, generics, body_id, sig }
424436 }
425437
438+ // Generates a block when we failed to resolve delegation, where a target expression is its only statement,
439+ // thus there will be no ICEs on further stages of analysis (see #144594)
440+ fn generate_delegation_error_block (
441+ & mut self ,
442+ block : & Block ,
443+ span : Span ,
444+ ) -> & ' hir mut hir:: Block < ' hir > {
445+ // As we generate a void function we want to convert target expression to statement to avoid additional
446+ // errors, such as mismatched return type
447+ let stmts = self . arena . alloc_from_iter ( [ hir:: Stmt {
448+ hir_id : self . next_id ( ) ,
449+ kind : rustc_hir:: StmtKind :: Semi ( self . arena . alloc ( self . lower_target_expr ( block) ) ) ,
450+ span,
451+ } ] ) ;
452+
453+ self . arena . alloc ( hir:: Block {
454+ stmts,
455+ expr : None ,
456+ hir_id : self . next_id ( ) ,
457+ rules : hir:: BlockCheckMode :: DefaultBlock ,
458+ span,
459+ targeted_by_break : false ,
460+ } )
461+ }
462+
426463 fn generate_header_error ( & self ) -> hir:: FnHeader {
427464 hir:: FnHeader {
428465 safety : hir:: Safety :: Safe . into ( ) ,
0 commit comments