@@ -665,46 +665,42 @@ impl<'a> AstValidator<'a> {
665665 /// - Non-const
666666 /// - Either foreign, or free and `unsafe extern "C"` semantically
667667 fn check_c_variadic_type ( & self , fk : FnKind < ' a > ) {
668- let variadic_spans: Vec < _ > = fk
669- . decl ( )
670- . inputs
671- . iter ( )
672- . filter ( |arg| matches ! ( arg. ty. kind, TyKind :: CVarArgs ) )
673- . map ( |arg| arg. span )
674- . collect ( ) ;
668+ // `...` is already rejected when it is not the final parameter.
669+ let variadic_param = match fk. decl ( ) . inputs . last ( ) {
670+ Some ( param) if matches ! ( param. ty. kind, TyKind :: CVarArgs ) => param,
671+ _ => return ,
672+ } ;
675673
676- if variadic_spans. is_empty ( ) {
677- return ;
678- }
674+ let FnKind :: Fn ( fn_ctxt, _, Fn { sig, .. } ) = fk else {
675+ // Unreachable because the parser already rejects `...` in closures.
676+ unreachable ! ( "C variable argument list cannot be used in closures" )
677+ } ;
679678
680- if let Some ( header) = fk. header ( )
681- && let Const :: Yes ( const_span) = header. constness
682- {
683- let mut spans = variadic_spans. clone ( ) ;
684- spans. push ( const_span) ;
679+ // C-variadics are not yet implemented in const evaluation.
680+ if let Const :: Yes ( const_span) = sig. header . constness {
685681 self . dcx ( ) . emit_err ( errors:: ConstAndCVariadic {
686- spans,
682+ spans : vec ! [ const_span , variadic_param . span ] ,
687683 const_span,
688- variadic_spans : variadic_spans . clone ( ) ,
684+ variadic_span : variadic_param . span ,
689685 } ) ;
690686 }
691687
692- match ( fk . ctxt ( ) , fk . header ( ) ) {
693- ( Some ( FnCtxt :: Foreign ) , _ ) => return ,
694- ( Some ( FnCtxt :: Free ) , Some ( header ) ) => match header. ext {
688+ match fn_ctxt {
689+ FnCtxt :: Foreign => return ,
690+ FnCtxt :: Free => match sig . header . ext {
695691 Extern :: Explicit ( StrLit { symbol_unescaped : sym:: C , .. } , _)
696692 | Extern :: Explicit ( StrLit { symbol_unescaped : sym:: C_dash_unwind , .. } , _)
697693 | Extern :: Implicit ( _)
698- if matches ! ( header. safety, Safety :: Unsafe ( _) ) =>
694+ if matches ! ( sig . header. safety, Safety :: Unsafe ( _) ) =>
699695 {
700696 return ;
701697 }
702698 _ => { }
703699 } ,
704- _ => { }
700+ FnCtxt :: Assoc ( _ ) => { }
705701 } ;
706702
707- self . dcx ( ) . emit_err ( errors:: BadCVariadic { span : variadic_spans } ) ;
703+ self . dcx ( ) . emit_err ( errors:: BadCVariadic { span : variadic_param . span } ) ;
708704 }
709705
710706 fn check_item_named ( & self , ident : Ident , kind : & str ) {
0 commit comments