Skip to content

Annotate MS.CA and MS.CA.C# for trimming#66519

Draft
agocke wants to merge 18 commits intodotnet:mainfrom
agocke:make-trimmable
Draft

Annotate MS.CA and MS.CA.C# for trimming#66519
agocke wants to merge 18 commits intodotnet:mainfrom
agocke:make-trimmable

Conversation

@agocke
Copy link
Member

@agocke agocke commented Jan 22, 2023

Brief description of trimming analysis: when trimming an application, the libraries should be annotated to be trim-compatible or, if that's not possible, to alert the user which APIs will not be compatible with trimming.

Almost all of MS.CA and MS.CA.CSharp are already trimming compatible, it is only native PDB writing which has problems (because it uses built-in COM support, which is basically reflection). The native PDB writing could eventually be moved to use COM wrappers and be made trim-compatible, but right now I've simply marked the APIs incompatible. There are still plenty of useful APIs for consumers, including all the syntax and binding APIs, that don't use PDB emit.

@ghost ghost added the Area-Compilers label Jan 22, 2023
@agocke agocke changed the title Add net6.0 MS.CA and MS.CA.C# build and annotate for trimming Annotate MS.CA and MS.CA.C# for trimming Feb 12, 2023
@agocke agocke force-pushed the make-trimmable branch 2 times, most recently from 96947e8 to d10d229 Compare February 12, 2023 03:45
@agocke agocke marked this pull request as ready for review February 13, 2023 18:09
@agocke agocke requested a review from a team as a code owner February 13, 2023 18:09
@agocke
Copy link
Member Author

agocke commented Feb 13, 2023

@dotnet/roslyn-compiler for review

@agocke
Copy link
Member Author

agocke commented Feb 13, 2023

static LocalizableResourceString()
{
ObjectBinder.RegisterTypeReader(typeof(LocalizableResourceString), reader => new LocalizableResourceString(reader));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need an explanation on why this was removed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fundamentally untrimmable, but the only usage I found was in tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure this isn't used for diagnostics being serialized across processes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried and couldn't find a place where it was used. The integration tests are also passing. I'm not sure how else to verify this.

@agocke agocke requested a review from a team as a code owner March 14, 2023 19:22
@agocke agocke requested a review from a team as a code owner March 14, 2023 19:46
@jaredpar jaredpar self-assigned this Mar 14, 2023
@agocke
Copy link
Member Author

agocke commented Mar 15, 2023

Not sure what's up with roslyn-ci here.

@jaredpar jaredpar closed this Mar 16, 2023
@jaredpar jaredpar reopened this Mar 16, 2023
@agocke
Copy link
Member Author

agocke commented Mar 27, 2023

Looks like the integration-corehost tests are a bit of a disaster. I'm going to ignore them unless someone has specific suggestions.

@agocke
Copy link
Member Author

agocke commented Apr 17, 2023

FYI we're bringing the first version of the COMWrapper source generator online, which will fix the trim issues in Emit, but I'm not going to include that work in this PR.

</PropertyGroup>

<!-- Enable trimming/AOT compat -->
<PropertyGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' AND '$(_TargetFrameworkVersionWithoutV)' &gt;= '6.0'">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net6.0')) ?

@jcouv
Copy link
Member

jcouv commented May 9, 2023

@agocke What's the next step for this PR? We can mark it as draft if it still needs some work to figure out (not quite ready for another look yet), to make room in our review queue.

@agocke
Copy link
Member Author

agocke commented May 9, 2023

Jared's review is stale. This is ready. Next steps are on your side.

AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method |
AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct,
Inherited = false)]
internal sealed class DynamicallyAccessedMembersAttribute : Attribute
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure whether Roslyn has special rules/policies for NuGet dependencies, but would it make sense to leverage PolySharp here rather than manually adding polyfills with ifdefs on new targets? PolySharp handles that automatically, and if size is a concern you can also configure it to only ever polyfill the exact types you need, rather than all available ones. It would also make it simpler to extend this in the future when/if more polyfills were needed.

For instance, for the changes in this PR you'd just need:

<ItemGroup>
  <PackageReference Include="PolySharp" Version="1.13.1" PrivateAssets="all" />
</ItemGroup>
<PropertyGroup>
  <PolySharpIncludeGeneratedTypes>
    System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute;
    System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes;
    System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute;
    System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute;
  </PolySharpIncludeGeneratedTypes>
</PropertyGroup>

@jaredpar jaredpar added this to the Backlog milestone Jul 18, 2023
internal static class TrimWarningMessages
{
internal const string AnalyzerReflectionLoadMessage = "Loading analyzers via reflection is not supported when trimming.";
internal const string NativePdbsNotSupported = "Native PDBs use built-in COM, which is not supported when trimming.";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be fixed with dotnet/symreader#340.

Copy link
Member

@jcouv jcouv Aug 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed link: dotnet/symreader#340
Should we file a roslyn issue to revisit the annotations once that PR is merged?

/// <see cref="ConditionalAttribute"/>. So it is always preserved in the compiled assembly.
/// </remarks>
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
internal sealed class UnconditionalSuppressMessageAttribute : Attribute
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's necessary here. IsExternalInit needs type forwarding to maintain binary compatibility because it gets used in modreqs, while tooling matches this attribute by name (99% sure).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if it's not necessary here I prefer we follow a single pattern.

// See the LICENSE file in the project root for more information.

using System;
using System.Diagnostics.CodeAnalysis;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be reverted?

TestRoundTripType(typeof(int));
TestRoundTripType(typeof(string));
TestRoundTripType(typeof(ObjectSerializationTests));
}
Copy link
Member

@jcouv jcouv Aug 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@agocke General question: could you share a bit about the overall flow/story? In particular, when/where do the messages in the annotations surface to users?
Also, what is the approach you use to find all the methods that need to be instrumented? (how do we know the annotations are complete?)

@jaredpar jaredpar modified the milestones: Backlog, Next Next Aug 25, 2025
@jcouv jcouv marked this pull request as draft September 22, 2025 14:48
@jcouv
Copy link
Member

jcouv commented Sep 22, 2025

@agocke Marked as draft since looks stale. Please un-draft and ping when ready for another look. Thanks

@jcouv jcouv self-assigned this Sep 22, 2025
@phil-allen-msft phil-allen-msft modified the milestones: Next Next, 18.4 Oct 10, 2025
@Sergio0694
Copy link
Contributor

Just for context we hit this in CsWinRT 3.0 as well, as we are shipping a new build tool as a Native AOT binary, which uses the Roslyn APIs to compile Windows Runtime projections from sources at publish time. For now we've had to just suppress all trimming warnings (see here), which seems to still work, but isn't ideal. We'd love to see this merged 🙂

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants