Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

semantic model vs extension method group #26344

Open
gafter opened this issue Apr 23, 2018 · 0 comments
Open

semantic model vs extension method group #26344

gafter opened this issue Apr 23, 2018 · 0 comments
Labels
Area-Compilers Bug Concept-Design Debt Engineering Debt, Design Debt, or poor product code quality
Milestone

Comments

@gafter
Copy link
Member

gafter commented Apr 23, 2018

When binding an instance method group, we try twice. First, assuming we will find something applicable, we apply the language rules correctly. Then, if that fails, we are more relaxed and gather even inapplicable and inaccessible candidates. This permits us to produce better diagnostics and information from SemanticModel for failed invocations.

However, we only do one pass for extension methods. As a result the SemanticModel has to do some work on its own to try to reconstruct things. It cannot always do a decent job. Below shows a regression in a test in a recent PR due to this. There was a line that used to read

            Assert.Equal(CandidateReason.Inaccessible, semanticInfo.CandidateReason);

that now reads

            Assert.Equal(CandidateReason.OverloadResolutionFailure, semanticInfo.CandidateReason);

That is because the compiler now avoids considering inaccessible methods when resolving extension methods (this was necessary to fix #25813)

The offending test is

        [WorkItem(542850, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542850")]
        [Fact]
        public void InaccessibleExtensionMethod()
        {
            string sourceCode = @"
using System;
using System.Collections.Generic;
using System.Linq;

public static class Extensions
{
    private static int Goo(this string z) { return 3; }
}

class Program
{
    static void Main(string[] args)
    {
        args[0]./*<bind>*/Goo/*</bind>*/();
    }
}
";
            var semanticInfo = GetSemanticInfoForTest<IdentifierNameSyntax>(sourceCode);

            Assert.Null(semanticInfo.Type);
            Assert.Null(semanticInfo.ConvertedType);
            Assert.Equal(ConversionKind.Identity, semanticInfo.ImplicitConversion.Kind);

            Assert.Null(semanticInfo.Symbol);
            Assert.Equal(CandidateReason.OverloadResolutionFailure, semanticInfo.CandidateReason);
            Assert.Equal(1, semanticInfo.CandidateSymbols.Length);
            var sortedCandidates = semanticInfo.CandidateSymbols.OrderBy(s => s.ToTestDisplayString(), StringComparer.Ordinal).ToArray();
            Assert.Equal("System.Int32 System.String.Goo()", sortedCandidates[0].ToTestDisplayString());
            Assert.Equal(SymbolKind.Method, sortedCandidates[0].Kind);

            Assert.Equal(1, semanticInfo.MethodGroup.Length);
            var sortedMethodGroup = semanticInfo.MethodGroup.OrderBy(s => s.ToTestDisplayString(), StringComparer.Ordinal).ToArray();
            Assert.Equal("System.Int32 System.String.Goo()", sortedMethodGroup[0].ToTestDisplayString());

            Assert.False(semanticInfo.IsCompileTimeConstant);
        }
@gafter gafter added Bug Area-Compilers Concept-Design Debt Engineering Debt, Design Debt, or poor product code quality labels Apr 23, 2018
@gafter gafter added this to the Unknown milestone Apr 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers Bug Concept-Design Debt Engineering Debt, Design Debt, or poor product code quality
Development

No branches or pull requests

1 participant