Ejemplo n.º 1
0
        void RunTypeInference(Candidate candidate)
        {
            IMethod method = candidate.Member as IMethod;

            if (method == null || method.TypeParameters.Count == 0)
            {
                if (explicitlyGivenTypeArguments != null)
                {
                    // method does not expect type arguments, but was given some
                    candidate.AddError(OverloadResolutionErrors.WrongNumberOfTypeArguments);
                }
                return;
            }
            // The method is generic:
            if (explicitlyGivenTypeArguments != null)
            {
                if (explicitlyGivenTypeArguments.Length == method.TypeParameters.Count)
                {
                    candidate.InferredTypes = explicitlyGivenTypeArguments;
                }
                else
                {
                    candidate.AddError(OverloadResolutionErrors.WrongNumberOfTypeArguments);
                    // wrong number of type arguments given, so truncate the list or pad with UnknownType
                    candidate.InferredTypes = new IType[method.TypeParameters.Count];
                    for (int i = 0; i < candidate.InferredTypes.Length; i++)
                    {
                        if (i < explicitlyGivenTypeArguments.Length)
                        {
                            candidate.InferredTypes[i] = explicitlyGivenTypeArguments[i];
                        }
                        else
                        {
                            candidate.InferredTypes[i] = SharedTypes.UnknownType;
                        }
                    }
                }
            }
            else
            {
                TypeInference ti = new TypeInference(context, conversions);
                bool          success;
                candidate.InferredTypes = ti.InferTypeArguments(method.TypeParameters, arguments, candidate.ParameterTypes, out success);
                if (!success)
                {
                    candidate.AddError(OverloadResolutionErrors.TypeInferenceFailed);
                }
            }
            // Now substitute in the formal parameters:
            var substitution = new ConstraintValidatingSubstitution(candidate.InferredTypes, this);

            for (int i = 0; i < candidate.ParameterTypes.Length; i++)
            {
                candidate.ParameterTypes[i] = candidate.ParameterTypes[i].AcceptVisitor(substitution);
            }
            if (!substitution.ConstraintsValid)
            {
                candidate.AddError(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint);
            }
        }
Ejemplo n.º 2
0
		void MapCorrespondingParameters(Candidate candidate)
		{
			// C# 4.0 spec: §7.5.1.1 Corresponding parameters
			candidate.ArgumentToParameterMap = new int[arguments.Length];
			for (int i = 0; i < arguments.Length; i++) {
				candidate.ArgumentToParameterMap[i] = -1;
				if (argumentNames[i] == null) {
					// positional argument
					if (i < candidate.ParameterTypes.Length) {
						candidate.ArgumentToParameterMap[i] = i;
					} else if (candidate.IsExpandedForm) {
						candidate.ArgumentToParameterMap[i] = candidate.ParameterTypes.Length - 1;
					} else {
						candidate.AddError(OverloadResolutionErrors.TooManyPositionalArguments);
					}
				} else {
					// named argument
					for (int j = 0; j < candidate.Parameters.Count; j++) {
						if (argumentNames[i] == candidate.Parameters[j].Name) {
							candidate.ArgumentToParameterMap[i] = j;
						}
					}
					if (candidate.ArgumentToParameterMap[i] < 0)
						candidate.AddError(OverloadResolutionErrors.NoParameterFoundForNamedArgument);
				}
			}
		}
Ejemplo n.º 3
0
        void MapCorrespondingParameters(Candidate candidate)
        {
            // C# 4.0 spec: §7.5.1.1 Corresponding parameters
            // Updated for C# 7.2 non-trailing named arguments
            candidate.ArgumentToParameterMap = new int[arguments.Length];
            bool hasPositionalArgument = false;

            // go backwards, so that hasPositionalArgument tells us whether there
            // are non-trailing named arguments
            for (int i = arguments.Length - 1; i >= 0; i--)
            {
                candidate.ArgumentToParameterMap[i] = -1;
                if (argumentNames[i] == null || hasPositionalArgument)
                {
                    hasPositionalArgument = true;
                    // positional argument or non-trailing named argument
                    if (i < candidate.ParameterTypes.Length)
                    {
                        candidate.ArgumentToParameterMap[i] = i;
                        if (argumentNames[i] != null && argumentNames[i] != candidate.Parameters[i].Name)
                        {
                            // non-trailing named argument must match name
                            candidate.AddError(OverloadResolutionErrors.NoParameterFoundForNamedArgument);
                        }
                    }
                    else if (candidate.IsExpandedForm)
                    {
                        candidate.ArgumentToParameterMap[i] = candidate.ParameterTypes.Length - 1;
                        if (argumentNames[i] != null)
                        {
                            // can't use non-trailing named argument here
                            candidate.AddError(OverloadResolutionErrors.NoParameterFoundForNamedArgument);
                        }
                    }
                    else
                    {
                        candidate.AddError(OverloadResolutionErrors.TooManyPositionalArguments);
                    }
                }
                else
                {
                    // (trailing) named argument
                    for (int j = 0; j < candidate.Parameters.Count; j++)
                    {
                        if (argumentNames[i] == candidate.Parameters[j].Name)
                        {
                            candidate.ArgumentToParameterMap[i] = j;
                        }
                    }
                    if (candidate.ArgumentToParameterMap[i] < 0)
                    {
                        candidate.AddError(OverloadResolutionErrors.NoParameterFoundForNamedArgument);
                    }
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Adds a candidate to overload resolution.
        /// </summary>
        /// <param name="member">The candidate member to add.</param>
        /// <param name="additionalErrors">Additional errors that apply to the candidate.
        /// This is used to represent errors during member lookup (e.g. OverloadResolutionErrors.Inaccessible)
        /// in overload resolution.</param>
        /// <returns>The errors that prevent the member from being applicable, if any.
        /// Note: this method does not return errors that do not affect applicability.</returns>
        public OverloadResolutionErrors AddCandidate(IParameterizedMember member, OverloadResolutionErrors additionalErrors)
        {
            if (member == null)
            {
                throw new ArgumentNullException("member");
            }

            Candidate c = new Candidate(member, false);

            c.AddError(additionalErrors);
            if (CalculateCandidate(c))
            {
                //candidates.Add(c);
            }

            if (this.AllowExpandingParams && member.Parameters.Count > 0 &&
                member.Parameters[member.Parameters.Count - 1].IsParams)
            {
                Candidate expandedCandidate = new Candidate(member, true);
                expandedCandidate.AddError(additionalErrors);
                // consider expanded form only if it isn't obviously wrong
                if (CalculateCandidate(expandedCandidate))
                {
                    //candidates.Add(expandedCandidate);

                    if (expandedCandidate.ErrorCount < c.ErrorCount)
                    {
                        return(expandedCandidate.Errors);
                    }
                }
            }
            return(c.Errors);
        }
Ejemplo n.º 5
0
		void CheckApplicability(Candidate candidate)
		{
			// C# 4.0 spec: §7.5.3.1 Applicable function member
			
			// Test whether parameters were mapped the correct number of arguments:
			int[] argumentCountPerParameter = new int[candidate.ParameterTypes.Length];
			foreach (int parameterIndex in candidate.ArgumentToParameterMap) {
				if (parameterIndex >= 0)
					argumentCountPerParameter[parameterIndex]++;
			}
			for (int i = 0; i < argumentCountPerParameter.Length; i++) {
				if (candidate.IsExpandedForm && i == argumentCountPerParameter.Length - 1)
					continue; // any number of arguments is fine for the params-array
				if (argumentCountPerParameter[i] == 0) {
					if (candidate.Parameters[i].IsOptional)
						candidate.HasUnmappedOptionalParameters = true;
					else
						candidate.AddError(OverloadResolutionErrors.MissingArgumentForRequiredParameter);
				} else if (argumentCountPerParameter[i] > 1) {
					candidate.AddError(OverloadResolutionErrors.MultipleArgumentsForSingleParameter);
				}
			}
			
			candidate.ArgumentConversions = new Conversion[arguments.Length];
			// Test whether argument passing mode matches the parameter passing mode
			for (int i = 0; i < arguments.Length; i++) {
				int parameterIndex = candidate.ArgumentToParameterMap[i];
				if (parameterIndex < 0) continue;
				
				ByReferenceResolveResult brrr = arguments[i] as ByReferenceResolveResult;
				if (brrr != null) {
					if ((brrr.IsOut && !candidate.Parameters[parameterIndex].IsOut) || (brrr.IsRef && !candidate.Parameters[parameterIndex].IsRef))
						candidate.AddError(OverloadResolutionErrors.ParameterPassingModeMismatch);
				} else {
					if (candidate.Parameters[parameterIndex].IsOut || candidate.Parameters[parameterIndex].IsRef)
						candidate.AddError(OverloadResolutionErrors.ParameterPassingModeMismatch);
				}
				IType parameterType = candidate.ParameterTypes[parameterIndex];
				Conversion c = conversions.ImplicitConversion(arguments[i], parameterType);
				candidate.ArgumentConversions[i] = c;
				if (IsExtensionMethodInvocation && parameterIndex == 0) {
					// First parameter to extension method must be an identity, reference or boxing conversion
					if (!(c == Conversion.IdentityConversion || c == Conversion.ImplicitReferenceConversion || c == Conversion.BoxingConversion))
						candidate.AddError(OverloadResolutionErrors.ArgumentTypeMismatch);
				} else {
					if (!c.IsValid)
						candidate.AddError(OverloadResolutionErrors.ArgumentTypeMismatch);
				}
			}
		}
Ejemplo n.º 6
0
        void RunTypeInference(Candidate candidate)
        {
            if (candidate.TypeParameters == null)
            {
                if (explicitlyGivenTypeArguments != null)
                {
                    // method does not expect type arguments, but was given some
                    candidate.AddError(OverloadResolutionErrors.WrongNumberOfTypeArguments);
                }
                // Grab new parameter types:
                ResolveParameterTypes(candidate, true);
                return;
            }
            ParameterizedType parameterizedDeclaringType = candidate.Member.DeclaringType as ParameterizedType;
            IList <IType>     classTypeArguments;

            if (parameterizedDeclaringType != null)
            {
                classTypeArguments = parameterizedDeclaringType.TypeArguments;
            }
            else
            {
                classTypeArguments = null;
            }
            // The method is generic:
            if (explicitlyGivenTypeArguments != null)
            {
                if (explicitlyGivenTypeArguments.Length == candidate.TypeParameters.Count)
                {
                    candidate.InferredTypes = explicitlyGivenTypeArguments;
                }
                else
                {
                    candidate.AddError(OverloadResolutionErrors.WrongNumberOfTypeArguments);
                    // wrong number of type arguments given, so truncate the list or pad with UnknownType
                    candidate.InferredTypes = new IType[candidate.TypeParameters.Count];
                    for (int i = 0; i < candidate.InferredTypes.Length; i++)
                    {
                        if (i < explicitlyGivenTypeArguments.Length)
                        {
                            candidate.InferredTypes[i] = explicitlyGivenTypeArguments[i];
                        }
                        else
                        {
                            candidate.InferredTypes[i] = SpecialType.UnknownType;
                        }
                    }
                }
            }
            else
            {
                TypeInference ti = new TypeInference(compilation, conversions);
                bool          success;
                candidate.InferredTypes = ti.InferTypeArguments(candidate.TypeParameters, arguments, candidate.ParameterTypes, out success, classTypeArguments);
                if (!success)
                {
                    candidate.AddError(OverloadResolutionErrors.TypeInferenceFailed);
                }
            }
            // Now substitute in the formal parameters:
            var substitution = new ConstraintValidatingSubstitution(classTypeArguments, candidate.InferredTypes, this);

            for (int i = 0; i < candidate.ParameterTypes.Length; i++)
            {
                candidate.ParameterTypes[i] = candidate.ParameterTypes[i].AcceptVisitor(substitution);
            }
            if (!substitution.ConstraintsValid)
            {
                candidate.AddError(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint);
            }
        }
Ejemplo n.º 7
0
		void CheckApplicability(Candidate candidate)
		{
			// C# 4.0 spec: §7.5.3.1 Applicable function member
			
			// Test whether parameters were mapped the correct number of arguments:
			int[] argumentCountPerParameter = new int[candidate.ParameterTypes.Length];
			foreach (int parameterIndex in candidate.ArgumentToParameterMap) {
				if (parameterIndex >= 0)
					argumentCountPerParameter[parameterIndex]++;
			}
			for (int i = 0; i < argumentCountPerParameter.Length; i++) {
				if (candidate.IsExpandedForm && i == argumentCountPerParameter.Length - 1)
					continue; // any number of arguments is fine for the params-array
				if (argumentCountPerParameter[i] == 0) {
					if (candidate.Parameters[i].IsOptional)
						candidate.HasUnmappedOptionalParameters = true;
					else
						candidate.AddError(OverloadResolutionErrors.MissingArgumentForRequiredParameter);
				} else if (argumentCountPerParameter[i] > 1) {
					candidate.AddError(OverloadResolutionErrors.MultipleArgumentsForSingleParameter);
				}
			}
			
			candidate.ArgumentConversions = new Conversion[arguments.Length];
			// Test whether argument passing mode matches the parameter passing mode
			for (int i = 0; i < arguments.Length; i++) {
				int parameterIndex = candidate.ArgumentToParameterMap[i];
				if (parameterIndex < 0) continue;
				
				ByReferenceResolveResult brrr = arguments[i] as ByReferenceResolveResult;
				if (brrr != null) {
					if ((brrr.IsOut && !candidate.Parameters[parameterIndex].IsOut) || (brrr.IsRef && !candidate.Parameters[parameterIndex].IsRef))
						candidate.AddError(OverloadResolutionErrors.ParameterPassingModeMismatch);
				} else {
					if (candidate.Parameters[parameterIndex].IsOut || candidate.Parameters[parameterIndex].IsRef)
						candidate.AddError(OverloadResolutionErrors.ParameterPassingModeMismatch);
				}
				IType parameterType = candidate.ParameterTypes[parameterIndex];
				Conversion c = conversions.ImplicitConversion(arguments[i], parameterType);
				candidate.ArgumentConversions[i] = c;
				if (IsExtensionMethodInvocation && parameterIndex == 0) {
					// First parameter to extension method must be an identity, reference or boxing conversion
					if (!(c == Conversion.IdentityConversion || c == Conversion.ImplicitReferenceConversion || c == Conversion.BoxingConversion))
						candidate.AddError(OverloadResolutionErrors.ArgumentTypeMismatch);
				} else {
					if (!c.IsValid)
						candidate.AddError(OverloadResolutionErrors.ArgumentTypeMismatch);
				}
			}
		}
Ejemplo n.º 8
0
		void RunTypeInference(Candidate candidate)
		{
			IMethod method = candidate.Member as IMethod;
			if (method == null || method.TypeParameters.Count == 0) {
				if (explicitlyGivenTypeArguments != null) {
					// method does not expect type arguments, but was given some
					candidate.AddError(OverloadResolutionErrors.WrongNumberOfTypeArguments);
				}
				return;
			}
			ParameterizedType parameterizedDeclaringType = candidate.Member.DeclaringType as ParameterizedType;
			IList<IType> classTypeArguments;
			if (parameterizedDeclaringType != null) {
				classTypeArguments = parameterizedDeclaringType.TypeArguments;
			} else {
				classTypeArguments = null;
			}
			// The method is generic:
			if (explicitlyGivenTypeArguments != null) {
				if (explicitlyGivenTypeArguments.Length == method.TypeParameters.Count) {
					candidate.InferredTypes = explicitlyGivenTypeArguments;
				} else {
					candidate.AddError(OverloadResolutionErrors.WrongNumberOfTypeArguments);
					// wrong number of type arguments given, so truncate the list or pad with UnknownType
					candidate.InferredTypes = new IType[method.TypeParameters.Count];
					for (int i = 0; i < candidate.InferredTypes.Length; i++) {
						if (i < explicitlyGivenTypeArguments.Length)
							candidate.InferredTypes[i] = explicitlyGivenTypeArguments[i];
						else
							candidate.InferredTypes[i] = SpecialType.UnknownType;
					}
				}
			} else {
				TypeInference ti = new TypeInference(compilation, conversions);
				bool success;
				candidate.InferredTypes = ti.InferTypeArguments(candidate.TypeParameters, arguments, candidate.ParameterTypes, out success, classTypeArguments);
				if (!success)
					candidate.AddError(OverloadResolutionErrors.TypeInferenceFailed);
			}
			// Now substitute in the formal parameters:
			var substitution = new ConstraintValidatingSubstitution(classTypeArguments, candidate.InferredTypes, this);
			for (int i = 0; i < candidate.ParameterTypes.Length; i++) {
				candidate.ParameterTypes[i] = candidate.ParameterTypes[i].AcceptVisitor(substitution);
			}
			if (!substitution.ConstraintsValid)
				candidate.AddError(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint);
		}
Ejemplo n.º 9
0
		void MapCorrespondingParameters(Candidate candidate)
		{
			// C# 4.0 spec: §7.5.1.1 Corresponding parameters
			candidate.ArgumentToParameterMap = new int[arguments.Length];
			for (int i = 0; i < arguments.Length; i++) {
				candidate.ArgumentToParameterMap[i] = -1;
				if (argumentNames[i] == null) {
					// positional argument
					if (i < candidate.ParameterTypes.Length) {
						candidate.ArgumentToParameterMap[i] = i;
					} else if (candidate.IsExpandedForm) {
						candidate.ArgumentToParameterMap[i] = candidate.ParameterTypes.Length - 1;
					} else {
						candidate.AddError(OverloadResolutionErrors.TooManyPositionalArguments);
					}
				} else {
					// named argument
					for (int j = 0; j < candidate.Parameters.Count; j++) {
						if (argumentNames[i] == candidate.Parameters[j].Name) {
							candidate.ArgumentToParameterMap[i] = j;
						}
					}
					if (candidate.ArgumentToParameterMap[i] < 0)
						candidate.AddError(OverloadResolutionErrors.NoParameterFoundForNamedArgument);
				}
			}
		}
Ejemplo n.º 10
0
		public OverloadResolutionErrors AddCandidate(IParameterizedMember member, OverloadResolutionErrors additionalErrors)
		{
			if (member == null)
				throw new ArgumentNullException("member");
			
			Candidate c = new Candidate(member, false);
			if (additionalErrors != OverloadResolutionErrors.None)
				c.AddError(additionalErrors);
			if (CalculateCandidate(c)) {
				//candidates.Add(c);
			}
			
			if (this.AllowExpandingParams && member.Parameters.Count > 0
			    && member.Parameters[member.Parameters.Count - 1].IsParams)
			{
				Candidate expandedCandidate = new Candidate(member, true);
				if (additionalErrors != OverloadResolutionErrors.None)
					expandedCandidate.AddError(additionalErrors);
				// consider expanded form only if it isn't obviously wrong
				if (CalculateCandidate(expandedCandidate)) {
					//candidates.Add(expandedCandidate);
					
					if (expandedCandidate.ErrorCount < c.ErrorCount)
						return expandedCandidate.Errors;
				}
			}
			return c.Errors;
		}
Ejemplo n.º 11
0
        void CheckApplicability(Candidate candidate)
        {
            // C# 4.0 spec: §7.5.3.1 Applicable function member

            // Test whether parameters were mapped the correct number of arguments:
            int[] argumentCountPerParameter = new int[candidate.ParameterTypes.Length];
            foreach (int parameterIndex in candidate.ArgumentToParameterMap)
            {
                if (parameterIndex >= 0)
                {
                    argumentCountPerParameter[parameterIndex]++;
                }
            }
            for (int i = 0; i < argumentCountPerParameter.Length; i++)
            {
                if (candidate.IsExpandedForm && i == argumentCountPerParameter.Length - 1)
                {
                    continue;                     // any number of arguments is fine for the params-array
                }
                if (argumentCountPerParameter[i] == 0)
                {
                    if (candidate.Parameters[i].IsOptional)
                    {
                        candidate.HasUnmappedOptionalParameters = true;
                    }
                    else
                    {
                        candidate.AddError(OverloadResolutionErrors.MissingArgumentForRequiredParameter);
                    }
                }
                else if (argumentCountPerParameter[i] > 1)
                {
                    candidate.AddError(OverloadResolutionErrors.MultipleArgumentsForSingleParameter);
                }
            }

            // Test whether argument passing mode matches the parameter passing mode
            for (int i = 0; i < arguments.Length; i++)
            {
                int parameterIndex = candidate.ArgumentToParameterMap[i];
                if (parameterIndex < 0)
                {
                    continue;
                }

                ByReferenceResolveResult brrr = arguments[i] as ByReferenceResolveResult;
                if (brrr != null)
                {
                    if ((brrr.IsOut && !candidate.Parameters[parameterIndex].IsOut) || (brrr.IsRef && !candidate.Parameters[parameterIndex].IsRef))
                    {
                        candidate.AddError(OverloadResolutionErrors.ParameterPassingModeMismatch);
                    }
                }
                else
                {
                    if (candidate.Parameters[parameterIndex].IsOut || candidate.Parameters[parameterIndex].IsRef)
                    {
                        candidate.AddError(OverloadResolutionErrors.ParameterPassingModeMismatch);
                    }
                }
                if (!conversions.ImplicitConversion(arguments[i], candidate.ParameterTypes[parameterIndex]))
                {
                    candidate.AddError(OverloadResolutionErrors.ArgumentTypeMismatch);
                }
            }
        }
Ejemplo n.º 12
0
        void CheckApplicability(Candidate candidate)
        {
            // C# 4.0 spec: §7.5.3.1 Applicable function member

            // Test whether parameters were mapped the correct number of arguments:
            int[] argumentCountPerParameter = new int[candidate.ParameterTypes.Length];
            foreach (int parameterIndex in candidate.ArgumentToParameterMap) {
                if (parameterIndex >= 0)
                    argumentCountPerParameter[parameterIndex]++;
            }
            for (int i = 0; i < argumentCountPerParameter.Length; i++) {
                if (candidate.IsExpandedForm && i == argumentCountPerParameter.Length - 1)
                    continue; // any number of arguments is fine for the params-array
                if (argumentCountPerParameter[i] == 0) {
                    if (candidate.Parameters[i].IsOptional)
                        candidate.HasUnmappedOptionalParameters = true;
                    else
                        candidate.AddError(OverloadResolutionErrors.MissingArgumentForRequiredParameter);
                } else if (argumentCountPerParameter[i] > 1) {
                    candidate.AddError(OverloadResolutionErrors.MultipleArgumentsForSingleParameter);
                }
            }

            // Test whether argument passing mode matches the parameter passing mode
            for (int i = 0; i < arguments.Length; i++) {
                int parameterIndex = candidate.ArgumentToParameterMap[i];
                if (parameterIndex < 0) continue;

                ByReferenceResolveResult brrr = arguments[i] as ByReferenceResolveResult;
                if (brrr != null) {
                    if ((brrr.IsOut && !candidate.Parameters[parameterIndex].IsOut) || (brrr.IsRef && !candidate.Parameters[parameterIndex].IsRef))
                        candidate.AddError(OverloadResolutionErrors.ParameterPassingModeMismatch);
                } else {
                    if (candidate.Parameters[parameterIndex].IsOut || candidate.Parameters[parameterIndex].IsRef)
                        candidate.AddError(OverloadResolutionErrors.ParameterPassingModeMismatch);
                }
                if (!conversions.ImplicitConversion(arguments[i], candidate.ParameterTypes[parameterIndex]))
                    candidate.AddError(OverloadResolutionErrors.ArgumentTypeMismatch);
            }
        }
 void MapCorrespondingParameters(Candidate candidate)
 {
     candidate.ArgumentToParameterMap = new int[arguments.Length];
     for(int i = 0; i < arguments.Length; ++i){
         candidate.ArgumentToParameterMap[i] = -1;
         // positional argument
         if(i < candidate.ParameterTypes.Length)
             candidate.ArgumentToParameterMap[i] = i;
         else if(candidate.IsExpandedForm)
             candidate.ArgumentToParameterMap[i] = candidate.ParameterTypes.Length - 1;
         else
             candidate.AddError(OverloadResolutionErrors.TooManyPositionalArguments);
     }
 }
        void CheckApplicability(Candidate candidate)
        {
            // C# 4.0 spec: §7.5.3.1 Applicable function member

            // Test whether parameters were mapped the correct number of arguments:
            int[] argument_count_per_parameter = new int[candidate.ParameterTypes.Length];
            foreach(int parameter_index in candidate.ArgumentToParameterMap){
                if(parameter_index >= 0)
                    argument_count_per_parameter[parameter_index]++;
            }

            for(int i = 0; i < argument_count_per_parameter.Length; ++i){
                if(candidate.IsExpandedForm && i == argument_count_per_parameter.Length - 1)
                    continue; // any number of arguments is fine for the params-array

                if(argument_count_per_parameter[i] == 0)
                    candidate.AddError(OverloadResolutionErrors.MissingArgumentForRequiredParameter);
                else if(argument_count_per_parameter[i] > 1)
                    candidate.AddError(OverloadResolutionErrors.MultipleArgumentsForSingleParameter);
            }

            // Test whether types of arguments match that of parameters
            for(int i = 0; i < arguments.Length; ++i){
                int parameterIndex = candidate.ArgumentToParameterMap[i];
                IType parameter_type = candidate.ParameterTypes[parameterIndex];
                if(!MatchType(arguments[i], parameter_type))
                    candidate.AddError(OverloadResolutionErrors.ArgumentTypeMismatch);
            }
        }