-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No write-back of mutable struct instances to live constant boxes #19094
Comments
cc: @VSadov |
|
@JonHanna @bartdesmet @VSadov As 2.0 comes closer, I kindly ask if there is an update on that topic? |
I'm not sure that they should be. Certainly reference types held in such nodes are mutable, but that seems to me to be akin to how a Of course CS1648 means we can't generally attempt to mutate a public interface IValue
{
int Value { get; set; }
}
public struct Mutable : IValue
{
public int Value { get; set; }
}
public class Reference : IValue
{
public int Value { get; set; }
}
public class HasValues<T> where T : IValue, new()
{
private T X = new T();
private readonly T Y = new T();
public void AddAndPrint()
{
X.Value++;
X.Value++;
X.Value++;
Y.Value++;
Y.Value++;
Y.Value++;
Console.WriteLine(X.Value);
Console.WriteLine(Y.Value);
}
}
static void Main()
{
new HasValues<Mutable>().AddAndPrint();
new HasValues<Reference>().AddAndPrint();
} Output:
The "constant" of |
Due to lack of recent activity, this issue has been marked as a candidate for backlog cleanup. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will undo this process. This process is part of our issue cleanup automation. |
This issue will now be closed since it had been marked |
Consider the following test:
which uses a lambda equivalent to:
where
o
is a mutable struct. With the expression interpreter, the assert succeeds, but with the expression compiler, the assert fails.The issue with the compiler is in the use of
unbox.any
upon accessing theClosure.Constants
array slot containing the live constant containing the boxed instance ofnew StructWithPropertiesAndFields()
. No write-back is ever attempted. Contrast this to:This will print true as well. The use of an
object[]
combined withunbox.any
instructions for accessing live constants prevents the ability to perform a mutation on the original storage location. In fact, the emitted code is:The use of
stloc
andldloca
originates from theEmitAddress
case for theConstant
node, so we create yet another copy prior to taking the address.With my pending changes on statically typed closures, this behavior will be corrected because the constants will be stored in a statically typed field in a closure class. Obtaining the address of the instance for use by the indexer assignment will emit
ldflda
.If we were to fix this in the current code, we'd have to check for (mutable non-primitive) structs and store them in a
StrongBox<T>
in theConstants
array slot instead, so we can avoid the use ofunbox.any
on the struct value (and the copying of the value to a temporary to obtain the address). Instead, we'd "unbox" the strong box from theConstants
storage slot andEmitAddress
for theValue
field in the strong box.The text was updated successfully, but these errors were encountered: