File: src/com/google/javascript/jscomp/TypeCheck.java
Issue: Missing type-checks for var_args notation
What steps will reproduce the problem?
1. Compile this:
//-------------------------------------
// ==ClosureCompiler==
// @compilation_level SIMPLE_OPTIMIZATIONS
// @warning_level VERBOSE
// @output_file_name default.js
// @formatting pretty_print
// ==/ClosureCompiler==

/**
* @param {...string} var_args
*/
function foo(var_args) {
    return arguments.length;
}

foo('hello'); // no warning - ok
foo(123); // warning - ok
foo('hello', 123); // no warning! error.
//-------------------------------------

What is the expected output? What do you see instead?
Should get a type-mismatch warning for the second parameter in the third foo() call.

What version of the product are you using? On what operating system?
Both online compiler and the 20100616 release.

Please provide any additional information below.
Seems like the type-checker treats 'var_args' as a single param and thus fails to type check the subsequent parameters.

// Fredrik

Buggy code:
private void visitParameterList(NodeTraversal t, Node call,
    FunctionType functionType) {
  Iterator<Node> arguments = call.children().iterator();
  arguments.next(); // skip the function name

  Iterator<Node> parameters = functionType.getParameters().iterator();
  int ordinal = 0;
  Node parameter = null;
  Node argument = null;
  while (arguments.hasNext() &&
         parameters.hasNext()) {
    // If there are no parameters left in the list, then the while loop
    // above implies that this must be a var_args function.
      parameter = parameters.next();
    argument = arguments.next();
    ordinal++;

    validator.expectArgumentMatchesParameter(t, argument,
        getJSType(argument), getJSType(parameter), call, ordinal);
  }

  int numArgs = call.getChildCount() - 1;
  int minArgs = functionType.getMinArguments();
  int maxArgs = functionType.getMaxArguments();
  if (minArgs > numArgs || maxArgs < numArgs) {
    report(t, call, WRONG_ARGUMENT_COUNT,
            validator.getReadableJSTypeName(call.getFirstChild(), false),
            String.valueOf(numArgs), String.valueOf(minArgs),
            maxArgs != Integer.MAX_VALUE ?
            " and no more than " + maxArgs + " argument(s)" : "");
  }
}

Fixed code:
private void visitParameterList(NodeTraversal t, Node call,
    FunctionType functionType) {
  Iterator<Node> arguments = call.children().iterator();
  arguments.next(); // skip the function name

  Iterator<Node> parameters = functionType.getParameters().iterator();
  int ordinal = 0;
  Node parameter = null;
  Node argument = null;
  while (arguments.hasNext() &&
         (parameters.hasNext() ||
          parameter != null && parameter.isVarArgs())) {
    // If there are no parameters left in the list, then the while loop
    // above implies that this must be a var_args function.
    if (parameters.hasNext()) {
      parameter = parameters.next();
    }
    argument = arguments.next();
    ordinal++;

    validator.expectArgumentMatchesParameter(t, argument,
        getJSType(argument), getJSType(parameter), call, ordinal);
  }

  int numArgs = call.getChildCount() - 1;
  int minArgs = functionType.getMinArguments();
  int maxArgs = functionType.getMaxArguments();
  if (minArgs > numArgs || maxArgs < numArgs) {
    report(t, call, WRONG_ARGUMENT_COUNT,
            validator.getReadableJSTypeName(call.getFirstChild(), false),
            String.valueOf(numArgs), String.valueOf(minArgs),
            maxArgs != Integer.MAX_VALUE ?
            " and no more than " + maxArgs + " argument(s)" : "");
  }
}