@@ -222,6 +222,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
222222 decl,
223223 coroutine_kind,
224224 body. as_deref ( ) ,
225+ attrs,
225226 ) ;
226227
227228 let itctx = ImplTraitContext :: Universal ;
@@ -233,7 +234,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
233234 header : this. lower_fn_header ( * header, hir:: Safety :: Safe ) ,
234235 span : this. lower_span ( * fn_sig_span) ,
235236 } ;
236- hir:: ItemKind :: Fn { sig, generics, body : body_id }
237+ hir:: ItemKind :: Fn { sig, generics, body : body_id, has_body : body . is_some ( ) }
237238 } )
238239 }
239240 ItemKind :: Mod ( _, mod_kind) => match mod_kind {
@@ -439,6 +440,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
439440 sig : delegation_results. sig ,
440441 generics : delegation_results. generics ,
441442 body : delegation_results. body_id ,
443+ has_body : true ,
442444 }
443445 }
444446 ItemKind :: MacCall ( ..) | ItemKind :: DelegationMac ( ..) => {
@@ -747,7 +749,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
747749
748750 fn lower_trait_item ( & mut self , i : & AssocItem ) -> & ' hir hir:: TraitItem < ' hir > {
749751 let hir_id = hir:: HirId :: make_owner ( self . current_hir_id_owner . def_id ) ;
750- self . lower_attrs ( hir_id, & i. attrs ) ;
752+ let attrs = self . lower_attrs ( hir_id, & i. attrs ) ;
751753 let trait_item_def_id = hir_id. expect_owner ( ) ;
752754
753755 let ( generics, kind, has_default) = match & i. kind {
@@ -785,6 +787,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
785787 & sig. decl ,
786788 sig. header . coroutine_kind ,
787789 Some ( body) ,
790+ attrs,
788791 ) ;
789792 let ( generics, sig) = self . lower_method_sig (
790793 generics,
@@ -877,7 +880,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
877880 let has_value = true ;
878881 let ( defaultness, _) = self . lower_defaultness ( i. kind . defaultness ( ) , has_value) ;
879882 let hir_id = hir:: HirId :: make_owner ( self . current_hir_id_owner . def_id ) ;
880- self . lower_attrs ( hir_id, & i. attrs ) ;
883+ let attrs = self . lower_attrs ( hir_id, & i. attrs ) ;
881884
882885 let ( generics, kind) = match & i. kind {
883886 AssocItemKind :: Const ( box ConstItem { generics, ty, expr, .. } ) => self . lower_generics (
@@ -900,6 +903,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
900903 & sig. decl ,
901904 sig. header . coroutine_kind ,
902905 body. as_deref ( ) ,
906+ attrs,
903907 ) ;
904908 let ( generics, sig) = self . lower_method_sig (
905909 generics,
@@ -1054,20 +1058,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
10541058 } )
10551059 }
10561060
1057- fn lower_fn_body_block (
1058- & mut self ,
1059- span : Span ,
1060- decl : & FnDecl ,
1061- body : Option < & Block > ,
1062- ) -> hir:: BodyId {
1063- self . lower_fn_body ( decl, |this| this. lower_block_expr_opt ( span, body) )
1064- }
1065-
1066- fn lower_block_expr_opt ( & mut self , span : Span , block : Option < & Block > ) -> hir:: Expr < ' hir > {
1067- match block {
1068- Some ( block) => self . lower_block_expr ( block) ,
1069- None => self . expr_err ( span, self . dcx ( ) . has_errors ( ) . unwrap ( ) ) ,
1070- }
1061+ fn lower_fn_body_block ( & mut self , decl : & FnDecl , body : & Block ) -> hir:: BodyId {
1062+ self . lower_fn_body ( decl, |this| this. lower_block_expr ( body) )
10711063 }
10721064
10731065 pub ( super ) fn lower_const_body ( & mut self , span : Span , expr : Option < & Expr > ) -> hir:: BodyId {
@@ -1089,9 +1081,37 @@ impl<'hir> LoweringContext<'_, 'hir> {
10891081 decl : & FnDecl ,
10901082 coroutine_kind : Option < CoroutineKind > ,
10911083 body : Option < & Block > ,
1084+ attrs : & ' hir [ hir:: Attribute ] ,
10921085 ) -> hir:: BodyId {
1093- let ( Some ( coroutine_kind) , Some ( body) ) = ( coroutine_kind, body) else {
1094- return self . lower_fn_body_block ( span, decl, body) ;
1086+ let Some ( body) = body else {
1087+ // Functions without a body are an error, except if this is an intrinsic. For those we
1088+ // create a fake body so that the entire rest of the compiler doesn't have to deal with
1089+ // this as a special case.
1090+ return self . lower_fn_body ( decl, |this| {
1091+ if attrs. iter ( ) . any ( |a| a. name_or_empty ( ) == sym:: rustc_intrinsic) {
1092+ let empty_block = hir:: Block {
1093+ hir_id : this. next_id ( ) ,
1094+ stmts : & [ ] ,
1095+ expr : None ,
1096+ rules : hir:: BlockCheckMode :: DefaultBlock ,
1097+ span,
1098+ targeted_by_break : false ,
1099+ } ;
1100+ let loop_ = hir:: ExprKind :: Loop (
1101+ this. arena . alloc ( empty_block) ,
1102+ None ,
1103+ hir:: LoopSource :: Loop ,
1104+ span,
1105+ ) ;
1106+ hir:: Expr { hir_id : this. next_id ( ) , kind : loop_, span }
1107+ } else {
1108+ this. expr_err ( span, this. dcx ( ) . has_errors ( ) . unwrap ( ) )
1109+ }
1110+ } ) ;
1111+ } ;
1112+ let Some ( coroutine_kind) = coroutine_kind else {
1113+ // Typical case: not a coroutine.
1114+ return self . lower_fn_body_block ( decl, body) ;
10951115 } ;
10961116 self . lower_body ( |this| {
10971117 let ( parameters, expr) = this. lower_coroutine_body_with_moved_arguments (
0 commit comments