Skip to content

[ILC/Android NativeAOT] FeatureGuard does not suppress IL3050 after PR #124801 decoupled ILC from ManagedAssemblyToLink #127017

@PureWeen

Description

@PureWeen

Description

[FeatureGuard(typeof(RequiresDynamicCodeAttribute))] + [FeatureSwitchDefinition] on a feature switch property correctly suppresses IL3050 warnings on all NativeAOT platforms except Android. The regression appeared between SDK builds 26166.111 and 26203.107.

Bisect

SDK dotnet/runtime SHA Android AOT
11.0.100-preview.3.26166.111 c38f37a3a1c3 ✅ No IL3050
11.0.100-preview.3.26203.107 d23e53a91dcd ❌ IL3050 emitted

No MAUI code changed between these builds — only the SDK version bump (dotnet/maui#34852).

Root Cause: PR #124801

"Decouple ILC from ManagedAssemblyToLink" (15da4216aef1) landed between these two runtime SHAs. This PR:

  1. Removed _ComputeManagedAssemblyForILLink from Microsoft.NETCore.Native.targets
  2. Changed @(ManagedAssemblyToLink) construction from @(ManagedBinary) to @(IntermediateAssembly)
  3. Was specifically made for Android NativeAOT where RunILLink=true

The Android SDK (36.99.0-preview.3.10) already has a partial workaround referencing this PR (clearing _IlcManagedInputAssemblies), confirming it disrupted the Android NativeAOT pipeline. The IL3050 regression appears to be a residual effect.

Why Android-Only

Platform RunILLink Feature switch processing
iOS/macCatalyst/macOS false ILC is the sole trimmer — applies --feature substitution directly ✅
Android true ILLink runs first, then ILC gets linked output. PR #124801 changed this flow ❌

On non-Android platforms, ILC reads all original assemblies and applies feature switches internally via --feature:Microsoft.Maui.RuntimeFeature.IsHybridWebViewSupported=false. This works correctly.

On Android (RunILLink=true), the decoupling in PR #124801 appears to have disrupted how RuntimeHostConfigurationOption items flow to ILC's --feature arguments, or ILC is now receiving a mix of linked/unlinked assemblies where the feature switch hasn't been substituted.

Reproduction

In dotnet/maui, RuntimeFeature.IsHybridWebViewSupported is configured with:

  • [FeatureSwitchDefinition] + [FeatureGuard(typeof(RequiresDynamicCodeAttribute))]
  • MSBuild: MauiHybridWebViewSupported=false when PublishAot=true, mapped to RuntimeHostConfigurationOption with Trim="true"

The guarded call site:

if (RuntimeFeature.IsHybridWebViewSupported)
{
    AddHybridWebViewHandler(handlersCollection); // [RequiresDynamicCode]
}

dotnet publish -r osx-arm64 -p:PublishAot=true → no IL3050 ✅
dotnet publish -r android-arm64 -p:PublishAot=true → IL3050 emitted ❌

Suggested Investigation

A binlog comparison between the two SDK versions would confirm the exact failure point:

  • Are --feature: flags present for IsHybridWebViewSupported in ILC's command line on Android?
  • Does @(ManagedAssemblyToLink) contain linked or unlinked Microsoft.Maui assemblies when ILC runs?
  • Did the _IlcManagedInputAssemblies clearing workaround in the Android SDK affect ILC's analysis scope?

MAUI Workaround

Applied [UnconditionalSuppressMessage] on the helper method (dotnet/maui#34986), matching the pattern used by ServiceProvider in dotnet/runtime per dotnet/linker#2715.

Context

cc @AustinWise @sbomer @simonrozsival

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

Status

No status

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions