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

Do not include function type conversions in user-defined conversions #56416

Merged
merged 6 commits into from
Sep 24, 2021

Conversation

cston
Copy link
Member

@cston cston commented Sep 15, 2021

Removes "function type conversions" from the set of "standard conversions" so that function type conversions (from the inferred type of a lambda expression or method group to Delegate, Expression or a base type) are not considered for user-defined conversions.

Fixes #56407

Relates to test plan #52192

@@ -642,6 +642,9 @@ private static bool IsEncompassingImplicitConversionKind(ConversionKind kind)

// Added for C# 7.1
case ConversionKind.DefaultLiteral:

// Added for C# 10.
case ConversionKind.FunctionType:
Copy link
Member Author

Choose a reason for hiding this comment

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

case ConversionKind.FunctionType:

Follow up with language design: should a function type conversion be considered an "encompassing" implicit conversion?

@cston cston force-pushed the 56407 branch 3 times, most recently from c9825eb to 958c08f Compare September 17, 2021 21:52
@cston cston changed the title Allow user-defined conversions from lambda expressions or method groups to Delegate, Expression, and base types Handle user-defined conversions from lambda expressions or method groups to Delegate, Expression, and base types Sep 18, 2021
@cston cston force-pushed the 56407 branch 2 times, most recently from 68be73b to f8c5df3 Compare September 19, 2021 04:22
@cston cston marked this pull request as ready for review September 19, 2021 05:29
@cston cston requested a review from a team as a code owner September 19, 2021 05:29
@cston cston changed the title Handle user-defined conversions from lambda expressions or method groups to Delegate, Expression, and base types Do not include function type conversions in user-defined conversions Sep 19, 2021
@@ -118,6 +119,13 @@ public Conversion ClassifyImplicitConversionFromExpression(BoundExpression sourc
}
}
}
else if (sourceExpression.GetFunctionType() is { })
{
if (IsValidFunctionTypeConversionTarget(destination, ref useSiteInfo))
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.

if (IsValidFunctionTypeConversionTarget(destination, ref useSiteInfo))

Should we also check conversions between two Function Types? #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.

The only code paths that should have to handle conversions between two function types are BestTypeInferrer and MethodTypeInferrer in cases where "bounds" are merged. Those code paths use ClassifyImplicitConversionFromTypeOrImplicitFunctionTypeConversion().

Copy link
Member Author

Choose a reason for hiding this comment

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

Added handling of conversions between function types.

}

Debug.Assert(false);
return Conversion.NoConversion;
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 Conversion.NoConversion

It is not clear why conversions to System.MulticastDelegate and the like are not checked. #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.

The only callers of this method are BestTypeInferrer and MethodTypeInferrer in cases where "bounds" are merged. In those cases, there are either two function types or two types that are not function types, so conversions from function type to non-function type do not need to be considered.

return conversion;
}

private Conversion ClassifyStandardImplicitConversionInternal(TypeSymbol source, TypeSymbol destination, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
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.

ClassifyStandardImplicitConversionInternal

It looks like there is only one call site. Consider making this a local function. #Closed

{
Debug.Assert((object)source != null);
Debug.Assert((object)destination != null);
Debug.Assert(source is not FunctionTypeSymbol);
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.

Debug.Assert(source is not FunctionTypeSymbol);

It feels like it would be better to handle this input rather than asserting that it doesn't occur. #Closed

{
if (IsValidFunctionTypeConversionTarget(destination, ref useSiteInfo))
{
return Conversion.FunctionType;
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 Conversion.FunctionType;

Is this an implicit conversion? It feels like the name of the function implies that implicit conversions should be ignored. #Closed

@@ -258,8 +258,8 @@ bool populateDisposableConversionOrDisposeMethod(bool fromExpression, out Conver
Conversion classifyConversion(bool fromExpression, TypeSymbol targetInterface, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
{
return fromExpression ?
originalBinder.Conversions.ClassifyImplicitConversionFromExpression(expressionOpt, targetInterface, ref useSiteInfo) :
originalBinder.Conversions.ClassifyImplicitConversionFromType(declarationTypeOpt, targetInterface, ref useSiteInfo);
originalBinder.Conversions.ClassifyImplicitConversionFromExpression(expressionOpt!, targetInterface, ref useSiteInfo) :
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.

!

Do we usually prefer asserts to suppressions? #Closed

@AlekseyTs
Copy link
Contributor

Done with review pass (commit 3)

@cston cston requested a review from a team September 22, 2021 23:39
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 6)

@cston cston requested a review from a team September 24, 2021 15:30
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 (commit 6)

@cston cston merged commit 3913f35 into dotnet:main Sep 24, 2021
@ghost ghost modified the milestones: 17.0, Next Sep 24, 2021
@cston cston deleted the 56407 branch September 24, 2021 23:24
@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
4 participants