diff --git a/src/language.yacc b/src/language.yacc
index 2346e88db2af0fa902193ddc014cfe10c9b19cfe..57ed9df2608e4a26be8f2493100366ec65927f3b 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -110,7 +110,7 @@
 /* This is the grammar definition of Pike. */
 
 #include "global.h"
-RCSID("$Id: language.yacc,v 1.205 2000/07/18 06:02:16 mast Exp $");
+RCSID("$Id: language.yacc,v 1.206 2000/08/15 19:00:24 grubba Exp $");
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
@@ -726,6 +726,7 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0
       int f;
       node *check_args = NULL;
       int save_line = lex.current_line;
+      int num_required_args = 0;
 #ifdef PIKE_DEBUG
       struct pike_string *save_file = lex.current_file;
       lex.current_file = $8->current_file;
@@ -743,35 +744,66 @@ def: modifiers type_or_error optional_stars TOK_IDENTIFIER push_compiler_frame0
 	{
 	  my_yyerror("Missing name for argument %d.",e);
 	} else {
-	  if ($1 & ID_VARIANT) {
-	    /* FIXME: Generate code that checks the arguments. */
-	    /* If there is a bad argument, call the fallback, and return. */
-	  } else {
-	    /* FIXME: Should probably use some other flag. */
-	    if ((runtime_options & RUNTIME_CHECK_TYPES) &&
-		(Pike_compiler->compiler_pass == 2) &&
-		(Pike_compiler->compiler_frame->variable[e].type != mixed_type_string)) {
-	      node *local_node;
-
-	      /* fprintf(stderr, "Creating soft cast node for local #%d\n", e);*/
-
-	      local_node = mklocalnode(e, 0);
-
-	      /* The following is needed to go around the optimization in
-	       * mksoftcastnode().
-	       */
-	      free_string(local_node->type);
-	      copy_shared_string(local_node->type, mixed_type_string);
-
-	      check_args =
-		mknode(F_COMMA_EXPR, check_args,
-		       mksoftcastnode(Pike_compiler->compiler_frame->variable[e].type,
-				      local_node));
+	  if (Pike_compiler->compiler_pass == 2) {
+	    if ($1 & ID_VARIANT) {
+	      struct pike_string *arg_type =
+		Pike_compiler->compiler_frame->variable[e].type;
+
+	      /* FIXME: Generate code that checks the arguments. */
+	      /* If there is a bad argument, call the fallback, and return. */
+	      if (! pike_types_le(void_type_string, arg_type)) {
+		/* Argument my not be void.
+		 * ie it's required.
+		 */
+		num_required_args++;
+	      }
+	    } else {
+	      /* FIXME: Should probably use some other flag. */
+	      if ((runtime_options & RUNTIME_CHECK_TYPES) &&
+		  (Pike_compiler->compiler_frame->variable[e].type != mixed_type_string)) {
+		node *local_node;
+
+		/* fprintf(stderr, "Creating soft cast node for local #%d\n", e);*/
+
+		local_node = mklocalnode(e, 0);
+
+		/* The following is needed to go around the optimization in
+		 * mksoftcastnode().
+		 */
+		free_string(local_node->type);
+		copy_shared_string(local_node->type, mixed_type_string);
+
+		check_args =
+		  mknode(F_COMMA_EXPR, check_args,
+			 mksoftcastnode(Pike_compiler->compiler_frame->variable[e].type,
+					local_node));
+	      }
 	    }
 	  }
 	}
       }
 
+      if ($1 & ID_VARIANT) {
+	int i = isidentifier($4->u.sval.u.string);
+	struct pike_string *bad_arg_str;
+	MAKE_CONSTANT_SHARED_STRING(bad_arg_str,
+				    "Bad number of arguments!\n");
+
+	fprintf(stderr, "Required args: %d\n", num_required_args);
+
+	check_args =
+	  mknode('?',
+		 mkopernode("`<",
+			    mkefuncallnode("query_num_arg", NULL),
+			    mkintnode(num_required_args)),
+		 mknode(':',
+			mkefuncallnode("throw",
+				       mkefuncallnode("aggregate",
+						      mkstrnode(bad_arg_str))),
+			NULL));
+	free_string(bad_arg_str);
+      }
+
       if (check_args) {
 	/* Prepend the arg checking code. */
 	$10 = mknode(F_COMMA_EXPR, mknode(F_POP_VALUE, check_args, NULL), $10);
@@ -1574,16 +1606,21 @@ lambda: TOK_LAMBDA push_compiler_frame1
       free_string(Pike_compiler->compiler_frame->current_return_type);
     copy_shared_string(Pike_compiler->compiler_frame->current_return_type,any_type_string);
   }
-  func_args failsafe_block
+  func_args
+  {
+    $<number>$ = Pike_compiler->varargs;
+    Pike_compiler->varargs = 0;
+  }
+  failsafe_block
   {
     struct pike_string *type;
     char buf[40];
     int f,e;
     struct pike_string *name;
     
-    debug_malloc_touch($5);
-    $5=mknode(F_COMMA_EXPR,$5,mknode(F_RETURN,mkintnode(0),0));
-    type=find_return_type($5);
+    debug_malloc_touch($6);
+    $6=mknode(F_COMMA_EXPR,$6,mknode(F_RETURN,mkintnode(0),0));
+    type=find_return_type($6);
 
     if(type) {
       push_finished_type(type);
@@ -1592,15 +1629,15 @@ lambda: TOK_LAMBDA push_compiler_frame1
       push_type(T_MIXED);
     
     e=$4-1;
-    if(Pike_compiler->varargs)
+    if($<number>5)
     {
       push_finished_type(Pike_compiler->compiler_frame->variable[e].type);
       e--;
-      Pike_compiler->varargs=0;
       pop_type_stack();
     }else{
       push_type(T_VOID);
     }
+    Pike_compiler->varargs=0;
     push_type(T_MANY);
     for(; e>=0; e--)
       push_finished_type(Pike_compiler->compiler_frame->variable[e].type);
@@ -1620,7 +1657,7 @@ lambda: TOK_LAMBDA push_compiler_frame1
 #endif /* LAMBDA_DEBUG */
     
     f=dooptcode(name,
-		$5,
+		$6,
 		type,
 		ID_STATIC | ID_PRIVATE | ID_INLINE);