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

Code before:
                // this makes the operator not symmetrical, but so far we do not care.
                // it is really a matter of which error gets reported.
                return;
            }
            else
            {
                // Merging two viable results together. We will always end up with at least two symbols.
                _symbolList.AddRange(other._symbolList);
            }
        }

        internal void MergeEqual(SingleLookupResult result)
        {
            if (Kind > result.Kind)
            {
                // existing result is better
            }
            else if (result.Kind > Kind)
            {
                this.SetFrom(result);
            }
            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.

Review comment (suggestion):
Consider a name like `isNonGenericVersusGeneric` instead, so that the terms in the function name are in the same order as the tests we do on the parameters.

Currently the name reads as if we are trying to decide whether we prefer or not an incoming generic symbol over a non-generic symbol. But that's not really what it's doing.

Code after:
                // this makes the operator not symmetrical, but so far we do not care.
                // it is really a matter of which error gets reported.
                return;
            }
            else
            {
                // Merging two viable results together. We will always end up with at least two symbols.
                _symbolList.AddRange(other._symbolList);
            }
        }

        internal void MergeEqual(SingleLookupResult result)
        {
            if (Kind > result.Kind)
            {
                // Existing result is strictly better.  Ignore what is incoming.  
                return;
            }

            if (result.Kind > Kind)
            {
                // 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;