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

Method type inference should make inference from explicit lambda return type #56534

Merged
merged 4 commits into from
Sep 24, 2021

Conversation

cston
Copy link
Member

@cston cston commented Sep 19, 2021

Update "type inference" to make an exact inference from an explicit lambda return type.

Proposed spec changes in bold:

The first phase

For each of the method arguments Ei:

  • If Ei is an anonymous function and Ti is a delegate type or expression tree type, an explicit parameter type inference (Explicit parameter type inferences) is made from Ei to Ti and an explicit return type inference is made from Ei to Ti.
  • Otherwise, if Ei has a type U and xi is a value parameter then a lower-bound inference is made from U to Ti.
  • Otherwise, if Ei has a type U and xi is a ref or out parameter then an exact inference is made from U to Ti.
  • Otherwise, no inference is made for this argument.

Explicit return type inference

An explicit return type inference is made from an expression E to a type T in the following way:

  • If E is an anonymous function with explicit return type Ur and T is a delegate type or expression tree type with return type Vr then an exact inference (Exact inferences) is made from Ur to Vr.

See LDM notes.

Fixes #54257

Relates to test plan #52192

@cston cston changed the title Method type inference should make inference from explicit return type Method type inference should make inference from explicit lambda return type Sep 20, 2021
@cston cston marked this pull request as ready for review September 20, 2021 23:19
@cston cston requested a review from a team as a code owner September 20, 2021 23:19
@cston cston added this to the 17.0 milestone Sep 21, 2021
var delegateReturnType = delegateInvokeMethod.ReturnTypeWithAnnotations;
if (!delegateReturnType.HasType)
{
return;
Copy link
Contributor

@AlekseyTs AlekseyTs Sep 21, 2021

Choose a reason for hiding this comment

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

return;

Is this code path reachable? #Closed

@@ -3003,7 +3003,7 @@ private static bool AreCloseEnough(Symbol original, Symbol updated)
private static bool AreLambdaAndNewDelegateSimilar(LambdaSymbol l, NamedTypeSymbol n)
{
var invokeMethod = n.DelegateInvokeMethod;
return invokeMethod.Parameters.SequenceEqual(l.Parameters,
return invokeMethod!.Parameters.SequenceEqual(l.Parameters,
Copy link
Contributor

@AlekseyTs AlekseyTs Sep 21, 2021

Choose a reason for hiding this comment

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

invokeMethod!

Assert instead? #Closed

Copy link
Member Author

Choose a reason for hiding this comment

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

An assert seems redundant since the dereference will fail at runtime regardless.

Copy link
Contributor

Choose a reason for hiding this comment

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

An assert seems redundant since the dereference will fail at runtime regardless.

I think we prefer using asserts to inform nullable analysis about expectations rather than suppressing diagnostics with !.

Copy link
Member

Choose a reason for hiding this comment

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

Chuck swayed me on this in some previous PR, but I don't think we circled back to Jared to update guidelines. If the code would clearly crash, then a suppression seems fine to me (assertion wouldn't add much).
Chuck, let's bring this up to team meeting or with Jared to confirm and capture.

static void F2<T>(Expression<Func<T, T>> x, T y) { Console.WriteLine(x.GetType()); }
static void Main()
{
F1(int (i) => i, (object)1);
Copy link
Contributor

@AlekseyTs AlekseyTs Sep 21, 2021

Choose a reason for hiding this comment

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

F1(int (i) => i, (object)1);

Do we have a test for a scenario when a conflicting types is coming from parameter type of the lambda? #Closed

// (see https://github.com/dotnet/csharplang/blob/main/meetings/2021/LDM-2021-06-21.md).
[WorkItem(54257, "https://github.com/dotnet/roslyn/issues/54257")]
[Fact]
public void TypeInference_ExplicitReturnType_06()
Copy link
Contributor

@AlekseyTs AlekseyTs Sep 21, 2021

Choose a reason for hiding this comment

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

TypeInference_ExplicitReturnType_06

Consider adding a test where the target return type isn't a T, but a generic type closed over T. #Closed

@AlekseyTs
Copy link
Contributor

Done with review pass (commit 1)

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 (commit 2)

@jcouv jcouv self-assigned this Sep 24, 2021

comp = CreateCompilation(source);
comp.VerifyDiagnostics(expectedDiagnostics);
}
Copy link
Member

@jcouv jcouv Sep 24, 2021

Choose a reason for hiding this comment

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

Consider adding a test with the explicit return type having a nullable annotation #Resolved

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 (iteration 2)

@jcouv
Copy link
Member

jcouv commented Sep 24, 2021

@cston Thanks for the spec sections in OP. Are you copying those back into the feature spec as well?

@cston
Copy link
Member Author

cston commented Sep 24, 2021

Are you copying those back into the feature spec as well?

dotnet/csharplang#5217

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 (iteration 4)

@cston cston merged commit 2761372 into dotnet:main Sep 24, 2021
@cston cston deleted the 54257 branch September 24, 2021 15:06
@ghost ghost modified the milestones: 17.0, Next Sep 24, 2021
@Cosifne Cosifne modified the milestones: Next, 17.0.P5 Sep 27, 2021
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.

Method type inference should make inference from explicit lambda return type
4 participants