Skip to content

Conversation

@333fred
Copy link
Member

@333fred 333fred commented Nov 10, 2025

Expands rules for how metadata will be emitted for the new unsafe feature

@333fred 333fred requested a review from a team as a code owner November 10, 2025 19:47
{
/// <summary>Indicates the language version of the memory safety rules used when the module was compiled.</summary>
[AttributeUsage(AttributeTargets.Module, Inherited = false)]
public sealed class MemorySafetyRulesAttribute : Attribute
Copy link
Member

Choose a reason for hiding this comment

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

Will this play well with other languages? Suppose that C# 15 adds new safety rules. Now also suppose that F# adds safety rules in version 8. Does Roslyn understand which langauge version the number is related to? Are attributes under System.Runtime.CompilerServices assumed to be limited to C#?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's based on the RefSafetyRulesAttribute scheme, which also used language version. Perhaps @jaredpar or @RikkiGibson could comment on that.

Copy link
Member

Choose a reason for hiding this comment

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

It's documented here: https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/low-level-struct-improvements.md#refsafetyrulesattribute. The version is actually ignored, but it could be considered in the future if there was another "ref safety rules" version.

Copy link
Member

@AaronRobinsonMSFT AaronRobinsonMSFT Nov 11, 2025

Choose a reason for hiding this comment

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

@jjonescz Thanks. I don't see anything specific about the attribute and other languages though. It seems like it is implicitly a C# only attribute. This gets back to my question of, what if F# has their own ref-safety rules? or another .NET compiler decides to express their own memory safety rules?

I'm not saying we should throw it all away or even add a new API or change the existing one. I think I would like to see some clear documentation on the API though say "is specifically for Roslyn" or "is specifically for C#". I'm not going to quibble about potentially other non-Roslyn C# compilers.

Copy link
Member

Choose a reason for hiding this comment

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

The attribute is essentially for C#. The version number in the attribute is always a C# major language version. Languages that want to interop with C#'s unsafe code, will need to recognize and understand it, and possibly even emit it themselves if they want their "unsafe methods", etc. to be understood and treated similarly as C#'s.

This gets back to my question of, what if F# has their own ref-safety rules? or another .NET compiler decides to express their own memory safety rules?

Other languages/compilers can simply be oblivious to this attribute. That is the default state of affairs. If another language decided to implement a divergent concept of unsafe, then, we would likely remain in that situation of: we are oblivious to their unsafe mechanics, and they are oblivious to ours. That seems like something we should avoid, and also something which is unlikely to arise inadvertently.

In the past, F# did some work to check ref safety for ref structs, etc. It doesn't look like they recognize RefSafetyRulesAttribute, though, they might wish to do so in the future. That's the nature of the impact I would anticipate on other major .NET languages for this feature as well.

Copy link
Member

Choose a reason for hiding this comment

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

The attribute is essentially for C#.

Then that should be documented cleared on the API.

public int Version { get; }
}

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Delegate | AttributeTargets.Constructor, AllowMultiple = false, Inherited = true)]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Delegate | AttributeTargets.Constructor, AllowMultiple = false, Inherited = true)]
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor, AllowMultiple = false, Inherited = true)]

As discussed offline, we may want to mark delegate Invoke method as unsafe so that delegate types are not special. AttributeTargets.Delegate is not needed in that case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants