Skip to content

ILLinker is trimming interfaces from some public types when on "library" mode #2238

@joperezr

Description

@joperezr

For additional context, you can look into: dotnet/runtime#57816 (comment)

We are using "library" mode to trim some of our assemblies in dotnet/runtime repo, and just found out that when a public type has an internal constructor, and this constructor doesn't get called inside the assembly, the linker seems to be trimming out non public members from that type, including explicit implementation of interfaces as well as declaration of interface implementations themselves. The more specific scenario we have in dotnet/runtime is a generated source code that looks like this:

    public sealed partial class AceEnumerator : System.Collections.IEnumerator
    {
        internal AceEnumerator() { throw new System.PlatformNotSupportedException(System.SR.PlatformNotSupported_AccessControl);  }
        public System.Security.AccessControl.GenericAce Current { get { throw new System.PlatformNotSupportedException(System.SR.PlatformNotSupported_AccessControl);  } }
        object System.Collections.IEnumerator.Current { get { throw new System.PlatformNotSupportedException(System.SR.PlatformNotSupported_AccessControl);  } }
        public bool MoveNext() { throw new System.PlatformNotSupportedException(System.SR.PlatformNotSupported_AccessControl);  }
        public void Reset() { throw new System.PlatformNotSupportedException(System.SR.PlatformNotSupported_AccessControl);  }
    }

In this case, AceEnumerator ctor is internal and because the whole source code of the assembly is generated (it all throws PlatformNotSupportedException) then nobody calls this internal constructor, so the Linker is trimming parts of the type and removing the interface from the type. The resulting type post-trimming looks like this:
image

After speaking about this offline with @sbomer, we reached the conclusion that ideally the linker shouldn't be removing interfaces from public types when in "library" mode, independently from whether they could be instantiated or not. Interface implementations are part of the public visible contract of a type, so in library mode they should be kept.

cc: @eerhardt @sbomer @vitek-karas

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions