namespace Microsoft.CodeAnalysis
{
public interface ISymbol
{
+ /// <summary>
+ /// Whether this symbol uses the updated memory safety rules and is considered <see langword="unsafe"/> under those rules.
+ /// </summary>
+ [Experimental(RoslynExperiments.PreviewLanguageFeatureApi, UrlFormat = "https://github.com/dotnet/roslyn/issues/82789")]
+ bool RequiresUnsafe { get; }
}
}
namespace Microsoft.CodeAnalysis.CSharp
{
public sealed class CSharpCompilationOptions
{
+ /// <summary>
+ /// Memory safety rules.
+ /// <list type="bullet">
+ /// <item><c>0</c> - legacy rules</item>
+ /// <item><c>2</c> - updated rules (support for <c>[RequiresUnsafe]</c> members)</item>
+ /// </list>
+ /// </summary>
+ [Experimental(RoslynExperiments.PreviewLanguageFeatureApi, UrlFormat = "https://github.com/dotnet/roslyn/issues/82789")]
+ public int MemorySafetyRules { get; private set; }
+ [Experimental(RoslynExperiments.PreviewLanguageFeatureApi, UrlFormat = "https://github.com/dotnet/roslyn/issues/82789")]
+ public CSharpCompilationOptions(
+ OutputKind outputKind,
+ bool reportSuppressedDiagnostics = false,
+ string? moduleName = null,
+ string? mainTypeName = null,
+ string? scriptClassName = null,
+ IEnumerable<string>? usings = null,
+ OptimizationLevel optimizationLevel = OptimizationLevel.Debug,
+ bool checkOverflow = false,
+ bool allowUnsafe = false,
+ string? cryptoKeyContainer = null,
+ string? cryptoKeyFile = null,
+ ImmutableArray<byte> cryptoPublicKey = default,
+ bool? delaySign = null,
+ Platform platform = Platform.AnyCpu,
+ ReportDiagnostic generalDiagnosticOption = ReportDiagnostic.Default,
+ int warningLevel = Diagnostic.DefaultWarningLevel,
+ IEnumerable<KeyValuePair<string, ReportDiagnostic>>? specificDiagnosticOptions = null,
+ bool concurrentBuild = true,
+ bool deterministic = false,
+ XmlReferenceResolver? xmlReferenceResolver = null,
+ SourceReferenceResolver? sourceReferenceResolver = null,
+ MetadataReferenceResolver? metadataReferenceResolver = null,
+ AssemblyIdentityComparer? assemblyIdentityComparer = null,
+ StrongNameProvider? strongNameProvider = null,
+ bool publicSign = false,
+ MetadataImportOptions metadataImportOptions = MetadataImportOptions.Public,
+ NullableContextOptions nullableContextOptions = NullableContextOptions.Disable,
+ int memorySafetyRules = 0);
- public CSharpCompilationOptions(
- OutputKind outputKind,
- bool reportSuppressedDiagnostics = false,
- string? moduleName = null,
- string? mainTypeName = null,
- string? scriptClassName = null,
- IEnumerable<string>? usings = null,
- OptimizationLevel optimizationLevel = OptimizationLevel.Debug,
- bool checkOverflow = false,
- bool allowUnsafe = false,
- string? cryptoKeyContainer = null,
- string? cryptoKeyFile = null,
- ImmutableArray<byte> cryptoPublicKey = default,
- bool? delaySign = null,
- Platform platform = Platform.AnyCpu,
- ReportDiagnostic generalDiagnosticOption = ReportDiagnostic.Default,
- int warningLevel = Diagnostic.DefaultWarningLevel,
- IEnumerable<KeyValuePair<string, ReportDiagnostic>>? specificDiagnosticOptions = null,
- bool concurrentBuild = true,
- bool deterministic = false,
- XmlReferenceResolver? xmlReferenceResolver = null,
- SourceReferenceResolver? sourceReferenceResolver = null,
- MetadataReferenceResolver? metadataReferenceResolver = null,
- AssemblyIdentityComparer? assemblyIdentityComparer = null,
- StrongNameProvider? strongNameProvider = null,
- bool publicSign = false,
- MetadataImportOptions metadataImportOptions = MetadataImportOptions.Public,
- NullableContextOptions nullableContextOptions = NullableContextOptions.Disable);
+ // 18.6 BACKCOMPAT OVERLOAD -- DO NOT TOUCH
+ public CSharpCompilationOptions(
+ OutputKind outputKind,
+ bool reportSuppressedDiagnostics,
+ string? moduleName,
+ string? mainTypeName,
+ string? scriptClassName,
+ IEnumerable<string>? usings,
+ OptimizationLevel optimizationLevel,
+ bool checkOverflow,
+ bool allowUnsafe,
+ string? cryptoKeyContainer,
+ string? cryptoKeyFile,
+ ImmutableArray<byte> cryptoPublicKey,
+ bool? delaySign,
+ Platform platform,
+ ReportDiagnostic generalDiagnosticOption,
+ int warningLevel,
+ IEnumerable<KeyValuePair<string, ReportDiagnostic>>? specificDiagnosticOptions,
+ bool concurrentBuild,
+ bool deterministic,
+ XmlReferenceResolver? xmlReferenceResolver,
+ SourceReferenceResolver? sourceReferenceResolver,
+ MetadataReferenceResolver? metadataReferenceResolver,
+ AssemblyIdentityComparer? assemblyIdentityComparer,
+ StrongNameProvider? strongNameProvider,
+ bool publicSign,
+ MetadataImportOptions metadataImportOptions,
+ NullableContextOptions nullableContextOptions);
+ [Experimental(RoslynExperiments.PreviewLanguageFeatureApi, UrlFormat = "https://github.com/dotnet/roslyn/issues/82789")]
+ public CSharpCompilationOptions WithMemorySafetyRules(int version);
}
}
Plus we need the following (not a public library API, but a public contract nevertheless):
Background and Motivation
Public API for compiler implementation of language feature unsafe evolution.
Proposed API
namespace Microsoft.CodeAnalysis { public interface ISymbol { + /// <summary> + /// Whether this symbol uses the updated memory safety rules and is considered <see langword="unsafe"/> under those rules. + /// </summary> + [Experimental(RoslynExperiments.PreviewLanguageFeatureApi, UrlFormat = "https://github.com/dotnet/roslyn/issues/82789")] + bool RequiresUnsafe { get; } } } namespace Microsoft.CodeAnalysis.CSharp { public sealed class CSharpCompilationOptions { + /// <summary> + /// Memory safety rules. + /// <list type="bullet"> + /// <item><c>0</c> - legacy rules</item> + /// <item><c>2</c> - updated rules (support for <c>[RequiresUnsafe]</c> members)</item> + /// </list> + /// </summary> + [Experimental(RoslynExperiments.PreviewLanguageFeatureApi, UrlFormat = "https://github.com/dotnet/roslyn/issues/82789")] + public int MemorySafetyRules { get; private set; } + [Experimental(RoslynExperiments.PreviewLanguageFeatureApi, UrlFormat = "https://github.com/dotnet/roslyn/issues/82789")] + public CSharpCompilationOptions( + OutputKind outputKind, + bool reportSuppressedDiagnostics = false, + string? moduleName = null, + string? mainTypeName = null, + string? scriptClassName = null, + IEnumerable<string>? usings = null, + OptimizationLevel optimizationLevel = OptimizationLevel.Debug, + bool checkOverflow = false, + bool allowUnsafe = false, + string? cryptoKeyContainer = null, + string? cryptoKeyFile = null, + ImmutableArray<byte> cryptoPublicKey = default, + bool? delaySign = null, + Platform platform = Platform.AnyCpu, + ReportDiagnostic generalDiagnosticOption = ReportDiagnostic.Default, + int warningLevel = Diagnostic.DefaultWarningLevel, + IEnumerable<KeyValuePair<string, ReportDiagnostic>>? specificDiagnosticOptions = null, + bool concurrentBuild = true, + bool deterministic = false, + XmlReferenceResolver? xmlReferenceResolver = null, + SourceReferenceResolver? sourceReferenceResolver = null, + MetadataReferenceResolver? metadataReferenceResolver = null, + AssemblyIdentityComparer? assemblyIdentityComparer = null, + StrongNameProvider? strongNameProvider = null, + bool publicSign = false, + MetadataImportOptions metadataImportOptions = MetadataImportOptions.Public, + NullableContextOptions nullableContextOptions = NullableContextOptions.Disable, + int memorySafetyRules = 0); - public CSharpCompilationOptions( - OutputKind outputKind, - bool reportSuppressedDiagnostics = false, - string? moduleName = null, - string? mainTypeName = null, - string? scriptClassName = null, - IEnumerable<string>? usings = null, - OptimizationLevel optimizationLevel = OptimizationLevel.Debug, - bool checkOverflow = false, - bool allowUnsafe = false, - string? cryptoKeyContainer = null, - string? cryptoKeyFile = null, - ImmutableArray<byte> cryptoPublicKey = default, - bool? delaySign = null, - Platform platform = Platform.AnyCpu, - ReportDiagnostic generalDiagnosticOption = ReportDiagnostic.Default, - int warningLevel = Diagnostic.DefaultWarningLevel, - IEnumerable<KeyValuePair<string, ReportDiagnostic>>? specificDiagnosticOptions = null, - bool concurrentBuild = true, - bool deterministic = false, - XmlReferenceResolver? xmlReferenceResolver = null, - SourceReferenceResolver? sourceReferenceResolver = null, - MetadataReferenceResolver? metadataReferenceResolver = null, - AssemblyIdentityComparer? assemblyIdentityComparer = null, - StrongNameProvider? strongNameProvider = null, - bool publicSign = false, - MetadataImportOptions metadataImportOptions = MetadataImportOptions.Public, - NullableContextOptions nullableContextOptions = NullableContextOptions.Disable); + // 18.6 BACKCOMPAT OVERLOAD -- DO NOT TOUCH + public CSharpCompilationOptions( + OutputKind outputKind, + bool reportSuppressedDiagnostics, + string? moduleName, + string? mainTypeName, + string? scriptClassName, + IEnumerable<string>? usings, + OptimizationLevel optimizationLevel, + bool checkOverflow, + bool allowUnsafe, + string? cryptoKeyContainer, + string? cryptoKeyFile, + ImmutableArray<byte> cryptoPublicKey, + bool? delaySign, + Platform platform, + ReportDiagnostic generalDiagnosticOption, + int warningLevel, + IEnumerable<KeyValuePair<string, ReportDiagnostic>>? specificDiagnosticOptions, + bool concurrentBuild, + bool deterministic, + XmlReferenceResolver? xmlReferenceResolver, + SourceReferenceResolver? sourceReferenceResolver, + MetadataReferenceResolver? metadataReferenceResolver, + AssemblyIdentityComparer? assemblyIdentityComparer, + StrongNameProvider? strongNameProvider, + bool publicSign, + MetadataImportOptions metadataImportOptions, + NullableContextOptions nullableContextOptions); + [Experimental(RoslynExperiments.PreviewLanguageFeatureApi, UrlFormat = "https://github.com/dotnet/roslyn/issues/82789")] + public CSharpCompilationOptions WithMemorySafetyRules(int version); } }Plus we need the following (not a public library API, but a public contract nevertheless):
csc.exe:-memorysafetyrules:2,Csctask and a corresponding MSBuild property:<MemorySafetyRules>2</MemorySafetyRules>.Usage Examples
Alternative Designs
int UpdatedMemorySafetyRulesVersionasconst/readonlyfield/property ofCSharpCompilationOptions.WithUpdatedMemorySafetyRulesonCSharpCompilationOptions.ISymbol.RequiresUnsafeinto a default interface member.Csc.MemorySafetyRulesbut not/memorysafetyrules:(pass it viaFeatureslikeInterceptorsNamespaces).Risks