When running tests which check if something is GC'd, it might fail.
Consider the following test:
[<TestMethod>] member _.TestGC() = let mutable obj = new Object() let weak = new WeakReference(obj); GC.Collect() Assert.IsTrue(obj <> null) Assert.IsTrue(weak.IsAlive) obj <- null GC.Collect() Assert.IsTrue((obj = null)) Assert.IsTrue(not weak.IsAlive)
This will fail in
This happens because of elaboration to new locals for every subexpression. For example,
let list1 = [1; 2; 3] let list2 = [1; 2; 3] assert (list1 = list2)
This elaborates every sub-expression to:
let list1 = [1; 2; 3] let list2 = [1; 2; 3] let list1' = list1 let list2' = list2 let is_eq = list1'.Equals(list2') assert (is_eq)
Rewriting our first example:
let obj' = obj let isNull = obj' <> null
While this usually isn't a problem,
obj' will end up holding a reference to the original object, so it won't be collected until it goes out of scope - which is only when the method exits.
The rewriting won't happen for
RELEASE mode, so the test should pass. But any effects related to the lifetime of objects in memory would exist in
Last modified on 2020-03-30