You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The MemorySafetyRulesAttribute is used by the compiler (it is disallowed to use it in source). The compiler applies it to a module when updated memory safety rules are enabled.
The RequiresUnsafeAttribute is used by users but can be also applied by the compiler implicitly for extern members.
classC{[RequiresUnsafe]publicvoidM(){}}
Alternative Designs
Since the RequiresUnsafe attribute is to be used by users, perhaps it should live in System.Diagnostics.CodeAnalysis instead - in fact, it's already defined there internally:
unsafe will also be allowed on field declarations. This allows code to indicate that part of an unsafe contract is carried within a field. For example, the following simplified code appears in the dotnet/runtime core framework:
So unless this scenario has been deemed irrelevant in the last 4 months (in which case I would like to understand why, as I would have used this), then it should have AttributeTargets.Field I would think.
Current namespace is System.Diagnostics.CodeAnalysis. That's what I'd prefer.
Imo CompilerServices is the more appropriate namespace, and it was a mistake to put UnscopedRef in CodeAnalysis.
If you look at the attributes (that are intended to be used by users) in CompilerServices vs CodeAnalysis:
CompilerServices: e.g., DllImport, LibraryImport, InlineArray, TypeForwardedTo, SkipLocalsInit, MethodImpl, InterpolatedStringHandler, IndexerName, CallerArgumentExpression, SpecialName, etc. - these generally all either can give compiler errors and/or directly affect compilation
CodeAnalysis: e.g., AllowNull, ConstantExpected, DynamicallyAccessedMembers, StringSyntax, MaybeNull, MaybeNullWhen, NotNull, Experimental, UnscopedRef, etc. - with the exception of the last one, these all either only give warnings or can be suppressed via #pragma warning disable / similar (in the case of experimental for example); only UnscopedRef (at least out of the examples I gave, plus I think also SetsRequiredMembers is the only other one) contribute to real compiler errors
Furthermore, people writing code that has [RequiresUnsafe] applied likely already have CompilerServices imported for other reasons (e.g., for Unsafe, DllImport, MethodImpl, SkipLocalsInit, RuntimeHelpers, etc.).
Therefore, I personally think it is more appropriate to place it in CompilerServices, and to follow this (pre-existing) pattern in the future, rather than following the "pattern" for the singluar exception to it in this area (UnscopedRef); and I think it would be more useful overall too.
(I also personally find it more annoying when I am testing snippets on something like sharplab to import CodeAnalysis namespace for UnscopedRef already, since I likely already have to have CompilerServices imported if I'm testing something that would have [RequiresUnsafe] (and importing things on sharplab is a terrible experience) - or if I'm writing a small code snippet to run in dotnet script or similar (similar kind of issue here))
I also personally prefer CompilerServices for a similar reason, but as a bonus that is what the compiler is already doing and avoids it needing to churn and produce a new build.
Either way we will discuss both options in API review, as we normally do. So lets present it as Roslyn has it implemented to avoid confusion in the review.
The main reason I would put it in Diagnostics.CodeAnalysis is to keep it alongside RequiresUnreferencedCode, RequiresDynamicCode, RequiresAssemblyFiles, et al.
I feel like things in CompilerServices should generally be things users aren't interacting with. MemorySafetyRulesAttribute seems like a thing the compiler writes down based on some external information, but RequiresUnsafeAttribute is less clearly that... if it's expected to be exceedingly rare (other than compiler-written) outside of the BCL (where we have Unsafe, Marshal, CollectionMarshal, etc) then CompilerServices might be OK... but if it has "general applicability" then I'd like it to be somewhere else.
It's used to annotate that code requires an unsafe { } context to be invoked, so we don't really "want" users using it regularly. I'd think it has the overall same level of user interaction as DllImport, LibraryImport, Unsafe, etc (all of which live in CompilerServices) and will frequently be coupled with such attributes/types. -- i.e. If you're using something from CompilerServices or InteropServices chances are you're working with some kind of unsafe code and so likely need to consider using RequiresUnsafe as well. The same is not true for needing System.Diagnostics.CodeAnalysis or vice-versa.
That being said, System.Diagnostics.CodeAnalysis isn't the worst place and has many other compiler related attributes as well, so its the only other obvious location. The biggest downside being Roslyn has to churn and update themselves if it is moved here.
My opinion is aligned with Jeremy. This is something that we expect users to interact with manually, and so should not be in CompilerServices. The compiler put it in there for the initial implementation when we assumed users would not be applying it by hand, so if we have to update for a better namespace, I'm perfectly happy with that.
Activity
dotnet-policy-service commentedon Mar 3, 2026
Tagging subscribers to this area: @dotnet/area-system-runtime-compilerservices
See info in area-owners.md if you want to be subscribed.
hamarb123 commentedon Mar 3, 2026
Sholdn't it also be allowed on fields? It seems to be mentioned in https://github.com/dotnet/designs/blob/main/accepted/2025/memory-safety/caller-unsafe.md that it should be:
So unless this scenario has been deemed irrelevant in the last 4 months (in which case I would like to understand why, as I would have used this), then it should have
AttributeTargets.FieldI would think.333fred commentedon Mar 3, 2026
It's an open question for the proposal. We will bring it up in review and get pre-approval to make the change should LDM sign off.
agocke commentedon Mar 4, 2026
Current namespace is
System.Diagnostics.CodeAnalysis. That's what I'd prefer.hamarb123 commentedon Mar 5, 2026
Imo
CompilerServicesis the more appropriate namespace, and it was a mistake to putUnscopedRefinCodeAnalysis.If you look at the attributes (that are intended to be used by users) in
CompilerServicesvsCodeAnalysis:CompilerServices: e.g.,DllImport,LibraryImport,InlineArray,TypeForwardedTo,SkipLocalsInit,MethodImpl,InterpolatedStringHandler,IndexerName,CallerArgumentExpression,SpecialName, etc. - these generally all either can give compiler errors and/or directly affect compilationCodeAnalysis: e.g.,AllowNull,ConstantExpected,DynamicallyAccessedMembers,StringSyntax,MaybeNull,MaybeNullWhen,NotNull,Experimental,UnscopedRef, etc. - with the exception of the last one, these all either only give warnings or can be suppressed via#pragma warning disable/ similar (in the case of experimental for example); onlyUnscopedRef(at least out of the examples I gave, plus I think alsoSetsRequiredMembersis the only other one) contribute to real compiler errorsFurthermore, people writing code that has
[RequiresUnsafe]applied likely already haveCompilerServicesimported for other reasons (e.g., forUnsafe,DllImport,MethodImpl,SkipLocalsInit,RuntimeHelpers, etc.).Therefore, I personally think it is more appropriate to place it in
CompilerServices, and to follow this (pre-existing) pattern in the future, rather than following the "pattern" for the singluar exception to it in this area (UnscopedRef); and I think it would be more useful overall too.(I also personally find it more annoying when I am testing snippets on something like sharplab to import
CodeAnalysisnamespace forUnscopedRefalready, since I likely already have to haveCompilerServicesimported if I'm testing something that would have[RequiresUnsafe](and importing things on sharplab is a terrible experience) - or if I'm writing a small code snippet to run indotnet scriptor similar (similar kind of issue here))tannergooding commentedon Mar 5, 2026
I also personally prefer CompilerServices for a similar reason, but as a bonus that is what the compiler is already doing and avoids it needing to churn and produce a new build.
Either way we will discuss both options in API review, as we normally do. So lets present it as Roslyn has it implemented to avoid confusion in the review.
agocke commentedon Mar 5, 2026
The main reason I would put it in Diagnostics.CodeAnalysis is to keep it alongside
RequiresUnreferencedCode,RequiresDynamicCode,RequiresAssemblyFiles, et al.bartonjs commentedon Mar 5, 2026
I feel like things in CompilerServices should generally be things users aren't interacting with.
MemorySafetyRulesAttributeseems like a thing the compiler writes down based on some external information, butRequiresUnsafeAttributeis less clearly that... if it's expected to be exceedingly rare (other than compiler-written) outside of the BCL (where we haveUnsafe,Marshal,CollectionMarshal, etc) then CompilerServices might be OK... but if it has "general applicability" then I'd like it to be somewhere else.tannergooding commentedon Mar 5, 2026
It's used to annotate that code requires an
unsafe { }context to be invoked, so we don't really "want" users using it regularly. I'd think it has the overall same level of user interaction asDllImport,LibraryImport,Unsafe, etc (all of which live inCompilerServices) and will frequently be coupled with such attributes/types. -- i.e. If you're using something fromCompilerServicesorInteropServiceschances are you're working with some kind of unsafe code and so likely need to consider usingRequiresUnsafeas well. The same is not true for needingSystem.Diagnostics.CodeAnalysisor vice-versa.That being said,
System.Diagnostics.CodeAnalysisisn't the worst place and has many other compiler related attributes as well, so its the only other obvious location. The biggest downside being Roslyn has to churn and update themselves if it is moved here.333fred commentedon Mar 5, 2026
My opinion is aligned with Jeremy. This is something that we expect users to interact with manually, and so should not be in CompilerServices. The compiler put it in there for the initial implementation when we assumed users would not be applying it by hand, so if we have to update for a better namespace, I'm perfectly happy with that.
bartonjs commentedon Mar 17, 2026
Video