Skip to content

ApiCompat does not notice breaking change in generic constraints #39659

@KalleOlaviNiemitalo

Description

@KalleOlaviNiemitalo
Contributor

Describe the bug

ApiCompat does not notice if the right assembly breaks compatibility by having more constraints on a type parameter than the left assembly. See dotnet/runtime#99878.

To Reproduce

ConstraintApiCompat.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
    <LangVersion>7.3</LangVersion>
  </PropertyGroup>

</Project>

Class1.cs

namespace ConstraintApiCompat
{
    public sealed class Class1<TEnum>
#if !NETSTANDARD
	where TEnum : struct, System.Enum
#endif
    {
        // This is here just to show that ApiCompat works in other respects.
#if NETSTANDARD
	public void Extra() {}
#endif
    }
}

.config/dotnet-tools.json

{
  "version": 1,
  "isRoot": true,
  "tools": {
    "microsoft.dotnet.apicompat.tool": {
      "version": "8.0.203",
      "commands": [
        "apicompat"
      ]
    }
  }
}

Build

dotnet tool restore
dotnet build
dotnet apicompat --left=bin/Debug/netstandard2.0/ConstraintApiCompat.dll --right=bin/Debug/net8.0/ConstraintApiCompat.dll

Expected result

ApiCompat should report at least one API compatibility error about the type constraint:

API compatibility errors between 'bin/Debug/netstandard2.0/ConstraintApiCompat.dll' (left) and 'bin/Debug/net8.0/ConstraintApiCompat.dll' (right):
CPxxxx: Type 'ConstraintApiCompat.Class1<TEnum>' does not have constraints 'where TEnum : struct, System.Enum' on bin/Debug/netstandard2.0/ConstraintApiCompat.dll but has on bin/Debug/net8.0/ConstraintApiCompat.dll
CP0002: Member 'void ConstraintApiCompat.Class1<TEnum>.Extra()' exists on bin/Debug/netstandard2.0/ConstraintApiCompat.dll but not on bin/Debug/net8.0/ConstraintApiCompat.dll
API breaking changes found. If those are intentional, the APICompat suppression file can be updated by specifying the '--generate-suppression-file' parameter.

Actual result

ApiCompat does not report any API compatibility errors about the type constraint:

API compatibility errors between 'bin/Debug/netstandard2.0/ConstraintApiCompat.dll' (left) and 'bin/Debug/net8.0/ConstraintApiCompat.dll' (right):
CP0002: Member 'void ConstraintApiCompat.Class1<TEnum>.Extra()' exists on bin/Debug/netstandard2.0/ConstraintApiCompat.dll but not on bin/Debug/net8.0/ConstraintApiCompat.dll
API breaking changes found. If those are intentional, the APICompat suppression file can be updated by specifying the '--generate-suppression-file' parameter.

Exceptions (if any)

None.

Further technical details

.NET SDK:
 Version:           8.0.202
 Commit:            25674bb2f4
 Workload version:  8.0.200-manifests.a7f084b6

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.19045
 OS Platform: Windows
 RID:         win-x64
 Base Path:   C:\Program Files\dotnet\sdk\8.0.202\

.NET workloads installed:
 [android]
   Installation Source: SDK 8.0.200
   Manifest Version:    34.0.85/8.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.android\34.0.85\WorkloadManifest.json
   Install Type:              Msi

 [aspire]
   Installation Source: SDK 8.0.200
   Manifest Version:    8.0.0-preview.4.24156.9/8.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.0.0-preview.4.24156.9\WorkloadManifest.json
   Install Type:              Msi


Host:
  Version:      8.0.3
  Architecture: x64
  Commit:       9f4b1f5d66

.NET SDKs installed:
  2.1.202 [C:\Program Files\dotnet\sdk]
  2.1.526 [C:\Program Files\dotnet\sdk]
  6.0.420 [C:\Program Files\dotnet\sdk]
  8.0.103 [C:\Program Files\dotnet\sdk]
  8.0.202 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.All 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.28 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 6.0.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.28 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 8.0.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
  x86   [C:\Program Files (x86)\dotnet]
    registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

No IDE.

Activity

ghost added
untriagedRequest triage from a team member
on Mar 21, 2024
ericstj

ericstj commented on Apr 10, 2024

@ericstj
Member

Looks like a gap - I don't see this tracked elsewhere. There was a sketch of support for this in the old API compat, but it wasn't enabled: https://github.com/dotnet/arcade/blob/release/6.0/src/Microsoft.DotNet.ApiCompat/src/Rules/Compat/CannotRemoveGenerics.cs

I'm taking a look at prototyping this.

self-assigned this
on Apr 10, 2024
added this to the 9.0.1xx milestone on Apr 10, 2024
KalleOlaviNiemitalo

KalleOlaviNiemitalo commented on Apr 19, 2024

@KalleOlaviNiemitalo
ContributorAuthor

Now that this has been fixed, I'm curious about whether the fix reveals any other mismatches in reference assemblies, similar to dotnet/runtime#99878. If there are any, will they show up in GitHub Checks for some "Update dependencies" pull request at dotnet/runtime?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

    Development

    Participants

    @ericstj@KalleOlaviNiemitalo

    Issue actions

      ApiCompat does not notice breaking change in generic constraints · Issue #39659 · dotnet/sdk