Skip to content

[API Proposal]: Add ExcludeStatics to RequiresUnreferencedCode and RequiresDynamicCode #117524

@agocke

Description

@agocke

Background and motivation

Adding RequiresUnreferencedCode and RequiresDynamicCode to a type has a unique value that adding it to methods does not: it allows you to address trim warnings inside method overrides or interface implementations without modifying the base method/interface.

Sometimes this is necessary because you cannot modify the base method/interface (e.g., it lives in another library).

Unfortunately, RequiresUnreferencedCode has a second effect that can not be disabled currently: it marks all static members inside the type as RUC. This creates a challenge. If you have an instance method override/implementation that needs RUC, you have to apply it to the type. But if you need to use one of the static methods in a trimmed scenario, that creates a warning. The result is a mandatory suppression somewhere.

As it is a goal to never require users to have to add suppressions to supported scenarios, we need a new piece of functionality: allow users to disable the effect of RUC/RDC on nested static members.

API Proposal

namespace System.Runtime.CompilerServices;

// Existing type
internal sealed class RequiresUnreferencedCodeAttribute : Attribute
{
+    public bool ExcludeStatics { get; init; }
}

// Existing type
internal sealed class RequiresDynamicCodeAttribute : Attribute
{
+    public bool ExcludeStatics { get; init; }
}

API Usage

// Assembly Program, being trimmed
public class Program
{
    public static void Main()
    {
        C.HelperMethod(); // No warning

        C.RucHelper(); // Warning

        using var c = new C(); // Warning on ctor
    }
}


// Assembly C, partially trimmable
[RequiresUnreferencedCode("msg", ExcludeStatics = true)]
public class C : IDisposable
{
    public void Dispose()
    {
        // ... implementation uses RUC
    }

    public static void HelperMethod()
    {
        // ...
    }

    [RequiresUnreferencedCode("msg2")]
    public static void RucHelper()
    {
       // ...
    }
}

Alternative Designs

No response

Risks

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions