Skip to content

Public types missing from reference assemblies don't work with ParamsSource #1177

@svick

Description

@svick

Consider the following benchmark:

using System;
using System.Collections.Generic;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains.CsProj;

class Program
{
    static void Main() => BenchmarkRunner.Run<Benchmark>();
}

public class MainConfig : ManualConfig
{
    public MainConfig()
    {
         Add(Job.Default.With(Platform.X64).With(CsProjCoreToolchain.NetCoreApp30));
         Options = ConfigOptions.KeepBenchmarkFiles;
    }
}

[Config(typeof(MainConfig))]
public class Benchmark
{
    public static IEnumerable<StringComparer> Comparers =>
        new[] { StringComparer.Ordinal };

    [ParamsSource(nameof(Comparers))]
    public StringComparer Comparer;

    [Benchmark]
    public void B() { }
}

When I attempt to run it, I get the following error:

Job-YBSJDZ.notcs(125,41): error CS0234: The type or namespace name 'OrdinalComparer' does not exist in the namespace 'System' (are you missing an assembly reference?) [C:\code\tmp\hwapp\bin\Release\netcoreapp3.0\Job-YBSJDZ\BenchmarkDotNet.Autogenerated.csproj]

The relevant generated code is:

instance.Comparer = (System.OrdinalComparer)System.Linq.Enumerable.ToArray(Benchmark.Comparers)[0];;

The problem here is that for some reason (dotnet/corert@83bcbe0), the actual type of StringComparer.Ordinal, OrdinalComparer is public, but it does not exist in reference assemblies. This means that the C# compiler won't see it, but the BDN code generator will consider it as the correct type to generate:

while (!(type.IsPublic || type.IsNestedPublic) && type.BaseType != null)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions