Skip to content

GenAPI generates incorrect nullable annotations for explicit interface implementations #4722

@safern

Description

@safern
  • Is this issue blocking no
  • Is this issue causing unreasonable pain no

Given an interface:

public interface IFoo {
    object? A(object? sender);
}

and an explicit implementation of this interface:

public class FooImpl : IFoo {
    object? IFoo.A(object? sender);
}

and when the assembly omits private members nullable metadata, so when the [module: NullablePublicOnly(true)] is present on the assembly, the compiler will not emit any nullable metadata for object? IFoo.A(object? sender);, so GenAPI will emit the wrong nullability for return type and parameters, it will emit it based on the closest NullableContextAttribute it finds which is wrong.

What we're missing, is that whenever it is an explicit interface implementation, we should be looking at the implemented member declaration and match that definition. We should be getting the implemented member and mapping the parameter nullability and return type nullability to the original declaration, rather than the member implementation itself. We're missing to do that here for the return type:

WriteTypeName(method.Type, method.ContainingType, method.ReturnValueAttributes, nullableContextValue);

and here for the parameters:

WriteParameters(method.Parameters, method.ContainingType, nullableContextValue, extensionMethod: method.IsExtensionMethod(), acceptsExtraArguments: method.AcceptsExtraArguments);

If it is an explicit implementation we already resolve the implemented interface and the nullability we're implementing it with for generics, so that the signature matches and code is compilable:

IMethodImplementation methodImplementation = method.GetMethodImplementation();

cc: @ericstj @eiriktsarpalis @stephentoub

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-Infrastructure-librariesArea maintained by .NET libraries team: APICompat, AsmDiff, GenAPI, GenFacades, PkgProj, etchelp wanted

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions