diff --git a/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs b/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs
index 280f1908f79f03..0e95901f271aca 100644
--- a/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs
+++ b/src/tools/illink/src/linker/Linker.Steps/MarkStep.cs
@@ -477,7 +477,6 @@ bool ProcessMarkedPending ()
foreach (var type in Annotations.GetPendingPreserve ()) {
marked = true;
- Debug.Assert (Annotations.IsProcessed (type));
ApplyPreserveInfo (type);
}
@@ -2785,7 +2784,7 @@ void ApplyPreserveInfo (TypeDefinition type)
if (Annotations.TryGetPreserve (type, out TypePreserve preserve)) {
if (!Annotations.SetAppliedPreserve (type, preserve))
- throw new InternalErrorException ($"Type {type} already has applied {preserve}.");
+ return;
var di = new DependencyInfo (DependencyKind.TypePreserve, type);
diff --git a/src/tools/illink/src/linker/Linker/Annotations.cs b/src/tools/illink/src/linker/Linker/Annotations.cs
index 68c8c320749966..bfcfe56e7d71e7 100644
--- a/src/tools/illink/src/linker/Linker/Annotations.cs
+++ b/src/tools/illink/src/linker/Linker/Annotations.cs
@@ -34,7 +34,6 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
-using System.Reflection.Metadata.Ecma335;
using ILLink.Shared.TrimAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
@@ -303,25 +302,12 @@ public bool SetAppliedPreserve (TypeDefinition type, TypePreserve preserve)
return true;
}
- public bool HasAppliedPreserve (TypeDefinition type, TypePreserve preserve)
- {
- if (!preserved_types.TryGetValue (type, out (TypePreserve preserve, bool applied) existing))
- throw new InternalErrorException ($"Type {type} must have a TypePreserve before it can be applied.");
-
- if (preserve != existing.preserve)
- throw new InternalErrorException ($"Type {type} does not have {preserve}. The TypePreserve may have changed before the call to {nameof (HasAppliedPreserve)}.");
-
- return existing.applied;
- }
-
public void SetPreserve (TypeDefinition type, TypePreserve preserve)
{
Debug.Assert (preserve != TypePreserve.Nothing);
if (!preserved_types.TryGetValue (type, out (TypePreserve preserve, bool applied) existing)) {
preserved_types.Add (type, (preserve, false));
if (IsProcessed (type)) {
- // Required to track preserve for marked types where the existing preserve
- // was Nothing (since these aren't explicitly tracked.)
var addedPending = pending_preserve.Add (type);
Debug.Assert (addedPending);
}
diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/CommandLine/CustomStepApplyPreserve.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/CommandLine/CustomStepApplyPreserve.cs
new file mode 100644
index 00000000000000..ae48755d7fedfd
--- /dev/null
+++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/CommandLine/CustomStepApplyPreserve.cs
@@ -0,0 +1,35 @@
+using System;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Metadata;
+
+namespace Mono.Linker.Tests.Cases.CommandLine
+{
+ [SetupCompileBefore ("CustomApplyPreserveStep.dll", new[] { "Dependencies/CustomApplyPreserveStep.cs" }, new[] { "illink.dll", "Mono.Cecil.dll" }, addAsReference: false)]
+ [SetupLinkerArgument ("--custom-step", "-MarkStep:CustomStep.CustomApplyPreserveStep,CustomApplyPreserveStep.dll")]
+ [SetupLinkerArgument ("--verbose")]
+ public class CustomStepApplyPreserve
+ {
+ [Kept]
+ public class HasPreserveApplied
+ {
+ [Kept]
+ public int Field;
+
+ [Kept]
+ public HasPreserveApplied () { }
+
+ [Kept]
+ public void Method ()
+ {
+ }
+
+ public class Nested { }
+ }
+
+ [Kept]
+ public static void Main ()
+ {
+ Console.WriteLine (typeof (HasPreserveApplied).FullName);
+ }
+ }
+}
diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/CommandLine/Dependencies/CustomApplyPreserveStep.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/CommandLine/Dependencies/CustomApplyPreserveStep.cs
new file mode 100644
index 00000000000000..1975f2c357179a
--- /dev/null
+++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/CommandLine/Dependencies/CustomApplyPreserveStep.cs
@@ -0,0 +1,13 @@
+namespace CustomStep
+{
+ public class CustomApplyPreserveStep : Mono.Linker.Steps.IStep
+ {
+ public void Process(Mono.Linker.LinkContext context)
+ {
+ var myType = context.GetType("Mono.Linker.Tests.Cases.CommandLine.CustomStepApplyPreserve/HasPreserveApplied");
+ context.Annotations.SetPreserve(myType, Mono.Linker.TypePreserve.Methods);
+ // Make sure we can set preserve multiple times
+ context.Annotations.SetPreserve(myType, Mono.Linker.TypePreserve.All);
+ }
+ }
+}
diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj b/src/tools/illink/test/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj
index 2b025d9861a116..f54ae5639f9b75 100644
--- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj
+++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj
@@ -22,6 +22,7 @@
+