-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Fix ArgumentsSource on external types not working if the argument type is not primitive #2820
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
Conversation
I thought sample benchmark IntroArgumentsSource.cs also needs to be fixed. Currently IntroArgumentsSource benchmark failed with following errors.
|
Thanks, nice catch. Should be fixed now! |
I'm trying to understand what was broken before. When I run the tests, they succeed. Can you add tests that failed previously that pass with this change? |
What is currently broken is that if you try to use
I address this in the PR description as well. I was also confused by the tests passing, since if you create an example project using my example code it does not work. Does our test infra not currently check the generated code at all? If it does, why did it miss this compiler error, and if it doesn't, how should we go about adding that capability? Before I add tests to this PR, I was hoping somebody with knowledge about our test infra would chime in with some insight. Such a person giving quick answers to the above questions would save me hours of investigating our very complicated test infra myself, which would be nice since it already took me hours of investigation to figure out the cause of this issue and figure out how to fix it. It seems like you didn't understand the information in the PR description. I'm sorry if I presented the information unclearly. Do you have any advice for how I can make my writing easier to understand? |
There doesn't seem to be anything wrong with the test infrastructure. I copied the existing tests to a new benchmark project, and they still succeed. It appears to be due to the arg type |
Catches some issues not previously caught.
Aha, you're completely correct. Thanks a lot! The primitive types got inlined as literals in the generated code which is why the bug wasn't triggered by them. I added some more test cases that use non-primitive types. I've confirmed that the new tests fail before this PR and pass after this PR. I've also updated the PR title and description to reflect this improved understanding of the bug. |
Thanks. Can you also update the ParamsSource tests? |
Done 😎 |
Co-authored-by: Tim Cassell <[email protected]>
Updated [BenchmarkDotNet](https://github.com/dotnet/BenchmarkDotNet) from 0.15.2 to 0.15.3. <details> <summary>Release notes</summary> _Sourced from [BenchmarkDotNet's releases](https://github.com/dotnet/BenchmarkDotNet/releases)._ ## 0.15.3 Full changelog: https://benchmarkdotnet.org/changelog/v0.15.3.html ## Highlights Improvements: - Naot instruction set support for .NET 10+, migrate to ISA groupings in CPU summary [#2828](dotnet/BenchmarkDotNet#2828) - Support benchmark filtering for TestAdapter [#2662](dotnet/BenchmarkDotNet#2662) [#2788](dotnet/BenchmarkDotNet#2788) - Support non-primitive external types in `ArgumentsSource` [#2820](dotnet/BenchmarkDotNet#2820) - Enable MSBuild parallel build via `--nodeReuse:false` [#2693](dotnet/BenchmarkDotNet#2693) [#2814](dotnet/BenchmarkDotNet#2814) - Improve CPU detection [#2747](dotnet/BenchmarkDotNet#2747) [#2749](dotnet/BenchmarkDotNet#2749) - Enable assembly signing for debug build [#2774](dotnet/BenchmarkDotNet#2774) Deprecations: - Deprecated `WithNuget` [#2812](dotnet/BenchmarkDotNet#2812) Bug fixes: - Fix `InvalidOperationException` in diagnosers [#2758](dotnet/BenchmarkDotNet#2758) [#2805](dotnet/BenchmarkDotNet#2805) - Fix file detection in `NativeMemoryProfiler` [#2794](dotnet/BenchmarkDotNet#2794) [#2795](dotnet/BenchmarkDotNet#2795) - Fix long file paths issue in `EtwProfiler` [#2807](dotnet/BenchmarkDotNet#2807) [#2808](dotnet/BenchmarkDotNet#2808) - Fix log duplications in TestAdapter [#2790](dotnet/BenchmarkDotNet#2790) - Fix x86 disassembler error for net462 [#2792](dotnet/BenchmarkDotNet#2792) - Fix `IsNetCore` and `IsNativeAOT` for single-file apps without AOT [#2799](dotnet/BenchmarkDotNet#2799) - Fix density plot generation in `RPlotExporter` for latest version of R [#2809](dotnet/BenchmarkDotNet#2809) Commits viewable in [compare view](dotnet/BenchmarkDotNet@v0.15.2...v0.15.3). </details> Updated [BenchmarkDotNet.Annotations](https://github.com/dotnet/BenchmarkDotNet) from 0.15.2 to 0.15.3. <details> <summary>Release notes</summary> _Sourced from [BenchmarkDotNet.Annotations's releases](https://github.com/dotnet/BenchmarkDotNet/releases)._ ## 0.15.3 Full changelog: https://benchmarkdotnet.org/changelog/v0.15.3.html ## Highlights Improvements: - Naot instruction set support for .NET 10+, migrate to ISA groupings in CPU summary [#2828](dotnet/BenchmarkDotNet#2828) - Support benchmark filtering for TestAdapter [#2662](dotnet/BenchmarkDotNet#2662) [#2788](dotnet/BenchmarkDotNet#2788) - Support non-primitive external types in `ArgumentsSource` [#2820](dotnet/BenchmarkDotNet#2820) - Enable MSBuild parallel build via `--nodeReuse:false` [#2693](dotnet/BenchmarkDotNet#2693) [#2814](dotnet/BenchmarkDotNet#2814) - Improve CPU detection [#2747](dotnet/BenchmarkDotNet#2747) [#2749](dotnet/BenchmarkDotNet#2749) - Enable assembly signing for debug build [#2774](dotnet/BenchmarkDotNet#2774) Deprecations: - Deprecated `WithNuget` [#2812](dotnet/BenchmarkDotNet#2812) Bug fixes: - Fix `InvalidOperationException` in diagnosers [#2758](dotnet/BenchmarkDotNet#2758) [#2805](dotnet/BenchmarkDotNet#2805) - Fix file detection in `NativeMemoryProfiler` [#2794](dotnet/BenchmarkDotNet#2794) [#2795](dotnet/BenchmarkDotNet#2795) - Fix long file paths issue in `EtwProfiler` [#2807](dotnet/BenchmarkDotNet#2807) [#2808](dotnet/BenchmarkDotNet#2808) - Fix log duplications in TestAdapter [#2790](dotnet/BenchmarkDotNet#2790) - Fix x86 disassembler error for net462 [#2792](dotnet/BenchmarkDotNet#2792) - Fix `IsNetCore` and `IsNativeAOT` for single-file apps without AOT [#2799](dotnet/BenchmarkDotNet#2799) - Fix density plot generation in `RPlotExporter` for latest version of R [#2809](dotnet/BenchmarkDotNet#2809) Commits viewable in [compare view](dotnet/BenchmarkDotNet@v0.15.2...v0.15.3). </details> Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Followup to #2748. As of BDN 0.15.2, you can't use
[ArgumentsSource]
with an external type providing the arguments if the argument type is not primitive. This happens because the generated code has compiler errors.The issue
If you have code like this:
Then BDN currently generates code like this:
The problem is that
MethodACases
is not in the type that the generated class (Runnable_0
) inherits from, it's in an external type (DiagnosticsCases
). So there's a compiler error here ("error CS0103: The name 'MethodACases' does not exist in the current context")This only happens if the argument type is non-primitive (like
MethodACase
). If it's a primitive type (likeint
) then the argument value is inlined as a literal, instead of usingParameterExtractor
.The fix
In this example, we need to put the fully qualified type name before the method call. The last line of the generated code should instead read:
However, we can't always add the fully qualified type name, because
ArgumentsSource
can also be used with non-static methods/properties.So, this PR checks if
ArgumentsSource
is being used with a static type. If so, the fully qualified type name is added at this location; otherwise, the generated code is unchanged compared to before this PR.I am worried about external instance methods
Using
ArgumentsSource
for non-primitive arguments with different kinds of members:As you can see from this helpful table, this PR fixes one broken case but there is still one broken case remaining. How best to fix this? Should the generated code create an instance of the member's type, and call the member from the new instance?
To be honest, I think there's no benefit to supporting instance members at all. @timcassell also dislikes that we support instance members and we discussed it a bit here: #2744 (comment).
Maybe we should take this opportunity to just drop support for instance members in
ArgumentsSource
andParamsSource
?Other things I am worried about