feat(AOT): Mark RequiresDynamicCode / RequiresUnreferencedCode#314
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds trim/AOT diagnostic metadata to Argu’s parser creation path so consumers publishing with trimming or Native AOT get clearer warnings about reflection-heavy schema generation.
Changes:
- Adds internal polyfills for
RequiresDynamicCodeAttributeandRequiresUnreferencedCodeAttribute. - Adds trim/AOT warning messages and annotates
ArgumentParser.Create<'Template>. - Adds conditional
IsTrimmable/IsAotCompatibleproject properties for future net8.0-compatible targets.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/Argu/TrimAnnotations.fs |
Defines internal diagnostic attribute polyfills for pre-.NET 7 targets. |
src/Argu/ArgumentParser.fs |
Adds trim/AOT messages and applies attributes to the static parser factory. |
src/Argu/Argu.fsproj |
Includes the new source file and adds conditional trim/AOT metadata properties. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@bartelink @Copilot — both review points addressed in e07cd21. API surface coverageYou and Copilot were right: Schema-building entry points (must be annotated):
Internal pass-through (no fresh reflection — argInfo is already in hand):
The latter group doesn't need annotating: they take an already-computed Build-time validation ("how would we know if new code needs annotations")This is the right question and the answer is: the trim/AOT analysers themselves, provided That's what So the path to a hard build-time gate is:
I deliberately didn't bundle that into this PR — it changes the publish surface and warrants its own discussion. Happy to open a follow-up issue for it (a "validate AOT/trim coverage in CI" tracker), or fold it into the V7-shaped breaking-change window you mentioned on #317. Just say which you'd prefer. The polyfill CI green; all 162 tests pass. |
bartelink
left a comment
There was a problem hiding this comment.
This seems reasonable to merge at this point - I guess my main ask/concern/risk I'm flagging is that we merge it and then don't get to the full delivery of the overall feature. So, let me know if/when you'd like it merged and I'll do so.
|
Very gracious of you to ask for my appro - but it's your repo, so please do as you will! |
…encedCode
* New file TrimAnnotations.fs: internal polyfills in
System.Diagnostics.CodeAnalysis for RequiresDynamicCodeAttribute and
RequiresUnreferencedCodeAttribute. The trimmer and AOT compiler
resolve attributes by full type name, so internal copies in this
assembly are picked up. Guarded with #if !NET7_0_OR_GREATER so a
future multi-target picks up the real BCL attributes.
* ArgumentParser.fs:
- Add module TrimMessages with constant explanatory strings.
- Annotate ArgumentParser.Create<'Template> with both attributes so
AOT-publish consumers see IL3050 and trim-publish consumers see
IL2026, each with a clear message pointing at the underlying
reflection use (MakeGenericType / Activator / FSharpType).
* Argu.fsproj: set IsTrimmable=true and IsAotCompatible=false guarded
with MSBuild IsTargetFrameworkCompatible('net8.0') so netstandard2.0
builds still succeed without NETSDK1212 noise. A future multi-target
pass to net8.0 will activate these flags automatically.
Pure metadata addition. No runtime impact. All 112 tests pass.
# Conflicts:
# src/Argu/Argu.fsproj
# src/Argu/ArgumentParser.fs
…y points Addresses review feedback that the warnings only covered ArgumentParser.Create while several other public APIs also enter the reflection schema-building path (preComputeUnionArgInfo / checkUnionArgInfo via the static lazies on ArgumentParser<'T>). Newly annotated public entry points: - new ArgumentParser<'T>(?programName, ?helpTextMessage, ?usageStringCharacterWidth, ?errorHandler, ?checkStructure) — the primary public constructor - ArgumentParser<'T>.CheckStructure() — forces argInfoWithCheck.Value - toParseResults — top-level helper that goes through Create - tagOf — top-level helper that goes through Create Schema work that goes through the internal (argInfo, ...) constructor (GetSubCommandParser, GetSubCommandParsers, ParseResults.Parser) does not trigger fresh reflection and so does not need annotating: it reuses an argInfo already produced behind one of the annotated entry points. No behaviour change. All 162 tests pass.
e07cd21 to
cbf001f
Compare
feat(AOT): Annotate Create with RequiresDynamicCode / RequiresUnreferencedCode
System.Diagnostics.CodeAnalysis for RequiresDynamicCodeAttribute and
RequiresUnreferencedCodeAttribute. The trimmer and AOT compiler
resolve attributes by full type name, so internal copies in this
assembly are picked up. Guarded with #if !NET7_0_OR_GREATER so a
future multi-target picks up the real BCL attributes.
AOT-publish consumers see IL3050 and trim-publish consumers see
IL2026, each with a clear message pointing at the underlying
reflection use (MakeGenericType / Activator / FSharpType).
with MSBuild IsTargetFrameworkCompatible('net8.0') so netstandard2.0
builds still succeed without NETSDK1212 noise. A future multi-target
pass to net8.0 will activate these flags automatically.
Pure metadata addition. No runtime impact. All 112 tests pass.