@@ -50,13 +50,16 @@ use rustc_hir::attrs::{AttributeKind, InlineAttr};
5050use rustc_hir:: def_id:: DefId ;
5151use rustc_hir:: { self as hir, FnDeclFlags } ;
5252use rustc_middle:: span_bug;
53- use rustc_middle:: ty:: Asyncness ;
53+ use rustc_middle:: ty:: { Asyncness , TyCtxt } ;
5454use rustc_span:: symbol:: kw;
5555use rustc_span:: { Ident , Span , Symbol } ;
5656use smallvec:: SmallVec ;
5757
5858use crate :: delegation:: generics:: { GenericsGenerationResult , GenericsGenerationResults } ;
59- use crate :: errors:: { CycleInDelegationSignatureResolution , UnresolvedDelegationCallee } ;
59+ use crate :: errors:: {
60+ CycleInDelegationSignatureResolution , DelegationBlockSpecifiedWhenNoParams ,
61+ UnresolvedDelegationCallee ,
62+ } ;
6063use crate :: {
6164 AllowReturnTypeNotation , GenericArgsMode , ImplTraitContext , ImplTraitPosition , LoweringContext ,
6265 ParamMode , ResolverAstLoweringExt ,
@@ -105,6 +108,12 @@ static ATTRS_ADDITIONS: &[AttrAdditionInfo] = &[
105108 } ,
106109] ;
107110
111+ // Function parameter count, including C variadic `...` if present.
112+ pub ( crate ) fn param_count ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> ( usize , bool /*c_variadic*/ ) {
113+ let sig = tcx. fn_sig ( def_id) . skip_binder ( ) . skip_binder ( ) ;
114+ ( sig. inputs ( ) . len ( ) + usize:: from ( sig. c_variadic ( ) ) , sig. c_variadic ( ) )
115+ }
116+
108117impl < ' hir > LoweringContext < ' _ , ' hir > {
109118 fn is_method ( & self , def_id : DefId , span : Span ) -> bool {
110119 match self . tcx . def_kind ( def_id) {
@@ -140,13 +149,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
140149
141150 let is_method = self . is_method ( sig_id, span) ;
142151
143- let ( param_count, c_variadic) = self . param_count ( sig_id) ;
152+ let ( param_count, c_variadic) = param_count ( self . tcx , sig_id) ;
144153
145154 let mut generics = self . uplift_delegation_generics ( delegation, sig_id, is_method) ;
146155
147156 let body_id = self . lower_delegation_body (
148157 delegation,
149- is_method ,
158+ sig_id ,
150159 param_count,
151160 & mut generics,
152161 span,
@@ -267,12 +276,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
267276 self . get_partial_res ( node_id) . and_then ( |r| r. expect_full_res ( ) . opt_def_id ( ) )
268277 }
269278
270- // Function parameter count, including C variadic `...` if present.
271- fn param_count ( & self , def_id : DefId ) -> ( usize , bool /*c_variadic*/ ) {
272- let sig = self . tcx . fn_sig ( def_id) . skip_binder ( ) . skip_binder ( ) ;
273- ( sig. inputs ( ) . len ( ) + usize:: from ( sig. c_variadic ( ) ) , sig. c_variadic ( ) )
274- }
275-
276279 fn lower_delegation_decl (
277280 & mut self ,
278281 sig_id : DefId ,
@@ -396,7 +399,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
396399 fn lower_delegation_body (
397400 & mut self ,
398401 delegation : & Delegation ,
399- is_method : bool ,
402+ sig_id : DefId ,
400403 param_count : usize ,
401404 generics : & mut GenericsGenerationResults < ' hir > ,
402405 span : Span ,
@@ -407,12 +410,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
407410 let mut parameters: Vec < hir:: Param < ' _ > > = Vec :: with_capacity ( param_count) ;
408411 let mut args: Vec < hir:: Expr < ' _ > > = Vec :: with_capacity ( param_count) ;
409412
413+ let is_method = this. is_method ( sig_id, span) ;
414+
415+ // Should be in sync with conditions in `lower_delayed_owner::is_dead_code`.
416+ let generate_block = is_method
417+ || matches ! ( this. tcx. def_kind( sig_id) , DefKind :: Fn )
418+ || !delegation. from_glob_or_list ;
419+
410420 for idx in 0 ..param_count {
411421 let ( param, pat_node_id) = this. generate_param ( is_method, idx, span) ;
412422 parameters. push ( param) ;
413423
414424 let arg = if let Some ( block) = block
415425 && idx == 0
426+ && generate_block
416427 {
417428 let mut self_resolver = SelfResolver {
418429 ctxt : this,
@@ -429,15 +440,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
429440 args. push ( arg) ;
430441 }
431442
432- // If we have no params in signature function but user still wrote some code in
433- // delegation body, then add this code as first arg, eventually an error will be shown,
434- // also nested delegations may need to access information about this code (#154332),
435- // so it is better to leave this code as opposed to bodies of extern functions,
436- // which are completely erased from existence.
443+ // Report an error if user has explicitly specified delegation's block
444+ // in a single delegation when reused function has no params.
437445 if param_count == 0
446+ && !delegation. from_glob_or_list
438447 && let Some ( block) = block
439448 {
440- args . push ( this . lower_target_expr ( & block) ) ;
449+ this . dcx ( ) . emit_err ( DelegationBlockSpecifiedWhenNoParams { span : block. span } ) ;
441450 }
442451
443452 let final_expr = this. finalize_body_lowering ( delegation, args, generics, span) ;
0 commit comments