List<AnalyzeArgumentResult> (@NotNull PyCallableParameter container, @NotNull List<PyExpression> arguments, @NotNull PyTypeChecker.GenericSubstitutions substitutions) { final PyType expected = container.getArgumentType(myTypeEvalContext); if (container.isPositionalContainer() && expected instanceof PyVariadicType) { PyUnpackedTupleType argumentTypes = PyUnpackedTupleTypeImpl.create(ContainerUtil.map(arguments, myTypeEvalContext::getType)); boolean matched = matchParameterAndArgument(expected, argumentTypes, null, substitutions); return ContainerUtil.map(arguments, argument -> { PyType expectedWithSubstitutions = substituteGenerics(expected, substitutions); // TODO Don't duplicate the message of each argument, highlight an entire series of them return new AnalyzeArgumentResult(argument, expected, expectedWithSubstitutions, argumentTypes, matched); }); } // For an expected type with generics we have to match all the actual types against it in order to do proper generic unification if (PyTypeChecker.hasGenerics(expected, myTypeEvalContext)) { // First collect type parameter substitutions by matching the expected type with the union. PyType actualJoin = PyUnionType.union(ContainerUtil.map(arguments, myTypeEvalContext::getType)); matchParameterAndArgument(expected, actualJoin, null, substitutions); PyType expectedWithSubstitutions = substituteGenerics(expected, substitutions); return ContainerUtil.map(arguments, argument -> { // Then match each argument type against the expected type after these substitutions. PyType actual = myTypeEvalContext.getType(argument); boolean matched = matchParameterAndArgument(expected, actual, argument, substitutions); return new AnalyzeArgumentResult(argument, expected, expectedWithSubstitutions, actual, matched); }); } else { return ContainerUtil.map( arguments, argument -> { PyType actual = myTypeEvalContext.getType(argument); boolean matched = matchParameterAndArgument(expected, actual, argument, substitutions); PyType expectedWithSubstitutions = substituteGenerics(expected, substitutions); return new AnalyzeArgumentResult(argument, expected, expectedWithSubstitutions, actual, matched); } ); } }