diff --git a/proposals/unsafe-evolution.md b/proposals/unsafe-evolution.md index 8ff74d95e1..c159b43f12 100644 --- a/proposals/unsafe-evolution.md +++ b/proposals/unsafe-evolution.md @@ -184,6 +184,43 @@ partial class C2 For properties, `get` and `set/init` members can be independently declared as `unsafe`; marking the entire property as `unsafe` means that both the `get` and `set/init` members are unsafe. +#### Metadata + +When an assembly is compiled with the new memory safety rules, it gets marked with `MemorySafetyRulesAttribute` (detailed below), filled in with `15` as the language version. This is a signal to +any downstream consumers that any members defined in the assembly will be properly attributed with `RequiresUnsafeAttribute` (detailed below) if an `unsafe` context is required to call them. +Any member in such an assembly that is not marked with `RequiresUnsafeAttribute` does not require an `unsafe` context to be called, regardless of the types in the signature of the member. + +When a member is marked as `unsafe`, the compiler will synthesize a `RequiresUnsafeAttribute` application on the member in metadata. When a user-facing member marked as `unsafe` generates +hidden members, such as an auto-property's backing field or get/set methods, both the user-facing member and any hidden members generated by that user-facing member are all marked as `unsafe`, +and `RequiresUnsafeAttribute` is applied to all of them. + +```cs +namespace System.Runtime.CompilerServices +{ + /// Indicates the language version of the memory safety rules used when the module was compiled. + [AttributeUsage(AttributeTargets.Module, Inherited = false)] + public sealed class MemorySafetyRulesAttribute : Attribute + { + /// Initializes a new instance of the class. + /// The language version of the memory safety rules used when the module was compiled. + public MemorySafetyRulesAttribute(int version) => Version = version; + + /// Gets the language version of the memory safety rules used when the module was compiled. + public int Version { get; } + } + + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Delegate | AttributeTargets.Constructor, AllowMultiple = false, Inherited = true)] + public sealed class RequiresUnsafeAttribute : Attribute + { + } +} +``` + +#### Compat mode + +For compat purposes, and to reduce the number of false negatives that occur when enabling the new rules, we have a fallback rule for modules that have not been updated to the new rules. For such modules, +a member is considered `unsafe` if it has a pointer or function pointer type in its signature. + ## Open questions ### Local functions/lambda safe contexts