// Determines if the given argument is compatible with the given parameter bool IsCompatibleArgument(ArgumentSyntax argument, IParameterSymbol parameter) { var parameterRefKind = parameter.RefKind; if (parameterRefKind == RefKind.None) { if (IsEmptyArgument(argument.Expression)) { // An argument left empty is considered to match any parameter // M(1, $$) // M(1, , 2$$) return(true); } var type = parameter.Type; if (parameter.IsParams && type is IArrayTypeSymbol arrayType && HasImplicitConversion(argument.Expression, arrayType.ElementType)) { return(true); } return(HasImplicitConversion(argument.Expression, type)); } var argumentRefKind = argument.GetRefKind(); if (parameterRefKind == RefKind.In && argumentRefKind == RefKind.None) { // A by-value argument matches an `in` parameter return(true); } if (parameterRefKind == argumentRefKind) { return(true); } return(false); }