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

Inaccessible extension methods should not be considered eligible candidates. #26345

Merged
merged 3 commits into from
Apr 27, 2018

Conversation

gafter
Copy link
Member

@gafter gafter commented Apr 23, 2018

Fixes #25813

@dotnet/roslyn-compiler Please review this small bug fix.

Note that there is a slight regression in the quality of our diagnostics for inaccessible extension methods. I think this is unavoidable unless we go to the two-pass technique used to diagnose problems with non-extension methods (first look for viable methods, then if that fails try again looking for anything, viable or not).

There is also a slight regression in one SemanticModel case caused by SemanticModel attempting to compensate for the fact that we don't take a two-pass approach. I've filed #26344 for that, as fixing it probably requires some deep refactoring of the SemanticModel and binding of overload resolution. Since the cost and risk of that is high and the benefits small, I do not consider that worth doing in this bug fix.

@gafter gafter added this to the 16.0 milestone Apr 23, 2018
@gafter gafter self-assigned this Apr 23, 2018
@gafter gafter requested a review from a team as a code owner April 23, 2018 20:04
@@ -11484,7 +11483,7 @@ static void Main(string[] args)
Assert.Equal(ConversionKind.Identity, semanticInfo.ImplicitConversion.Kind);

Assert.Null(semanticInfo.Symbol);
Assert.Equal(CandidateReason.Inaccessible, semanticInfo.CandidateReason);
Assert.Equal(CandidateReason.OverloadResolutionFailure, semanticInfo.CandidateReason);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -6084,7 +6084,7 @@ private static void CombineExtensionMethodArguments(BoundExpression receiver, An
this.LookupExtensionMethodsInSingleBinder(scope, lookupResult, rightName, arity, options, ref useSiteDiagnostics);
diagnostics.Add(node, useSiteDiagnostics);

if (!lookupResult.IsClear)
if (lookupResult.IsMultiViable)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the bug fix.

@@ -88,7 +88,7 @@ public bool IsExtensionMethodGroup
}

public bool IsLocalFunctionInvocation =>
MethodGroup.Methods.Count == 1 && // Local functions cannot be overloaded
MethodGroup?.Methods.Count == 1 && // Local functions cannot be overloaded
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is another little bug fix while I was in the area. It prevents the debugger from displaying exceptions for this property when viewing the members of a MethodGroupResolution.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Were you able to cover this previous crash case with a test?


In reply to: 183521116 [](ancestors = 183521116)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, because there is no crash. It is just very poor experience in the debugger that I am fixing.

@gafter
Copy link
Member Author

gafter commented Apr 24, 2018

@dotnet/roslyn-compiler Please review this small bug fix.

@jcouv jcouv modified the milestones: 16.0, 15.8 Apr 24, 2018
@jcouv
Copy link
Member

jcouv commented Apr 24, 2018

Since this PR is targeting master, I'm fixing the milestone to be 15.8 instead of 16.0.

@@ -783,9 +783,9 @@ public static void M(string s)
// (4,35): error CS1057: 'Extensions.SomeExtension(string)': static classes cannot contain protected members
// static private protected void SomeExtension(this string s) { } // error: no pp in static class
Diagnostic(ErrorCode.ERR_ProtectedInStatic, "SomeExtension").WithArguments("Extensions.SomeExtension(string)").WithLocation(4, 35),
// (11,11): error CS0122: 'Extensions.SomeExtension(string)' is inaccessible due to its protection level
// (11,11): error CS1061: 'string' does not contain a definition for 'SomeExtension' and no extension method 'SomeExtension' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?)
Copy link
Member

@jcouv jcouv Apr 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no extension [](start = 105, length = 12)

Should the error message be updated to mention accessibility? "... no accessible extension method ..." #Closed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed on making this change.


In reply to: 183898009 [](ancestors = 183898009)

Copy link
Member Author

@gafter gafter Apr 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, sure. #Resolved

// fixed (int* p = new Fixable(1))
Diagnostic(ErrorCode.ERR_ExprCannotBeFixed, "new Fixable(1)").WithLocation(6, 25),
// (6,25): error CS0122: 'FixableExt.GetPinnableReference(Fixable)' is inaccessible due to its protection level
// (6,25): error CS8385: The given expression cannot be used in a fixed statement
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, maybe the message could be tweaked to give hints.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is it currently gives no hints. Should this diagnostic also mention that the method GetPinnableReference could be called if it were found, but that it must be non-static, what its signature should be, and that it could be either an instance or extension method? I think this PR is the wrong place to start educating users about the new feature.

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@333fred 333fred left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, though I like @jcouv's suggestion on tweaking the message.

@gafter
Copy link
Member Author

gafter commented Apr 25, 2018

I've adjusted the diagnostic as suggested (one of the two). Please let me know if there is anything else.

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM Thanks

@@ -11145,5 +11145,33 @@ static void Main()
Diagnostic(ErrorCode.ERR_BadRetType, "F").WithArguments("Program.F(in System.DateTime)", "string").WithLocation(16, 15)
);
}

[Fact, WorkItem(25813, "https://github.com/dotnet/roslyn/issues/25813")]
public void InaccessibleExtensionMethod()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InaccessibleExtensionMethod [](start = 20, length = 27)

It would be interesting to test scenario when there are instance candidates and extension candidates and all of them are inaccessible. What would be the error message and candidates returned by SemanticModel?

Copy link
Contributor

@AlekseyTs AlekseyTs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (iteration 2)

@gafter
Copy link
Member Author

gafter commented Apr 26, 2018

test windows_debug_spanish_unit32_prtest please

@gafter
Copy link
Member Author

gafter commented Apr 27, 2018

test windows_release_vs-integration_prtest please

@gafter gafter merged commit 1c8a900 into dotnet:master Apr 27, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

C# compiler chooses inaccessible extension method over accessible one
4 participants