Skip to content

Commit 7367446

Browse files
authored
Fix IL2091 trimming warning in FSharp.Core LazyExtensions.Create (#19114)
1 parent ce8cf73 commit 7367446

File tree

5 files changed

+63
-14
lines changed

5 files changed

+63
-14
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Fixed
2+
3+
* Fix IL2091 trimming warning in `LazyExtensions.Create` by adding `DynamicallyAccessedMembers` attribute to the generic type parameter. ([Issue #17356](https://github.com/dotnet/fsharp/issues/17356), [PR #18302](https://github.com/dotnet/fsharp/pull/18302))

src/FSharp.Core/prim-types.fs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7299,11 +7299,12 @@ namespace Microsoft.FSharp.Core
72997299
namespace Microsoft.FSharp.Control
73007300

73017301
open System
7302+
open System.Diagnostics.CodeAnalysis
73027303
open Microsoft.FSharp.Core
73037304
open Microsoft.FSharp.Core.Operators
73047305

73057306
module LazyExtensions =
7306-
type Lazy<'T> with
7307+
type Lazy<[<DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)>]'T> with
73077308
[<CompiledName("Create")>] // give the extension member a 'nice', unmangled compiled name, unique within this module
73087309
static member Create(creator : unit -> 'T) : Lazy<'T> =
73097310
let creator = Func<'T>(creator)

src/FSharp.Core/prim-types.fsi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6144,6 +6144,7 @@ namespace Microsoft.FSharp.Core
61446144

61456145
namespace Microsoft.FSharp.Control
61466146

6147+
open System.Diagnostics.CodeAnalysis
61476148
open Microsoft.FSharp.Core
61486149

61496150
/// <summary>Extensions related to Lazy values.</summary>
@@ -6152,7 +6153,7 @@ namespace Microsoft.FSharp.Control
61526153
[<AutoOpen>]
61536154
module LazyExtensions =
61546155

6155-
type System.Lazy<'T> with
6156+
type System.Lazy<[<DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)>]'T> with
61566157

61576158
/// <summary>Creates a lazy computation that evaluates to the result of the given function when forced.</summary>
61586159
///

tests/AheadOfTime/Trimming/Program.fs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9365,6 +9365,20 @@ module NonStructuralComparisonOverTimeSpanDirect =
93659365
do check "test9407" (NonStructuralComparison.hash 11L) (Operators.hash 11L)
93669366
do check "test9408" (NonStructuralComparison.hash 11UL) (Operators.hash 11UL)
93679367

9368+
let testLazySimple () =
9369+
let f23 () = let z = lazy (12345) in z.Force()
9370+
check "lazy_simple" 12345 (f23())
9371+
9372+
let testSeqWithTryFinally () =
9373+
let result =
9374+
seq {
9375+
try
9376+
yield 1
9377+
yield 2
9378+
with
9379+
| ex -> ()
9380+
} |> Seq.toList
9381+
check "seq_try_with" [1; 2] result
93689382

93699383
[<EntryPoint>]
93709384
let main _ =
@@ -9385,6 +9399,8 @@ let main _ =
93859399
PercentAPublicTests.tests ()
93869400
PercentAInternalTests.tests ()
93879401
ClassWithEvents.testWithEventClass ()
9402+
testLazySimple ()
9403+
testSeqWithTryFinally ()
93889404

93899405
match !failures with
93909406
| [] ->
Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,39 @@
1-
function CheckTrim($root, $tfm, $outputfile, $expected_len) {
1+
function CheckTrim($root, $tfm, $outputfile, $expected_len, $callerLineNumber) {
22
Write-Host "Publish and Execute: ${tfm} - ${root}"
33
Write-Host "Expecting ${expected_len} for ${outputfile}"
44

5+
$errors = @()
6+
$scriptFile = $PSCommandPath
7+
58
$cwd = Get-Location
69
Set-Location (Join-Path $PSScriptRoot "${root}")
710
$build_output = dotnet publish -restore -c release -f:$tfm "${root}.fsproj" -bl:"../../../../artifacts/log/Release/AheadOfTime/Trimming/${root}_${tfm}.binlog"
811
Set-Location ${cwd}
912
if ($LASTEXITCODE -ne 0)
1013
{
11-
Write-Error "Build failed with exit code ${LASTEXITCODE}"
12-
Write-Error "${build_output}" -ErrorAction Stop
14+
$errors += "Build failed with exit code ${LASTEXITCODE}"
15+
Write-Host "##vso[task.logissue type=error;sourcepath=${scriptFile};linenumber=${callerLineNumber}]Build failed for ${root} with exit code ${LASTEXITCODE}"
16+
return $errors
1317
}
1418

1519
$process = Start-Process -FilePath $(Join-Path $PSScriptRoot "${root}\bin\release\${tfm}\win-x64\publish\${root}.exe") -Wait -NoNewWindow -PassThru -RedirectStandardOutput $(Join-Path $PSScriptRoot "output.txt")
1620

1721
# Checking that the test passed
1822
$output = Get-Content $(Join-Path $PSScriptRoot output.txt)
1923
$expected = "All tests passed"
20-
if ($LASTEXITCODE -ne 0)
24+
if ($process.ExitCode -ne 0)
2125
{
22-
Write-Error "Test failed with exit code ${LASTEXITCODE}" -ErrorAction Stop
26+
$errors += "Test failed with exit code $($process.ExitCode)"
27+
Write-Host "##vso[task.logissue type=error;sourcepath=${scriptFile};linenumber=${callerLineNumber}]Test execution failed for ${root} with exit code $($process.ExitCode)"
2328
}
24-
if ($output -eq $expected)
29+
elseif ($output -ne $expected)
2530
{
26-
Write-Host "Test passed"
31+
$errors += "Test failed with unexpected output: Expected '${expected}', Actual '${output}'"
32+
Write-Host "##vso[task.logissue type=error;sourcepath=${scriptFile};linenumber=${callerLineNumber}]Test failed for ${root} with unexpected output: Expected '${expected}', Actual '${output}'"
2733
}
2834
else
2935
{
30-
Write-Error "Test failed with unexpected output:`nExpected:`n`t${expected}`nActual`n`t${output}" -ErrorAction Stop
36+
Write-Host "Test passed"
3137
}
3238

3339
# Checking that the trimmed outputfile binary is of expected size (needs adjustments if test is updated).
@@ -39,24 +45,46 @@ function CheckTrim($root, $tfm, $outputfile, $expected_len) {
3945
}
4046
elseif ($file_len -ne $expected_len)
4147
{
42-
Write-Error "Test failed with unexpected ${tfm} - trimmed ${outputfile} length:`nExpected:`n`t${expected_len} Bytes`nActual:`n`t${file_len} Bytes`nEither codegen or trimming logic have changed. Please investigate and update expected dll size or report an issue." -ErrorAction Stop
48+
$errors += "Test failed with unexpected ${tfm} - trimmed ${outputfile} length: Expected ${expected_len} Bytes, Actual ${file_len} Bytes"
49+
Write-Host "##vso[task.logissue type=error;sourcepath=${scriptFile};linenumber=${callerLineNumber}]Trimmed ${outputfile} size mismatch for ${root}: Expected ${expected_len} Bytes, Actual ${file_len} Bytes. Either codegen or trimming logic have changed. Please investigate and update expected dll size or report an issue."
4350
}
4451

4552
$fileBeforePublish = Get-Item (Join-Path $PSScriptRoot "${root}\bin\release\${tfm}\win-x64\${outputfile}")
4653
$sizeBeforePublish = $fileBeforePublish.Length
4754
$sizeDiff = $sizeBeforePublish - $file_len
4855
Write-Host "Size of ${tfm} - ${outputfile} before publish: ${sizeBeforePublish} Bytes, which means the diff is ${sizeDiff} Bytes"
56+
57+
return $errors
4958
}
5059

5160
# NOTE: Trimming now errors out on desktop TFMs, as shown below:
5261
# error NETSDK1124: Trimming assemblies requires .NET Core 3.0 or higher.
5362

63+
$allErrors = @()
64+
5465
# Check net9.0 trimmed assemblies
55-
CheckTrim -root "SelfContained_Trimming_Test" -tfm "net9.0" -outputfile "FSharp.Core.dll" -expected_len 300032
66+
$allErrors += CheckTrim -root "SelfContained_Trimming_Test" -tfm "net9.0" -outputfile "FSharp.Core.dll" -expected_len 311296 -callerLineNumber 66
5667

5768
# Check net9.0 trimmed assemblies with static linked FSharpCore
58-
CheckTrim -root "StaticLinkedFSharpCore_Trimming_Test" -tfm "net9.0" -outputfile "StaticLinkedFSharpCore_Trimming_Test.dll" -expected_len 9154048
69+
$allErrors += CheckTrim -root "StaticLinkedFSharpCore_Trimming_Test" -tfm "net9.0" -outputfile "StaticLinkedFSharpCore_Trimming_Test.dll" -expected_len 9169408 -callerLineNumber 69
5970

6071
# Check net9.0 trimmed assemblies with F# metadata resources removed
61-
CheckTrim -root "FSharpMetadataResource_Trimming_Test" -tfm "net9.0" -outputfile "FSharpMetadataResource_Trimming_Test.dll" -expected_len 7607296
72+
$allErrors += CheckTrim -root "FSharpMetadataResource_Trimming_Test" -tfm "net9.0" -outputfile "FSharpMetadataResource_Trimming_Test.dll" -expected_len 7609344 -callerLineNumber 72
73+
74+
# Report all errors and exit with failure if any occurred
75+
if ($allErrors.Count -gt 0) {
76+
Write-Host ""
77+
Write-Host "============================================"
78+
Write-Host "TRIMMING TESTS FAILED"
79+
Write-Host "============================================"
80+
Write-Host "Total errors: $($allErrors.Count)"
81+
foreach ($err in $allErrors) {
82+
Write-Error $err
83+
}
84+
exit 1
85+
}
6286

87+
Write-Host ""
88+
Write-Host "============================================"
89+
Write-Host "ALL TRIMMING TESTS PASSED"
90+
Write-Host "============================================"

0 commit comments

Comments
 (0)