@@ -84,6 +84,19 @@ enum AttrAdditionKind {
8484 Inherit { factory : fn ( Span , & hir:: Attribute ) -> hir:: Attribute } ,
8585}
8686
87+ /// Summary info about function parameters.
88+ #[ derive( Debug , Clone , Copy , Eq , PartialEq ) ]
89+ struct ParamInfo {
90+ /// The number of function parameters, including any C variadic `...` parameter.
91+ pub param_count : usize ,
92+
93+ /// Whether the function arguments end in a C variadic `...` parameter.
94+ pub c_variadic : bool ,
95+
96+ /// The index of the splatted parameter, if any.
97+ pub splatted : Option < u16 > ,
98+ }
99+
87100const PARENT_ID : hir:: ItemLocalId = hir:: ItemLocalId :: ZERO ;
88101
89102static ATTRS_ADDITIONS : & [ AttrAdditionInfo ] = & [
@@ -199,22 +212,26 @@ impl<'hir> LoweringContext<'_, 'hir> {
199212
200213 let is_method = self . is_method ( sig_id, span) ;
201214
202- let ( param_count , c_variadic ) = self . param_count ( sig_id) ;
215+ let param_info = self . param_info ( sig_id) ;
203216
204- if !self . check_block_soundness ( delegation, sig_id, is_method, param_count) {
217+ if !self . check_block_soundness ( delegation, sig_id, is_method, param_info . param_count ) {
205218 return self . generate_delegation_error ( span, delegation) ;
206219 }
207220
208221 let mut generics = self . uplift_delegation_generics ( delegation, sig_id, is_method) ;
209222
210- let ( body_id, call_expr_id, unused_target_expr) =
211- self . lower_delegation_body ( delegation, sig_id, param_count, & mut generics, span) ;
223+ let ( body_id, call_expr_id, unused_target_expr) = self . lower_delegation_body (
224+ delegation,
225+ sig_id,
226+ param_info. param_count ,
227+ & mut generics,
228+ span,
229+ ) ;
212230
213231 let decl = self . lower_delegation_decl (
214232 delegation. source ,
215233 sig_id,
216- param_count,
217- c_variadic,
234+ param_info,
218235 span,
219236 & generics,
220237 delegation. id ,
@@ -367,24 +384,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
367384 self . get_partial_res ( node_id) . and_then ( |r| r. expect_full_res ( ) . opt_def_id ( ) )
368385 }
369386
370- // Function parameter count , including C variadic `...` if present.
371- fn param_count ( & self , def_id : DefId ) -> ( usize , bool /*c_variadic*/ ) {
387+ /// Returns function parameter info , including C variadic `...` and `#[splat] ` if present.
388+ fn param_info ( & self , def_id : DefId ) -> ParamInfo {
372389 let sig = self . tcx . fn_sig ( def_id) . skip_binder ( ) . skip_binder ( ) ;
373- ( sig. inputs ( ) . len ( ) + usize:: from ( sig. c_variadic ( ) ) , sig. c_variadic ( ) )
390+
391+ // FIXME(splat): use `sig.splatted()` once FnSig has it
392+ ParamInfo {
393+ param_count : sig. inputs ( ) . len ( ) + usize:: from ( sig. c_variadic ( ) ) ,
394+ c_variadic : sig. c_variadic ( ) ,
395+ splatted : None ,
396+ }
374397 }
375398
376399 fn lower_delegation_decl (
377400 & mut self ,
378401 source : DelegationSource ,
379402 sig_id : DefId ,
380- param_count : usize ,
381- c_variadic : bool ,
403+ param_info : ParamInfo ,
382404 span : Span ,
383405 generics : & GenericsGenerationResults < ' hir > ,
384406 call_path_node_id : NodeId ,
385407 call_expr_id : HirId ,
386408 unused_target_expr : bool ,
387409 ) -> & ' hir hir:: FnDecl < ' hir > {
410+ let ParamInfo { param_count, c_variadic, splatted } = param_info;
411+
388412 // The last parameter in C variadic functions is skipped in the signature,
389413 // like during regular lowering.
390414 let decl_param_count = param_count - c_variadic as usize ;
@@ -429,7 +453,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
429453 output : hir:: FnRetTy :: Return ( output) ,
430454 fn_decl_kind : FnDeclFlags :: default ( )
431455 . set_lifetime_elision_allowed ( true )
432- . set_c_variadic ( c_variadic) ,
456+ . set_c_variadic ( c_variadic)
457+ . set_splatted ( splatted, inputs. len ( ) )
458+ . unwrap ( ) ,
433459 } )
434460 }
435461
0 commit comments