Repository: dotnet/roslyn
File: src/Compilers/CSharp/Portable/Binder/LookupResult.cs (C#)

Code before:
            else if (Kind == LookupResultKind.WrongArity && result.Kind == LookupResultKind.WrongArity)
            {
                // When both results are WrongArity, prefer reporting errors about generic types
                // over non-generic types to provide more helpful error messages
                if (preferGenericOverNonGeneric(this.SingleSymbolOrDefault, result.Symbol))
                {
                    this.SetFrom(result);
                }
                else if (!preferGenericOverNonGeneric(result.Symbol, this.SingleSymbolOrDefault))
                {
                    // Neither is preferred, add both symbols
                    if ((object)result.Symbol != null)
                    {
                        _symbolList.Add(result.Symbol);
                    }
                }
                // else: existing result is preferred (generic over non-generic), keep it
            }
            else if ((object)result.Symbol != null)
            {
                // Same goodness. Include all symbols
                _symbolList.Add(result.Symbol);
            }

            static bool preferGenericOverNonGeneric(Symbol firstSymbol, Symbol secondSymbol)
                => firstSymbol is NamedTypeSymbol { Arity: 0 } && secondSymbol is NamedTypeSymbol { Arity: > 0 };
        }

        // global pool
        //TODO: consider if global pool is ok.
        private static readonly ObjectPool<LookupResult> s_poolInstance = CreatePool();

        // if someone needs to create a pool
        internal static ObjectPool<LookupResult> CreatePool()
        {
            ObjectPool<LookupResult> pool = null;
            pool = new ObjectPool<LookupResult>(() => new LookupResult(pool), 128); // we rarely need more than 10
            return pool;
        }

        internal static LookupResult GetInstance()
        {
            var instance = s_poolInstance.Allocate();
            Debug.Assert(instance.IsClear);
            return instance;
        }

        internal void Free()
        {
            this.Clear();
            if (_pool != null)

Review comment (suggestion):
I think we should just use `Symbol.GetArity()` instead of pattern matching, and also test the analogous method case:

```cs
class Program
{
    static void Main()
    {
        // error CS0308: The non-generic method 'Program.M(object)' cannot be used with type arguments
        // (It seems reasonable to prefer `M<T1, T2>` in this case for the same reason as a type.)
        M<int>(default!); 
    }

    void M(object obj) { }
    T2 M<T1, T2>(T1 t) => throw null!;
}
```

Code after:
                // Incoming result is better.  Let it win completely over anything we've built up so far.
                this.SetFrom(result);
                return;
            }

            if (Kind == LookupResultKind.WrongArity && result.Kind == LookupResultKind.WrongArity)
            {
                if (isNonGenericVersusGeneric(result.Symbol, this.SingleSymbolOrDefault))
                {
                    // Current result is generic, and incoming is not.  We just want stick with what we currently have
                    // as the better symbol to be referring to when generics are provided, but arity is wrong.
                    return;
                }

                if (isNonGenericVersusGeneric(this.SingleSymbolOrDefault, result.Symbol))
                {
                    // Current result is non generic, but incoming is generic.  It's strictly the better symbol to be
                    // referring to when generics are provided, but arity is wrong.
                    this.SetFrom(result);
                    return;
                }

                // Neither is preferred, fall through and include all symbols.
            }

            // Same goodness. Include all symbols
            _symbolList.AddIfNotNull(result.Symbol);

            static bool isNonGenericVersusGeneric(Symbol firstSymbol, Symbol secondSymbol)
                => firstSymbol.GetArity() == 0 && secondSymbol.GetArity() > 0;
        }

        // global pool
        //TODO: consider if global pool is ok.
        private static readonly ObjectPool<LookupResult> s_poolInstance = CreatePool();

        // if someone needs to create a pool
        internal static ObjectPool<LookupResult> CreatePool()
        {
            ObjectPool<LookupResult> pool = null;
            pool = new ObjectPool<LookupResult>(() => new LookupResult(pool), 128); // we rarely need more than 10
            return pool;
        }

        internal static LookupResult GetInstance()
        {
            var instance = s_poolInstance.Allocate();
            Debug.Assert(instance.IsClear);
            return instance;
        }