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

Fix overload resolution with constrained generic method #1581

Merged
merged 1 commit into from Mar 3, 2023

Conversation

exyi
Copy link
Member

@exyi exyi commented Feb 12, 2023

For example, given two methods M1(int a) and M1(T a) where T: IEnumerable, dotvvm would try to call MakeGenericMethod on the second overload, which throws an exception and fails the entire binding compilation. Now the exception is handled and other overloads are tried before failing compilation with "could not find overload" error.

Note that I tried to verify the constraints before calling the MakeGenericMethod, but it seems impossible to figure out some C# type constraints from reflection, for example new() and unmanaged. MakeGenericMethod at least checks new(), but it doesn't check unmanaged either. At least now we can blame the bug one someone else.

This change has the disadvantage that if you only had one overload, you'd get a nice error explaining why the type parameters could not be assigned. Now you'll only get a generic "no matching overload" error

cc @martindybal

For example, given two methods M1(int a) and M1<T>(T a) where T: IEnumerable,
dotvvm would try to call MakeGenericMethod on the second overload,
which throws an exception and fails the entire binding compilation.
Now the exception is handled and other overloads are tried before
failing compilation with "could not find overload" error.

Note that I tried to verify the constraints before calling the
MakeGenericMethod, but it seems impossible to figure out
some C# type constraints from reflection, for example
new() and unmanaged. MakeGenericMethod at least checks
new(), but it doesn't check unmanaged either. At least now we
can blame the bug one someone else.

This change has the disadvantage that if you only had one overload,
you'd get a nice error explaining why the type parameters
could not be assigned. Now you'll only get a generic
"no matching overload" error
@acizmarik
Copy link
Member

We can actually extract some information about type parameters: https://learn.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/how-to-examine-and-instantiate-generic-types-with-reflection. See the usage, for example about GenericParameterAttributes.DefaultConstructorConstraint

It could be nice to support at least the most common ones and leave more complicated stuff to the try-catch

@acizmarik acizmarik added this to the Version 4.1 milestone Feb 15, 2023
@acizmarik acizmarik merged commit dee0da3 into main Mar 3, 2023
@acizmarik acizmarik deleted the fix-typeconstrained-overloads branch March 3, 2023 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants