@@ -222,6 +222,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
222
222
decl,
223
223
coroutine_kind,
224
224
body. as_deref ( ) ,
225
+ attrs,
225
226
) ;
226
227
227
228
let itctx = ImplTraitContext :: Universal ;
@@ -233,7 +234,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
233
234
header : this. lower_fn_header ( * header, hir:: Safety :: Safe ) ,
234
235
span : this. lower_span ( * fn_sig_span) ,
235
236
} ;
236
- hir:: ItemKind :: Fn ( sig, generics, body_id)
237
+ hir:: ItemKind :: Fn { sig, generics, body : body_id, has_body : body . is_some ( ) }
237
238
} )
238
239
}
239
240
ItemKind :: Mod ( _, mod_kind) => match mod_kind {
@@ -435,11 +436,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
435
436
}
436
437
ItemKind :: Delegation ( box delegation) => {
437
438
let delegation_results = self . lower_delegation ( delegation, id) ;
438
- hir:: ItemKind :: Fn (
439
- delegation_results. sig ,
440
- delegation_results. generics ,
441
- delegation_results. body_id ,
442
- )
439
+ hir:: ItemKind :: Fn {
440
+ sig : delegation_results. sig ,
441
+ generics : delegation_results. generics ,
442
+ body : delegation_results. body_id ,
443
+ has_body : true ,
444
+ }
443
445
}
444
446
ItemKind :: MacCall ( ..) | ItemKind :: DelegationMac ( ..) => {
445
447
panic ! ( "macros should have been expanded by now" )
@@ -747,7 +749,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
747
749
748
750
fn lower_trait_item ( & mut self , i : & AssocItem ) -> & ' hir hir:: TraitItem < ' hir > {
749
751
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 ) ;
751
753
let trait_item_def_id = hir_id. expect_owner ( ) ;
752
754
753
755
let ( generics, kind, has_default) = match & i. kind {
@@ -785,6 +787,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
785
787
& sig. decl ,
786
788
sig. header . coroutine_kind ,
787
789
Some ( body) ,
790
+ attrs,
788
791
) ;
789
792
let ( generics, sig) = self . lower_method_sig (
790
793
generics,
@@ -877,7 +880,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
877
880
let has_value = true ;
878
881
let ( defaultness, _) = self . lower_defaultness ( i. kind . defaultness ( ) , has_value) ;
879
882
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 ) ;
881
884
882
885
let ( generics, kind) = match & i. kind {
883
886
AssocItemKind :: Const ( box ConstItem { generics, ty, expr, .. } ) => self . lower_generics (
@@ -900,6 +903,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
900
903
& sig. decl ,
901
904
sig. header . coroutine_kind ,
902
905
body. as_deref ( ) ,
906
+ attrs,
903
907
) ;
904
908
let ( generics, sig) = self . lower_method_sig (
905
909
generics,
@@ -1054,20 +1058,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
1054
1058
} )
1055
1059
}
1056
1060
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) )
1071
1063
}
1072
1064
1073
1065
pub ( super ) fn lower_const_body ( & mut self , span : Span , expr : Option < & Expr > ) -> hir:: BodyId {
@@ -1089,9 +1081,37 @@ impl<'hir> LoweringContext<'_, 'hir> {
1089
1081
decl : & FnDecl ,
1090
1082
coroutine_kind : Option < CoroutineKind > ,
1091
1083
body : Option < & Block > ,
1084
+ attrs : & ' hir [ hir:: Attribute ] ,
1092
1085
) -> 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) ;
1095
1115
} ;
1096
1116
self . lower_body ( |this| {
1097
1117
let ( parameters, expr) = this. lower_coroutine_body_with_moved_arguments (
0 commit comments