Skip to content

Conversation

smasher164
Copy link
Contributor

@smasher164 smasher164 commented Feb 6, 2023

Private fields in a value type (like a struct) are part of its API contract.

  • A struct containing a field that is a reference type cannot be used as a reference.
  • A struct containing nonempty fields needs to be fully initialized. (See "definite assignment" rules)
  • A struct containing generic fields cannot have struct layout cycles.

Fixes dotnet/arcade#11347

Copy link
Member

@ViktorHofer ViktorHofer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please format your changes:

Copy link
Member

@ericstj ericstj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added some comments. One thing that this could use in general is more comments around what this is doing and why. The code being ported was pretty extensively commented (https://github.com/dotnet/arcade/blob/aa90e21c63248b4d6d61e8de14a0d8e7a9275130/src/Microsoft.Cci.Extensions/Writers/CSharp/CSharpWriter.cs#L195) because the thing this is doing is very unusual. It's not just sub-setting what's passed in, its constructing replacement API and we should be very clear why it's doing that.

if (hasRefPrivateField)
{
// add reference type dummy field
yield return dummyField("object", "_dummy", new());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding constants for these _dummy names. There might be some roslyn API that makes passing in known/special types like int and object easier without having to refer to them as strings and parse those.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is, it looks like

SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword))

The issue is that it doesn't easily generalize in a way where I can pass the generic type/field names to the dummyField method. I could however add some string constants here for "object", "_dummy", "int", and "_dummyPrimitive".

"src\\Tests\\Microsoft.NET.TestFramework\\Microsoft.NET.TestFramework.csproj",
]
}
} No newline at end of file
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That file was actually quite nice. Feel free to bring it back if you want to. We have the same for apicompat.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, loading this file into VS kept crashing it, so I opted to remove it.
It doesn't crash for apicompat.slnf, so I'd have to figure out if something's missing.

Copy link
Member

@andriipatsula andriipatsula left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Looks good

@smasher164 smasher164 merged commit c3fb33c into dotnet:main Feb 10, 2023
@smasher164 smasher164 deleted the synth-private branch February 10, 2023 09:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

For a compile-time compat add synthesized private fields for a value type (struct)

4 participants