/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Emit3/Attributes/AttributeTests_RefReadOnly.cs
2 566 строк
93 KB
Tomáš Matoušek
Move some emit tests from Emit2 to Emit3 to avoid hitting UserString heap limit (#75091)
13 сен 2024, 12:01
Не верифицирован
13 сен 2024, 12:01
814c61c
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Roslyn.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests { public class AttributeTests_RefReadOnly : CSharpTestBase { [Fact] public void RefReadOnlyIsWrittenToMetadata_SameAssembly_Method() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } } class Test { public ref readonly int M(in int x) { return ref x; } } "; CompileAndVerify(text, verify: Verification.Fails, symbolValidator: module => { var method = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod("M"); Assert.Equal(RefKind.RefReadOnly, method.RefKind); Assert.True(method.ReturnsByRefReadonly); var parameter = method.GetParameters().Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); Assert.Empty(method.GetReturnTypeAttributes()); var peModule = (PEModuleSymbol)module; Assert.True(peModule.Module.HasIsReadOnlyAttribute(((PEMethodSymbol)method).Signature.ReturnParam.Handle)); Assert.True(peModule.Module.HasIsReadOnlyAttribute(((PEParameterSymbol)parameter).Handle)); AssertDeclaresType(peModule, WellKnownType.System_Runtime_CompilerServices_IsReadOnlyAttribute, Accessibility.Public); }); } [Fact] public void InIsWrittenToMetadata_NeedsToBeGenerated_Method_Parameter() { var text = @" class Test { public void M(in int x) { } } "; CompileAndVerify(text, symbolValidator: module => { var parameter = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod("M").GetParameters().Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); var peModule = (PEModuleSymbol)module; Assert.True(peModule.Module.HasIsReadOnlyAttribute(((PEParameterSymbol)parameter).Handle)); AssertDeclaresType(peModule, WellKnownType.System_Runtime_CompilerServices_IsReadOnlyAttribute, Accessibility.Internal); }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Method_ReturnType() { var text = @" class Test { private int x; public ref readonly int M() { return ref x; } } "; CompileAndVerify(text, symbolValidator: module => { var method = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod("M"); Assert.Equal(RefKind.RefReadOnly, method.RefKind); Assert.True(method.ReturnsByRefReadonly); Assert.Empty(method.GetReturnTypeAttributes()); }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_DifferentAssembly_Method() { var codeA = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } }"; var referenceA = CreateCompilation(codeA).VerifyDiagnostics().ToMetadataReference(); var codeB = @" class Test { public ref readonly int M(in int x) { return ref x; } } "; CompileAndVerify(codeB, verify: Verification.Fails, references: new[] { referenceA }, symbolValidator: module => { var method = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod("M"); Assert.Equal(RefKind.RefReadOnly, method.RefKind); Assert.True(method.ReturnsByRefReadonly); var parameter = method.GetParameters().Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); Assert.Empty(method.GetReturnTypeAttributes()); AssertNoIsReadOnlyAttributeExists(module.ContainingAssembly); }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_SameAssembly_Operator() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } } struct Test { public static int operator +(in Test x, in Test y) { return 0; } } "; CompileAndVerify(text, symbolValidator: module => { var method = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod("op_Addition"); Assert.Equal(2, method.ParameterCount); foreach (var parameter in method.Parameters) { Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); } }); } [Fact] public void InIsWrittenToMetadata_NeedsToBeGenerated_Operator_Parameter() { var text = @" struct Test { public static int operator +(in Test x, in Test y) { return 0; } } "; CompileAndVerify(text, symbolValidator: module => { var method = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod("op_Addition"); Assert.Equal(2, method.ParameterCount); foreach (var parameter in method.Parameters) { Assert.Empty(parameter.GetAttributes()); } }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_Operator_Method() { var codeA = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } }"; var referenceA = CreateCompilation(codeA).VerifyDiagnostics().ToMetadataReference(); var codeB = @" struct Test { public static int operator +(in Test x, in Test y) { return 0; } } "; CompileAndVerify(codeB, references: new[] { referenceA }, symbolValidator: module => { var method = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod("op_Addition"); Assert.Equal(2, method.ParameterCount); foreach (var parameter in method.Parameters) { Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); } AssertNoIsReadOnlyAttributeExists(module.ContainingAssembly); }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_SameAssembly_Constructor() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } } class Test { public Test(in int x) { } } "; CompileAndVerify(text, symbolValidator: module => { var parameter = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod(".ctor").Parameters.Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); }); } [Fact] public void InIsWrittenToMetadata_NeedsToBeGenerated_Constructor_Parameter() { var text = @" class Test { public Test(in int x) { } } "; CompileAndVerify(text, symbolValidator: module => { var parameter = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod(".ctor").Parameters.Single(); Assert.Empty(parameter.GetAttributes()); }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_Constructor_Method() { var codeA = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } }"; var referenceA = CreateCompilation(codeA).VerifyDiagnostics().ToMetadataReference(); var codeB = @" class Test { public Test(in int x) { } } "; CompileAndVerify(codeB, references: new[] { referenceA }, symbolValidator: module => { var parameter = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod(".ctor").Parameters.Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); AssertNoIsReadOnlyAttributeExists(module.ContainingAssembly); }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_SameAssembly_Property() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } } class Test { private int x = 0; public ref readonly int P1 { get { return ref x; } } public ref readonly int P2 => ref x; } "; CompileAndVerify(text, symbolValidator: module => { var type = module.ContainingAssembly.GetTypeByMetadataName("Test"); AssertProperty(type.GetProperty("P1")); AssertProperty(type.GetProperty("P2")); void AssertProperty(PropertySymbol property) { Assert.Equal(RefKind.RefReadOnly, property.RefKind); Assert.True(property.ReturnsByRefReadonly); Assert.Empty(property.GetAttributes()); } }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Property() { var text = @" class Test { private int x = 0; public ref readonly int P1 { get { return ref x; } } public ref readonly int P2 => ref x; } "; CompileAndVerify(text, symbolValidator: module => { var type = module.ContainingAssembly.GetTypeByMetadataName("Test"); AssertProperty(type.GetProperty("P1")); AssertProperty(type.GetProperty("P2")); void AssertProperty(PropertySymbol property) { Assert.Equal(RefKind.RefReadOnly, property.RefKind); Assert.True(property.ReturnsByRefReadonly); Assert.Empty(property.GetAttributes()); } }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_DifferentAssembly_Property() { var codeA = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } }"; var referenceA = CreateCompilation(codeA).VerifyDiagnostics().ToMetadataReference(); var codeB = @" class Test { private int x = 0; public ref readonly int P1 { get { return ref x; } } public ref readonly int P2 => ref x; } "; CompileAndVerify(codeB, references: new[] { referenceA }, symbolValidator: module => { var type = module.ContainingAssembly.GetTypeByMetadataName("Test"); AssertProperty(type.GetProperty("P1")); AssertProperty(type.GetProperty("P2")); void AssertProperty(PropertySymbol property) { Assert.Equal(RefKind.RefReadOnly, property.RefKind); Assert.True(property.ReturnsByRefReadonly); Assert.Empty(property.GetAttributes()); AssertNoIsReadOnlyAttributeExists(module.ContainingAssembly); } }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_SameAssembly_Indexer() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } } class Test { public ref readonly int this[in int x] { get { return ref x; } } } "; CompileAndVerify(text, verify: Verification.Fails, symbolValidator: module => { var indexer = module.ContainingAssembly.GetTypeByMetadataName("Test").GetProperty("this[]"); Assert.Equal(RefKind.RefReadOnly, indexer.RefKind); Assert.True(indexer.ReturnsByRefReadonly); var parameter = indexer.GetParameters().Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); Assert.Empty(indexer.GetAttributes()); }); } [Fact] public void InIsWrittenToMetadata_NeedsToBeGenerated_Indexer_Parameter() { var text = @" class Test { public int this[in int x] { get { return x; } } } "; CompileAndVerify(text, symbolValidator: module => { var parameter = module.ContainingAssembly.GetTypeByMetadataName("Test").GetProperty("this[]").GetParameters().Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Indexer_ReturnType() { var text = @" class Test { private int x; public ref readonly int this[int p] { get { return ref x; } } } "; CompileAndVerify(text, symbolValidator: module => { var indexer = module.ContainingAssembly.GetTypeByMetadataName("Test").GetProperty("this[]"); Assert.Equal(RefKind.RefReadOnly, indexer.RefKind); Assert.True(indexer.ReturnsByRefReadonly); Assert.Empty(indexer.GetAttributes()); }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_DifferentAssembly_Indexer() { var codeA = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } }"; var referenceA = CreateCompilation(codeA).VerifyDiagnostics().ToMetadataReference(); var codeB = @" class Test { public ref readonly int this[in int x] { get { return ref x; } } } "; CompileAndVerify(codeB, verify: Verification.Fails, references: new[] { referenceA }, symbolValidator: module => { var indexer = module.ContainingAssembly.GetTypeByMetadataName("Test").GetProperty("this[]"); Assert.Equal(RefKind.RefReadOnly, indexer.RefKind); Assert.True(indexer.ReturnsByRefReadonly); var parameter = indexer.GetParameters().Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); Assert.Empty(indexer.GetAttributes()); AssertNoIsReadOnlyAttributeExists(module.ContainingAssembly); }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_SameAssembly_Delegate() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } } public delegate ref readonly int D(in int x); "; CompileAndVerify(text, symbolValidator: module => { var method = module.ContainingAssembly.GetTypeByMetadataName("D").DelegateInvokeMethod; Assert.Equal(RefKind.RefReadOnly, method.RefKind); Assert.True(method.ReturnsByRefReadonly); var parameter = method.GetParameters().Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); Assert.Empty(method.GetReturnTypeAttributes()); }); } [Fact] public void InIsWrittenToMetadata_NeedsToBeGenerated_Delegate_Parameter() { var text = @" public delegate void D(in int x); "; CompileAndVerify(text, symbolValidator: module => { var parameter = module.ContainingAssembly.GetTypeByMetadataName("D").DelegateInvokeMethod.GetParameters().Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Delegate_ReturnType() { var text = @" public delegate ref readonly int D(); "; CompileAndVerify(text, symbolValidator: module => { var method = module.ContainingAssembly.GetTypeByMetadataName("D").DelegateInvokeMethod; Assert.Equal(RefKind.RefReadOnly, method.RefKind); Assert.True(method.ReturnsByRefReadonly); Assert.Empty(method.GetReturnTypeAttributes()); }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_DifferentAssembly_Delegate() { var codeA = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } }"; var referenceA = CreateCompilation(codeA).VerifyDiagnostics().ToMetadataReference(); var codeB = @" public delegate ref readonly int D(in int x); "; CompileAndVerify(codeB, references: new[] { referenceA }, symbolValidator: module => { var method = module.ContainingAssembly.GetTypeByMetadataName("D").DelegateInvokeMethod; Assert.Equal(RefKind.RefReadOnly, method.RefKind); Assert.True(method.ReturnsByRefReadonly); var parameter = method.GetParameters().Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); Assert.Empty(method.GetReturnTypeAttributes()); AssertNoIsReadOnlyAttributeExists(module.ContainingAssembly); }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_SameAssembly_LocalFunctions() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } } public class Test { public void M() { ref readonly int Inner(in int x) { return ref x; } } } "; var options = TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All); CompileAndVerify(text, verify: Verification.Fails, options: options, symbolValidator: module => { var method = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod("<M>g__Inner|0_0"); Assert.Equal(RefKind.RefReadOnly, method.RefKind); Assert.True(method.ReturnsByRefReadonly); var parameter = method.GetParameters().Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); Assert.Empty(method.GetReturnTypeAttributes()); }); } [Fact] public void InIsWrittenToMetadata_NeedsToBeGenerated_LocalFunctions_Parameters() { var text = @" public class Test { public void M() { void Inner(in int x) { } } } "; var options = TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All); CompileAndVerify(text, options: options, symbolValidator: module => { var parameter = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod("<M>g__Inner|0_0").GetParameters().Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_LocalFunctions_ReturnType() { var text = @" public class Test { private int x; public void M() { ref readonly int Inner() { return ref x; } } } "; var options = TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All); CompileAndVerify(text, verify: Verification.Fails, options: options, symbolValidator: module => { var method = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod("<M>g__Inner|1_0"); Assert.Equal(RefKind.RefReadOnly, method.RefKind); Assert.True(method.ReturnsByRefReadonly); Assert.Empty(method.GetReturnTypeAttributes()); }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_DifferentAssembly_LocalFunctions() { var codeA = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } }"; var referenceA = CreateCompilation(codeA).VerifyDiagnostics().ToMetadataReference(); var codeB = @" public class Test { public void M() { ref readonly int Inner(in int x) { return ref x; } } } "; var options = TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All); CompileAndVerify(codeB, verify: Verification.Fails, references: new[] { referenceA }, options: options, symbolValidator: module => { var method = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod("<M>g__Inner|0_0"); Assert.Equal(RefKind.RefReadOnly, method.RefKind); Assert.True(method.ReturnsByRefReadonly); var parameter = method.GetParameters().Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); Assert.Empty(method.GetReturnTypeAttributes()); AssertNoIsReadOnlyAttributeExists(module.ContainingAssembly); }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_SameAssembly_Lambda() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } } delegate ref readonly int D(in int x); class Test { public void M1() { M2((in int x) => ref x); } public void M2(D value) { } } "; var options = TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All); CompileAndVerify(text, verify: Verification.Fails, options: options, symbolValidator: module => { var method = module.GlobalNamespace.GetMember<MethodSymbol>("Test.<>c.<M1>b__0_0"); Assert.Equal(RefKind.RefReadOnly, method.RefKind); Assert.True(method.ReturnsByRefReadonly); var parameter = method.GetParameters().Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); Assert.Empty(method.GetReturnTypeAttributes()); }); } [Fact] public void InIsWrittenToMetadata_NeedsToBeGenerated_Lambda_Parameter() { var text = @" delegate void D(in int x); class Test { public void M1() { M2((in int x) => {}); } public void M2(D value) { } } "; var options = TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All); CompileAndVerify(text, options: options, symbolValidator: module => { var parameter = module.GlobalNamespace.GetMember<MethodSymbol>("Test.<>c.<M1>b__0_0").GetParameters().Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Lambda_ReturnType() { var text = @" delegate ref readonly int D(); class Test { private int x; public void M1() { M2(() => ref x); } public void M2(D value) { } } "; var options = TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All); CompileAndVerify(text, options: options, symbolValidator: module => { var method = module.GlobalNamespace.GetMember<MethodSymbol>("Test.<M1>b__1_0"); Assert.Equal(RefKind.RefReadOnly, method.RefKind); Assert.True(method.ReturnsByRefReadonly); Assert.Empty(method.GetReturnTypeAttributes()); }); } [Fact] public void RefReadOnlyIsWrittenToMetadata_DifferentAssembly_Lambda() { var codeA = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } }"; var referenceA = CreateCompilation(codeA).VerifyDiagnostics().ToMetadataReference(); var codeB = @" delegate ref readonly int D(in int x); class Test { public void M1() { M2((in int x) => ref x); } public void M2(D value) { } } "; var options = TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All); CompileAndVerify(codeB, verify: Verification.Fails, options: options, references: new[] { referenceA }, symbolValidator: module => { var method = module.GlobalNamespace.GetMember<MethodSymbol>("Test.<>c.<M1>b__0_0"); Assert.Equal(RefKind.RefReadOnly, method.RefKind); Assert.True(method.ReturnsByRefReadonly); var parameter = method.GetParameters().Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); Assert.Empty(method.GetReturnTypeAttributes()); AssertNoIsReadOnlyAttributeExists(module.ContainingAssembly); }); } [Fact] public void IsReadOnlyAttributeIsDisallowedEverywhereInSource_Delegates() { var codeA = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } }"; var referenceA = CreateCompilation(codeA).VerifyDiagnostics().ToMetadataReference(); var codeB = @" using System.Runtime.CompilerServices; [IsReadOnly] public delegate ref readonly int D([IsReadOnly]in int x); "; CreateCompilation(codeB, references: new[] { referenceA }).VerifyDiagnostics( // (4,2): error CS8335: Do not use 'System.Runtime.CompilerServices.IsReadOnlyAttribute'. This is reserved for compiler usage. // [IsReadOnly] Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(4, 2), // (5,37): error CS8335: Do not use 'System.Runtime.CompilerServices.IsReadOnlyAttribute'. This is reserved for compiler usage. // public delegate ref readonly int D([IsReadOnly]in int x); Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(5, 37)); } [Fact] public void IsReadOnlyAttributeIsDisallowedEverywhereInSource_Types() { var codeA = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } }"; var referenceA = CreateCompilation(codeA).VerifyDiagnostics().ToMetadataReference(); var codeB = @" using System.Runtime.CompilerServices; [IsReadOnly] public class Test { } "; CreateCompilation(codeB, references: new[] { referenceA }).VerifyDiagnostics( // (4,2): error CS8335: Do not use 'System.Runtime.CompilerServices.IsReadOnlyAttribute'. This is reserved for compiler usage. // [IsReadOnly] Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(4, 2)); } [Fact] public void IsReadOnlyAttributeIsDisallowedEverywhereInSource_Fields() { var codeA = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } }"; var referenceA = CreateCompilation(codeA).VerifyDiagnostics().ToMetadataReference(); var codeB = @" using System.Runtime.CompilerServices; public class Test { [IsReadOnly] private int x = 0; public int X => x; } "; CreateCompilation(codeB, references: new[] { referenceA }).VerifyDiagnostics( // (6,6): error CS8335: Do not use 'System.Runtime.CompilerServices.IsReadOnlyAttribute'. This is reserved for compiler usage. // [IsReadOnly] Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(6, 6)); } [Fact] public void IsReadOnlyAttributeIsDisallowedEverywhereInSource_Properties() { var codeA = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } }"; var referenceA = CreateCompilation(codeA).VerifyDiagnostics().ToMetadataReference(); var codeB = @" using System.Runtime.CompilerServices; public class Test { private int x = 0; [IsReadOnly] public ref readonly int Property => ref x; } "; CreateCompilation(codeB, references: new[] { referenceA }).VerifyDiagnostics( // (8,6): error CS8335: Do not use 'System.Runtime.CompilerServices.IsReadOnlyAttribute'. This is reserved for compiler usage. // [IsReadOnly] Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(8, 6)); } [Fact] public void IsReadOnlyAttributeIsDisallowedEverywhereInSource_Methods() { var codeA = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } }"; var referenceA = CreateCompilation(codeA).VerifyDiagnostics().ToMetadataReference(); var codeB = @" using System.Runtime.CompilerServices; public class Test { [IsReadOnly] [return: IsReadOnly] public ref readonly int Method([IsReadOnly]in int x) { return ref x; } } "; CreateCompilation(codeB, references: new[] { referenceA }).VerifyDiagnostics( // (6,6): error CS8335: Do not use 'System.Runtime.CompilerServices.IsReadOnlyAttribute'. This is reserved for compiler usage. // [IsReadOnly] Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(6, 6), // (7,14): error CS8335: Do not use 'System.Runtime.CompilerServices.IsReadOnlyAttribute'. This is reserved for compiler usage. // [return: IsReadOnly] Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(7, 14), // (8,37): error CS8335: Do not use 'System.Runtime.CompilerServices.IsReadOnlyAttribute'. This is reserved for compiler usage. // public ref readonly int Method([IsReadOnly]in int x) Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(8, 37)); } [Fact] public void IsReadOnlyAttributeIsDisallowedEverywhereInSource_Indexers() { var codeA = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } }"; var referenceA = CreateCompilation(codeA).VerifyDiagnostics().ToMetadataReference(); var codeB = @" using System.Runtime.CompilerServices; public class Test { [IsReadOnly] public ref readonly int this[[IsReadOnly]in int x] { get { return ref x; } } } "; CreateCompilation(codeB, references: new[] { referenceA }).VerifyDiagnostics( // (6,6): error CS8335: Do not use 'System.Runtime.CompilerServices.IsReadOnlyAttribute'. This is reserved for compiler usage. // [IsReadOnly] Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(6, 6), // (7,35): error CS8335: Do not use 'System.Runtime.CompilerServices.IsReadOnlyAttribute'. This is reserved for compiler usage. // public ref readonly int this[[IsReadOnly]in int x] { get { return ref x; } } Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(7, 35)); } [Fact] public void UserReferencingEmbeddedAttributeShouldResultInAnError() { var code = @" [Embedded] public class Test { public ref readonly int M(in int p) => ref p; }"; CreateCompilation(code).VerifyDiagnostics( // (2,2): error CS0246: The type or namespace name 'EmbeddedAttribute' could not be found (are you missing a using directive or an assembly reference?) // [Embedded] Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Embedded").WithArguments("EmbeddedAttribute").WithLocation(2, 2), // (2,2): error CS0246: The type or namespace name 'Embedded' could not be found (are you missing a using directive or an assembly reference?) // [Embedded] Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Embedded").WithArguments("Embedded").WithLocation(2, 2)); } [Fact] public void UserReferencingIsReadOnlyAttributeShouldResultInAnError() { var code = @" [IsReadOnly] public class Test { public ref readonly int M(in int p) => ref p; }"; CreateCompilation(code).VerifyDiagnostics( // (2,2): error CS0246: The type or namespace name 'IsReadOnlyAttribute' could not be found (are you missing a using directive or an assembly reference?) // [IsReadOnly] Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "IsReadOnly").WithArguments("IsReadOnlyAttribute").WithLocation(2, 2), // (2,2): error CS0246: The type or namespace name 'IsReadOnly' could not be found (are you missing a using directive or an assembly reference?) // [IsReadOnly] Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "IsReadOnly").WithArguments("IsReadOnly").WithLocation(2, 2)); } [Fact] public void TypeReferencingAnotherTypeThatUsesAPublicAttributeFromAThirdNotReferencedAssemblyShouldGenerateItsOwn() { var options = TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All); var code1 = CreateCompilation(@" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } }"); var code2 = CreateCompilation(@" public class Test1 { public static ref readonly int M(in int p) => ref p; }", references: new[] { code1.ToMetadataReference() }, options: options); CompileAndVerify(code2, verify: Verification.Fails, symbolValidator: module => { // IsReadOnly is not generated in assembly var isReadOnlyAttributeName = WellKnownTypes.GetMetadataName(WellKnownType.System_Runtime_CompilerServices_IsReadOnlyAttribute); Assert.Null(module.ContainingAssembly.GetTypeByMetadataName(isReadOnlyAttributeName)); }); var code3 = CreateCompilation(@" public class Test2 { public static ref readonly int M(in int p) => ref Test1.M(p); }", references: new[] { code2.ToMetadataReference() }, options: options); CompileAndVerify(code3, symbolValidator: module => { // IsReadOnly is generated in assembly AssertGeneratedEmbeddedAttribute(module.ContainingAssembly, AttributeDescription.CodeAnalysisEmbeddedAttribute.FullName); AssertGeneratedEmbeddedAttribute(module.ContainingAssembly, AttributeDescription.IsReadOnlyAttribute.FullName); }); } [Fact] public void BuildingAModuleRequiresIsReadOnlyAttributeToBeThere_Missing_SourceMethod() { var code = @" public class Test { public void M(in int x) { } }"; CreateCompilation(code, options: TestOptions.ReleaseModule).VerifyDiagnostics( // (4,19): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsReadOnlyAttribute' is not defined or imported // public void M(in int x) { } Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(4, 19)); } [Fact] public void BuildingAModuleRequiresIsReadOnlyAttributeToBeThere_Missing_SourceMethod_MultipleLocations() { var code = @" public class Test { public void M1(in int x) { } public void M2(in int x) { } }"; CreateCompilation(code, options: TestOptions.ReleaseModule).VerifyDiagnostics( // (4,20): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsReadOnlyAttribute' is not defined or imported // public void M1(in int x) { } Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(4, 20), // (5,20): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsReadOnlyAttribute' is not defined or imported // public void M2(in int x) { } Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(5, 20)); } [Fact] public void BuildingAModuleRequiresIsReadOnlyAttributeToBeThere_Missing_LocalFunctions() { var code = @" public class Test { public void Parent() { void child(in int p) { } int x = 0; child(x); } }"; CreateCompilation(code, options: TestOptions.ReleaseModule).VerifyDiagnostics( // (6,20): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsReadOnlyAttribute' is not defined or imported // void child(in int p) { } Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "in int p").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(6, 20)); } [Fact] public void BuildingAModuleRequiresIsReadOnlyAttributeToBeThere_InAReference() { var reference = CreateCompilation(@" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } }").ToMetadataReference(); var code = @" public class Test { public void M(in int x) { } }"; CompileAndVerify(code, verify: Verification.Fails, references: new[] { reference }, options: TestOptions.ReleaseModule, symbolValidator: module => { AssertNoIsReadOnlyAttributeExists(module.ContainingAssembly); var parameter = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod("M").GetParameters().Single(); Assert.Equal(RefKind.In, parameter.RefKind); Assert.Empty(parameter.GetAttributes()); }); } [Fact] public void ReferencingAnEmbeddedIsReadOnlyAttributeDoesNotUseIt_InternalsVisible() { var options = TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All); var code1 = @" [assembly:System.Runtime.CompilerServices.InternalsVisibleToAttribute(""Assembly2"")] public class Test1 { public static ref readonly int M(in int p) => ref p; }"; var comp1 = CompileAndVerify(code1, options: options, verify: Verification.Fails, symbolValidator: module => { AssertGeneratedEmbeddedAttribute(module.ContainingAssembly, AttributeDescription.CodeAnalysisEmbeddedAttribute.FullName); AssertGeneratedEmbeddedAttribute(module.ContainingAssembly, AttributeDescription.IsReadOnlyAttribute.FullName); }); var code2 = @" public class Test2 { public static ref readonly int M(in int p) => ref Test1.M(p); }"; CompileAndVerify(code2, options: options.WithModuleName("Assembly2"), references: new[] { comp1.Compilation.ToMetadataReference() }, symbolValidator: module => { AssertGeneratedEmbeddedAttribute(module.ContainingAssembly, AttributeDescription.CodeAnalysisEmbeddedAttribute.FullName); AssertGeneratedEmbeddedAttribute(module.ContainingAssembly, AttributeDescription.IsReadOnlyAttribute.FullName); }); } [Fact] public void IfIsReadOnlyAttributeIsDefinedThenEmbeddedIsNotGenerated() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } } class Test { public ref readonly int M(in int x) { return ref x; } } "; CompileAndVerify(text, references: new[] { RefSafetyRulesAttributeLib }, verify: Verification.Fails, symbolValidator: module => { Assert.Null(module.ContainingAssembly.GetTypeByMetadataName(AttributeDescription.CodeAnalysisEmbeddedAttribute.FullName)); }); } [Fact] public void IsReadOnlyAttributeExistsWithWrongConstructorSignature_NetModule() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { public IsReadOnlyAttribute(int p) { } } } class Test { public void M(in int x) { } }"; CreateCompilation(text, options: TestOptions.ReleaseModule).VerifyDiagnostics( // (11,19): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // public void M(in int x) { } Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 19)); } [Fact] public void IsReadOnlyAttributeExistsWithWrongConstructorSignature_Assembly() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { public IsReadOnlyAttribute(int p) { } } } class Test { public void M(in int x) { } }"; CreateCompilation(text).VerifyEmitDiagnostics( // (11,19): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // public void M(in int x) { } Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 19)); } [Fact] public void IsReadOnlyAttributeExistsWithWrongConstructorSignature_PrivateConstructor() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { private IsReadOnlyAttribute() { } } } class Test { public void M(in int x) { } }"; CreateCompilation(text).VerifyEmitDiagnostics( // (11,19): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // public void M(in int x) { } Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 19)); } [Fact] public void IsReadOnlyAttributesAreNotPortedInNoPia() { var comAssembly = CreateCompilationWithMscorlib40(@" using System; using System.Runtime.InteropServices; [assembly: ImportedFromTypeLib(""test.dll"")] [assembly: Guid(""9784f9a1-594a-4351-8f69-0fd2d2df03d3"")] [ComImport()] [Guid(""9784f9a1-594a-4351-8f69-0fd2d2df03d3"")] public interface Test { ref readonly int Property { get; } ref readonly int Method(in int x); }"); CompileAndVerify(comAssembly, symbolValidator: module => { var type = module.ContainingAssembly.GetTypeByMetadataName("Test"); var property = type.GetMember<PEPropertySymbol>("Property"); Assert.NotNull(property); Assert.Empty(property.GetAttributes()); var method = type.GetMethod("Method"); Assert.NotNull(method); Assert.Empty(method.GetReturnTypeAttributes()); var parameter = method.Parameters.Single(); Assert.NotNull(parameter); Assert.Empty(parameter.GetAttributes()); }); var code = @" class User { public void M(Test p) { p.Method(p.Property); } }"; var options = TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All); var compilation_CompilationReference = CreateCompilationWithMscorlib40(code, options: options, references: new[] { comAssembly.ToMetadataReference(embedInteropTypes: true) }); CompileAndVerify(compilation_CompilationReference, symbolValidator: symbolValidator); var compilation_BinaryReference = CreateCompilationWithMscorlib40(code, options: options, references: new[] { comAssembly.EmitToImageReference(embedInteropTypes: true) }); CompileAndVerify(compilation_BinaryReference, symbolValidator: symbolValidator); void symbolValidator(ModuleSymbol module) { // No attribute is copied AssertNoIsReadOnlyAttributeExists(module.ContainingAssembly); var type = module.ContainingAssembly.GetTypeByMetadataName("Test"); var property = type.GetMember<PEPropertySymbol>("Property"); Assert.NotNull(property); Assert.Empty(property.GetAttributes()); var method = type.GetMethod("Method"); Assert.NotNull(method); Assert.Empty(method.GetReturnTypeAttributes()); var parameter = method.Parameters.Single(); Assert.NotNull(parameter); Assert.Empty(parameter.GetAttributes()); } } [Fact] public void TryingToBindFromSemanticModelDoesNotPolluteCompilation_Lambdas_Parameters() { var reference = CreateCompilation(@" public delegate int D (in int x); ").VerifyEmitDiagnostics(); Assert.True(NeedsGeneratedIsReadOnlyAttribute(reference)); var compilation = CreateCompilation(@" public class Test { public void Process(D lambda) { } void User() { } }", references: new[] { reference.ToMetadataReference() }); compilation.VerifyEmitDiagnostics(); Assert.False(NeedsGeneratedIsReadOnlyAttribute(compilation)); var tree = compilation.SyntaxTrees.Single(); var model = compilation.GetSemanticModel(tree, ignoreAccessibility: false); var userFunction = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Single(method => method.Identifier.Text == "User"); var position = userFunction.Body.CloseBraceToken.Position; var newInvocation = SyntaxFactory.ParseExpression("Process((in int x) => x)"); var result = model.GetSpeculativeSymbolInfo(position, newInvocation, SpeculativeBindingOption.BindAsExpression); Assert.NotNull(result.Symbol); Assert.Equal(CandidateReason.None, result.CandidateReason); Assert.Empty(result.CandidateSymbols); Assert.False(NeedsGeneratedIsReadOnlyAttribute(compilation)); } [Fact] public void TryingToBindFromSemanticModelDoesNotPolluteCompilation_Lambdas_ReturnTypes() { var reference = CreateCompilation(@" public delegate ref readonly int D (); ").VerifyEmitDiagnostics(); Assert.True(NeedsGeneratedIsReadOnlyAttribute(reference)); var compilation = CreateCompilation(@" public class Test { private int x; public void Process(D lambda) { x = lambda(); } void User() { } }", references: new[] { reference.ToMetadataReference() }); compilation.VerifyEmitDiagnostics(); Assert.False(NeedsGeneratedIsReadOnlyAttribute(compilation)); var tree = compilation.SyntaxTrees.Single(); var model = compilation.GetSemanticModel(tree, ignoreAccessibility: false); var userFunction = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Single(method => method.Identifier.Text == "User"); var position = userFunction.Body.CloseBraceToken.Position; var newInvocation = SyntaxFactory.ParseExpression("Process(() => ref x)"); var result = model.GetSpeculativeSymbolInfo(position, newInvocation, SpeculativeBindingOption.BindAsExpression); Assert.NotNull(result.Symbol); Assert.Equal(CandidateReason.None, result.CandidateReason); Assert.Empty(result.CandidateSymbols); Assert.False(NeedsGeneratedIsReadOnlyAttribute(compilation)); } [Fact] public void TryingToBindFromSemanticModelDoesNotPolluteCompilation_LocalFunctions_Parameters() { var compilation = CreateCompilation(@" public class Test { void User() { } }"); compilation.VerifyEmitDiagnostics(); Assert.False(NeedsGeneratedIsReadOnlyAttribute(compilation)); var tree = compilation.SyntaxTrees.Single(); var model = compilation.GetSemanticModel(tree, ignoreAccessibility: false); var userFunction = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Single(method => method.Identifier.Text == "User"); var position = userFunction.Body.CloseBraceToken.Position; var localfunction = SyntaxFactory.ParseStatement("int localFunction(in int x) { return x; }"); Assert.True(model.TryGetSpeculativeSemanticModel(position, localfunction, out var newModel)); var localFunctionSymbol = newModel.GetDeclaredSymbol(localfunction); Assert.NotNull(localFunctionSymbol); Assert.False(NeedsGeneratedIsReadOnlyAttribute(compilation)); } [Fact] public void TryingToBindFromSemanticModelDoesNotPolluteCompilation_LocalFunctions_ReturnTypes() { var compilation = CreateCompilation(@" public class Test { void User() { } }"); compilation.VerifyEmitDiagnostics(); Assert.False(NeedsGeneratedIsReadOnlyAttribute(compilation)); var tree = compilation.SyntaxTrees.Single(); var model = compilation.GetSemanticModel(tree, ignoreAccessibility: false); var userFunction = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Single(method => method.Identifier.Text == "User"); var position = userFunction.Body.CloseBraceToken.Position; var localfunction = SyntaxFactory.ParseStatement("ref readonly int localFunction(int x) { return ref x; }"); Assert.True(model.TryGetSpeculativeSemanticModel(position, localfunction, out var newModel)); var localFunctionSymbol = newModel.GetDeclaredSymbol(localfunction); Assert.NotNull(localFunctionSymbol); Assert.False(NeedsGeneratedIsReadOnlyAttribute(compilation)); } [Fact] public void TryingPossibleBindingsForRefReadOnlyDoesNotPolluteCompilationForInvalidOnes() { var reference = CreateCompilation(@" public delegate ref readonly int D1 (); public delegate ref int D2 (); ").VerifyEmitDiagnostics(); Assert.True(NeedsGeneratedIsReadOnlyAttribute(reference)); var compilation = CreateCompilation(@" public class Test { public void Process(D1 lambda, int x) { } public void Process(D2 lambda, byte x) { } void User() { byte byteVar = 0; Process(() => { throw null; }, byteVar); } }", references: new[] { reference.ToMetadataReference() }); compilation.VerifyEmitDiagnostics(); Assert.False(NeedsGeneratedIsReadOnlyAttribute(compilation)); } [Fact] public void RefReadOnlyErrorsForLambdasDoNotPolluteCompilationDeclarationsDiagnostics() { var reference = CreateCompilation(@" public delegate int D (in int x); ").EmitToImageReference(); var code = @" public class Test { public void Process(D lambda) { } void User() { Process((in int p) => p); } }"; var compilation = CreateCompilation(code, options: TestOptions.ReleaseModule, references: new[] { reference }); compilation.DeclarationDiagnostics.Verify(); compilation.VerifyDiagnostics( // (8,18): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsReadOnlyAttribute' is not defined or imported // Process((in int p) => p); Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "in int p").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(8, 18)); } [Fact] public void RefReadOnlyErrorsForLocalFunctionsDoNotPolluteCompilationDeclarationsDiagnostics() { var code = @" public class Test { private int x = 0; void User() { void local(in int x) { } local(x); } }"; var compilation = CreateCompilation(code, options: TestOptions.ReleaseModule); compilation.DeclarationDiagnostics.Verify(); compilation.VerifyDiagnostics( // (7,20): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsReadOnlyAttribute' is not defined or imported // void local(in int x) { } Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(7, 20)); } [Fact] public void RefReadOnlyDefinitionsInsideUserDefinedIsReadOnlyAttribute_Class_NoParent() { var code = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute { private int value; public ref readonly int Method(in int x) => ref value; public static int operator +(in IsReadOnlyAttribute x, in IsReadOnlyAttribute y) => 0; public ref readonly int Property => ref value; public ref readonly int this[in int x] => ref value; } }"; CompileAndVerify(code, verify: Verification.Passes, symbolValidator: module => { var isReadOnlyAttributeName = WellKnownTypes.GetMetadataName(WellKnownType.System_Runtime_CompilerServices_IsReadOnlyAttribute); var type = module.ContainingAssembly.GetTypeByMetadataName(isReadOnlyAttributeName); var method = type.GetMethod("Method"); Assert.Empty(method.GetReturnTypeAttributes()); Assert.Empty(method.Parameters.Single().GetAttributes()); var @operator = type.GetMethod("op_Addition"); Assert.Empty(@operator.Parameters[0].GetAttributes()); Assert.Empty(@operator.Parameters[1].GetAttributes()); var property = type.GetProperty("Property"); Assert.Empty(property.GetAttributes()); var indexer = type.GetProperty("this[]"); Assert.Empty(indexer.GetAttributes()); Assert.Empty(indexer.Parameters.Single().GetAttributes()); }); } [Fact] public void RefReadOnlyDefinitionsInsideUserDefinedIsReadOnlyAttribute_Class_CorrectParent() { var code = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { private int value; public ref readonly int Method(in int x) => ref value; public static int operator +(in IsReadOnlyAttribute x, in IsReadOnlyAttribute y) => 0; public ref readonly int Property => ref value; public ref readonly int this[in int x] => ref value; } }"; CompileAndVerify(code, verify: Verification.Passes, symbolValidator: module => { var isReadOnlyAttributeName = WellKnownTypes.GetMetadataName(WellKnownType.System_Runtime_CompilerServices_IsReadOnlyAttribute); var type = module.ContainingAssembly.GetTypeByMetadataName(isReadOnlyAttributeName); var method = type.GetMethod("Method"); Assert.Empty(method.GetReturnTypeAttributes()); Assert.Empty(method.Parameters.Single().GetAttributes()); var @operator = type.GetMethod("op_Addition"); Assert.Empty(@operator.Parameters[0].GetAttributes()); Assert.Empty(@operator.Parameters[1].GetAttributes()); var property = type.GetProperty("Property"); Assert.Empty(property.GetAttributes()); var indexer = type.GetProperty("this[]"); Assert.Empty(indexer.GetAttributes()); Assert.Empty(indexer.Parameters.Single().GetAttributes()); }); } [Fact] public void RefReadOnlyDefinitionsInsideUserDefinedIsReadOnlyAttribute_ClassInherit() { var code = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } } public class Child : System.Runtime.CompilerServices.IsReadOnlyAttribute { private int value; public ref readonly int Method(in int x) => ref value; public static int operator +(in Child x, in Child y) => 0; public ref readonly int Property => ref value; public ref readonly int this[in int x] => ref value; }"; CompileAndVerify(code, verify: Verification.Passes, symbolValidator: module => { var type = module.ContainingAssembly.GetTypeByMetadataName("Child"); var method = type.GetMethod("Method"); Assert.Empty(method.GetReturnTypeAttributes()); Assert.Empty(method.Parameters.Single().GetAttributes()); var @operator = type.GetMethod("op_Addition"); Assert.Empty(@operator.Parameters[0].GetAttributes()); Assert.Empty(@operator.Parameters[1].GetAttributes()); var property = type.GetProperty("Property"); Assert.Empty(property.GetAttributes()); var indexer = type.GetProperty("this[]"); Assert.Empty(indexer.GetAttributes()); Assert.Empty(indexer.Parameters.Single().GetAttributes()); }); } [Fact] public void RefReadOnlyDefinitionsInsideUserDefinedIsReadOnlyAttribute_ClassOverride_SameAssembly() { var code = @" namespace System.Runtime.CompilerServices { public abstract class IsReadOnlyAttribute : System.Attribute { public IsReadOnlyAttribute() { } public abstract ref readonly int Method(in int x); public abstract ref readonly int Property { get; } public abstract ref readonly int this[in int x] { get; } } } public class Child : System.Runtime.CompilerServices.IsReadOnlyAttribute { private int value; public override ref readonly int Method(in int x) => ref value; public override ref readonly int Property => ref value; public override ref readonly int this[in int x] => ref value; }"; CompileAndVerify(code, verify: Verification.Passes, symbolValidator: module => { var type = module.ContainingAssembly.GetTypeByMetadataName("Child"); var method = type.GetMethod("Method"); Assert.Empty(method.GetReturnTypeAttributes()); Assert.Empty(method.Parameters.Single().GetAttributes()); var property = type.GetProperty("Property"); Assert.Empty(property.GetAttributes()); var indexer = type.GetProperty("this[]"); Assert.Empty(indexer.GetAttributes()); Assert.Empty(indexer.Parameters.Single().GetAttributes()); }); } [Fact] public void RefReadOnlyDefinitionsInsideUserDefinedIsReadOnlyAttribute_ClassOverride_ExternalAssembly() { var reference = CreateCompilation(@" namespace System.Runtime.CompilerServices { public abstract class IsReadOnlyAttribute : System.Attribute { public IsReadOnlyAttribute() { } public abstract ref readonly int Method(in int x); public abstract ref readonly int Property { get; } public abstract ref readonly int this[in int x] { get; } } }", assemblyName: "testRef").ToMetadataReference(); var code = @" public class Child : System.Runtime.CompilerServices.IsReadOnlyAttribute { private int value; public override ref readonly int Method(in int x) => ref value; public override ref readonly int Property => ref value; public override ref readonly int this[in int x] => ref value; }"; CompileAndVerify(code, verify: Verification.Passes, references: new[] { reference }, symbolValidator: module => { var type = module.ContainingAssembly.GetTypeByMetadataName("Child"); var method = type.GetMethod("Method"); Assert.Empty(method.GetReturnTypeAttributes()); Assert.Empty(method.Parameters.Single().GetAttributes()); var property = type.GetProperty("Property"); Assert.Empty(property.GetAttributes()); var indexer = type.GetProperty("this[]"); Assert.Empty(indexer.GetAttributes()); Assert.Empty(indexer.Parameters.Single().GetAttributes()); }); } [Fact] public void RefReadOnlyDefinitionsInsideUserDefinedIsReadOnlyAttribute_ClassOverridden_SameAssembly() { var code = @" namespace System.Runtime.CompilerServices { public abstract class Parent : System.Attribute { public abstract ref readonly int Method(in int x); public abstract ref readonly int Property { get; } public abstract ref readonly int this[in int x] { get; } } public class IsReadOnlyAttribute : Parent { private int value; public override ref readonly int Method(in int x) => ref value; public override ref readonly int Property => ref value; public override ref readonly int this[in int x] => ref value; } }"; CompileAndVerify(code, verify: Verification.Passes, symbolValidator: module => { var typeName = WellKnownTypes.GetMetadataName(WellKnownType.System_Runtime_CompilerServices_IsReadOnlyAttribute); var type = module.ContainingAssembly.GetTypeByMetadataName(typeName); var method = type.GetMethod("Method"); Assert.Empty(method.GetReturnTypeAttributes()); Assert.Empty(method.Parameters.Single().GetAttributes()); var property = type.GetProperty("Property"); Assert.Empty(property.GetAttributes()); var indexer = type.GetProperty("this[]"); Assert.Empty(indexer.GetAttributes()); Assert.Empty(indexer.Parameters.Single().GetAttributes()); }); } [Fact] public void RefReadOnlyDefinitionsInsideUserDefinedIsReadOnlyAttribute_ClassOverridden_ExternalAssembly() { var reference = CreateCompilation(@" namespace System.Runtime.CompilerServices { public abstract class Parent : System.Attribute { public abstract ref readonly int Method(in int x); public abstract ref readonly int Property { get; } public abstract ref readonly int this[in int x] { get; } } }").ToMetadataReference(); var code = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : Parent { private int value; public override ref readonly int Method(in int x) => ref value; public override ref readonly int Property => ref value; public override ref readonly int this[in int x] => ref value; } }"; CompileAndVerify(code, verify: Verification.Passes, references: new[] { reference }, symbolValidator: module => { var typeName = WellKnownTypes.GetMetadataName(WellKnownType.System_Runtime_CompilerServices_IsReadOnlyAttribute); var type = module.ContainingAssembly.GetTypeByMetadataName(typeName); var method = type.GetMethod("Method"); Assert.Empty(method.GetReturnTypeAttributes()); Assert.Empty(method.Parameters.Single().GetAttributes()); var property = type.GetProperty("Property"); Assert.Empty(property.GetAttributes()); var indexer = type.GetProperty("this[]"); Assert.Empty(indexer.GetAttributes()); Assert.Empty(indexer.Parameters.Single().GetAttributes()); }); } [Fact] public void RefReadOnlyDefinitionsInsideUserDefinedIsReadOnlyAttribute_Class_WrongParent() { var code = @" namespace System.Runtime.CompilerServices { public class TestParent { } public class IsReadOnlyAttribute : TestParent { private int value; public ref readonly int Method(in int x) => ref value; public static int operator +(in IsReadOnlyAttribute x, in IsReadOnlyAttribute y) => 0; public ref readonly int Property => ref value; public ref readonly int this[in int x] => ref value; } }"; CompileAndVerify(code, verify: Verification.Passes, symbolValidator: module => { var isReadOnlyAttributeName = WellKnownTypes.GetMetadataName(WellKnownType.System_Runtime_CompilerServices_IsReadOnlyAttribute); var type = module.ContainingAssembly.GetTypeByMetadataName(isReadOnlyAttributeName); var method = type.GetMethod("Method"); Assert.Empty(method.GetReturnTypeAttributes()); Assert.Empty(method.Parameters.Single().GetAttributes()); var @operator = type.GetMethod("op_Addition"); Assert.Empty(@operator.Parameters[0].GetAttributes()); Assert.Empty(@operator.Parameters[1].GetAttributes()); var property = type.GetProperty("Property"); Assert.Empty(property.GetAttributes()); var indexer = type.GetProperty("this[]"); Assert.Empty(indexer.GetAttributes()); Assert.Empty(indexer.Parameters.Single().GetAttributes()); }); } [Fact] public void RefReadOnlyDefinitionsInsideUserDefinedIsReadOnlyAttribute_Interface() { var code = @" namespace System.Runtime.CompilerServices { public interface IsReadOnlyAttribute { ref readonly int Method(in int x); } }"; CreateCompilation(code).VerifyEmitDiagnostics( // (6,9): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // ref readonly int Method(in int x); Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(6, 9), // (6,33): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // ref readonly int Method(in int x); Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(6, 33)); } [Fact] public void RefReadOnlyDefinitionsInsideUserDefinedIsReadOnlyAttribute_ExplicitInterfaceImplementation_SameAssembly() { var code = @" namespace System.Runtime.CompilerServices { public interface ITest { ref readonly int Method(in int x); ref readonly int Property { get; } ref readonly int this[in int x] { get; } } public class IsReadOnlyAttribute : ITest { private int value; ref readonly int ITest.Method(in int x) => ref value; ref readonly int ITest.Property => ref value; ref readonly int ITest.this[in int x] => ref value; } }"; CompileAndVerify(code, verify: Verification.Passes, symbolValidator: module => { var typeName = WellKnownTypes.GetMetadataName(WellKnownType.System_Runtime_CompilerServices_IsReadOnlyAttribute); var type = module.ContainingAssembly.GetTypeByMetadataName(typeName); var method = type.GetMethod("System.Runtime.CompilerServices.ITest.Method"); Assert.Empty(method.GetReturnTypeAttributes()); Assert.Empty(method.Parameters.Single().GetAttributes()); var property = type.GetProperty("System.Runtime.CompilerServices.ITest.Property"); Assert.Empty(property.GetAttributes()); var indexer = type.GetProperty("System.Runtime.CompilerServices.ITest.Item"); Assert.Empty(indexer.GetAttributes()); Assert.Empty(indexer.Parameters.Single().GetAttributes()); }); } [Fact] public void RefReadOnlyDefinitionsInsideUserDefinedIsReadOnlyAttribute_ExplicitInterfaceImplementation_ExternalAssembly() { var reference = CreateCompilation(@" namespace System.Runtime.CompilerServices { public interface ITest { ref readonly int Method(in int x); ref readonly int Property { get; } ref readonly int this[in int x] { get; } } }").ToMetadataReference(); var code = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : ITest { private int value; ref readonly int ITest.Method(in int x) => ref value; ref readonly int ITest.Property => ref value; ref readonly int ITest.this[in int x] => ref value; } }"; CompileAndVerify(code, verify: Verification.Passes, references: new[] { reference }, symbolValidator: module => { var typeName = WellKnownTypes.GetMetadataName(WellKnownType.System_Runtime_CompilerServices_IsReadOnlyAttribute); var type = module.ContainingAssembly.GetTypeByMetadataName(typeName); var method = type.GetMethod("System.Runtime.CompilerServices.ITest.Method"); Assert.Empty(method.GetReturnTypeAttributes()); Assert.Empty(method.Parameters.Single().GetAttributes()); var property = type.GetProperty("System.Runtime.CompilerServices.ITest.Property"); Assert.Empty(property.GetAttributes()); var indexer = type.GetProperty("System.Runtime.CompilerServices.ITest.Item"); Assert.Empty(indexer.GetAttributes()); Assert.Empty(indexer.Parameters.Single().GetAttributes()); }); } [Fact] public void IsReadOnlyAttributeIsGenerated_ExplicitInterfaceImplementation_SameAssembly() { var code = @" public interface ITest { ref readonly int Method(in int x); ref readonly int Property { get; } ref readonly int this[in int x] { get; } } public class TestImpl : ITest { private int value; ref readonly int ITest.Method(in int x) => ref value; ref readonly int ITest.Property => ref value; ref readonly int ITest.this[in int x] => ref value; }"; CompileAndVerify(code, verify: Verification.Passes, symbolValidator: module => { var type = module.ContainingAssembly.GetTypeByMetadataName("TestImpl"); var method = type.GetMethod("ITest.Method"); Assert.Empty(method.GetReturnTypeAttributes()); Assert.Empty(method.Parameters.Single().GetAttributes()); var property = type.GetProperty("ITest.Property"); Assert.Empty(property.GetAttributes()); var indexer = type.GetProperty("ITest.Item"); Assert.Empty(indexer.GetAttributes()); Assert.Empty(indexer.Parameters.Single().GetAttributes()); }); } [Fact] public void IsReadOnlyAttributeIsGenerated_ExplicitInterfaceImplementation_ExternalAssembly() { var reference = CreateCompilation(@" public interface ITest { ref readonly int Method(in int x); ref readonly int Property { get; } ref readonly int this[in int x] { get; } }").ToMetadataReference(); var code = @" public class TestImpl : ITest { private int value; ref readonly int ITest.Method(in int x) => ref value; ref readonly int ITest.Property => ref value; ref readonly int ITest.this[in int x] => ref value; }"; CompileAndVerify(code, verify: Verification.Passes, references: new[] { reference }, symbolValidator: module => { var type = module.ContainingAssembly.GetTypeByMetadataName("TestImpl"); var method = type.GetMethod("ITest.Method"); Assert.Empty(method.GetReturnTypeAttributes()); Assert.Empty(method.Parameters.Single().GetAttributes()); var property = type.GetProperty("ITest.Property"); Assert.Empty(property.GetAttributes()); var indexer = type.GetProperty("ITest.Item"); Assert.Empty(indexer.GetAttributes()); Assert.Empty(indexer.Parameters.Single().GetAttributes()); }); } [Fact] public void RefReadOnlyDefinitionsInsideUserDefinedIsReadOnlyAttribute_Delegate() { var code = @" namespace System.Runtime.CompilerServices { public delegate ref readonly int IsReadOnlyAttribute(in int x); }"; CreateCompilation(code).VerifyEmitDiagnostics( // (4,21): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // public delegate ref readonly int IsReadOnlyAttribute(in int x); Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(4, 21), // (4,58): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // public delegate ref readonly int IsReadOnlyAttribute(in int x); Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(4, 58)); } [Fact] public void MissingRequiredConstructorWillReportErrorsOnApproriateSyntax_Constructor() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { public IsReadOnlyAttribute(int p) { } } } public class Test { public Test(in int x) { } }"; CreateCompilation(text).VerifyEmitDiagnostics( // (11,17): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // public Test(in int x) { } Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 17)); } [Fact] public void MissingRequiredConstructorWillReportErrorsOnApproriateSyntax_Method() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { public IsReadOnlyAttribute(int p) { } } } public class Test { public ref readonly int Method(in int x) => ref x; }"; CreateCompilation(text).VerifyEmitDiagnostics( // (11,12): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // public ref readonly int Method(in int x) => ref x; Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 12), // (11,36): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // public ref readonly int Method(in int x) => ref x; Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 36)); } [Fact] public void MissingRequiredConstructorWillReportErrorsOnApproriateSyntax_LocalFunction() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { public IsReadOnlyAttribute(int p) { } } } public class Test { public void M() { int x = 0; ref readonly int local(in int p) { return ref p; } local(x); } }"; CreateCompilation(text).VerifyEmitDiagnostics( // (15,9): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // ref readonly int local(in int p) Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(15, 9), // (15,32): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // ref readonly int local(in int p) Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int p").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(15, 32)); } [Fact] public void MissingRequiredConstructorWillReportErrorsOnApproriateSyntax_Lambda() { var reference = CreateCompilation(@" public delegate ref readonly int D(in int x); ").EmitToImageReference(); var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { public IsReadOnlyAttribute(int p) { } } } class Test { public void M1() { M2((in int x) => ref x); } public void M2(D value) { } }"; CreateCompilation(text, references: new[] { reference }).VerifyEmitDiagnostics( // (14,33): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // M2((in int x) => ref x); Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "=>").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(14, 23), // (14,13): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // M2((in int x) => ref x); Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(14, 13)); } [Fact] public void MissingRequiredConstructorWillReportErrorsOnApproriateSyntax_Property() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { public IsReadOnlyAttribute(int p) { } } } public class Test { private int value; public ref readonly int Property => ref value; }"; CreateCompilation(text).VerifyEmitDiagnostics( // (12,12): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // public ref readonly int Property => ref value; Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(12, 12)); } [Fact] public void MissingRequiredConstructorWillReportErrorsOnApproriateSyntax_Indexer() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { public IsReadOnlyAttribute(int p) { } } } public class Test { public ref readonly int this[in int x] => ref x; }"; CreateCompilation(text).VerifyEmitDiagnostics( // (12,12): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // public ref readonly int this[in int x] => ref x; Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(12, 12), // (12,34): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // public ref readonly int this[in int x] => ref x; Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(12, 34)); } [Fact] public void MissingRequiredConstructorWillReportErrorsOnApproriateSyntax_Operator() { var text = @" namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { public IsReadOnlyAttribute(int p) { } } } public class Test { public static int operator + (in Test x, in Test y) => 0; }"; CreateCompilation(text).VerifyEmitDiagnostics( // (11,35): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // public static int operator + (in Test x, in Test y) => 0; Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in Test x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 35), // (11,46): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // public static int operator + (in Test x, in Test y) => 0; Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in Test y").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 46)); } [Fact] public void EmitAttribute_LambdaReturnType() { var source = @"class Program { static void Main() { var f = (ref readonly int () => throw null); f(); } }"; CompileAndVerify( source, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), symbolValidator: module => { var method = module.ContainingAssembly.GetTypeByMetadataName("Program+<>c").GetMethod("<Main>b__0_0"); Assert.Equal(RefKind.RefReadOnly, method.RefKind); }); } [Fact] public void EmitAttribute_LambdaParameters() { var source = @"class Program { static void Main() { var f = (in int x, ref int y) => { }; int x = 1; int y = 2; f(x, ref y); } }"; CompileAndVerify( source, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), symbolValidator: module => { var method = module.ContainingAssembly.GetTypeByMetadataName("Program+<>c").GetMethod("<Main>b__0_0"); Assert.Equal(RefKind.RefReadOnly, method.Parameters[0].RefKind); Assert.Equal(RefKind.Ref, method.Parameters[1].RefKind); }); } [Fact] public void EmitAttribute_LocalFunctionReturnType() { var source = @"class Program { static void Main() { ref readonly int L() => throw null; L(); } }"; CompileAndVerify( source, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), symbolValidator: module => { var method = module.ContainingAssembly.GetTypeByMetadataName("Program").GetMethod("<Main>g__L|0_0"); Assert.Equal(RefKind.RefReadOnly, method.RefKind); }); } [Fact] public void EmitAttribute_LocalFunctionParameters() { var source = @"class Program { static void Main() { void L(ref int x, in int y) { }; int x = 1; int y = 2; L(ref x, y); } }"; CompileAndVerify( source, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), symbolValidator: module => { var method = module.ContainingAssembly.GetTypeByMetadataName("Program").GetMethod("<Main>g__L|0_0"); Assert.Equal(RefKind.Ref, method.Parameters[0].RefKind); Assert.Equal(RefKind.RefReadOnly, method.Parameters[1].RefKind); }); } [Fact] public void EmitAttribute_Lambda_NetModule() { var source = @"class Program { static void Main() { var f1 = (in int x, ref int y) => { }; int x = 1; int y = 2; f1(x, ref y); var f2 = (ref readonly int () => throw null); f2(); } }"; var comp = CreateCompilation(source, options: TestOptions.ReleaseModule); comp.VerifyDiagnostics( // (5,19): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsReadOnlyAttribute' is not defined or imported // var f1 = (in int x, ref int y) => { }; Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(5, 19), // (9,39): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsReadOnlyAttribute' is not defined or imported // var f2 = (ref readonly int () => throw null); Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "=>").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(9, 39)); } [Fact] public void EmitAttribute_LocalFunction_NetModule() { var source = @"class Program { static void Main() { void L1(ref int x, in int y) { }; int x = 1; int y = 2; L1(ref x, y); ref readonly int L2() => throw null; L2(); } }"; var comp = CreateCompilation(source, options: TestOptions.ReleaseModule); comp.VerifyDiagnostics( // (5,28): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsReadOnlyAttribute' is not defined or imported // void L1(ref int x, in int y) { }; Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "in int y").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(5, 28), // (9,9): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsReadOnlyAttribute' is not defined or imported // ref readonly int L2() => throw null; Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(9, 9)); } [Fact] public void EmitAttribute_Lambda_MissingAttributeConstructor() { var sourceA = @"namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : Attribute { private IsReadOnlyAttribute() { } } }"; var sourceB = @"class Program { static void Main() { var f1 = (in int x, ref int y) => { }; int x = 1; int y = 2; f1(x, ref y); var f2 = (ref readonly int () => throw null); f2(); } }"; var comp = CreateCompilation(new[] { sourceA, sourceB }); comp.VerifyDiagnostics( // (5,19): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // var f1 = (in int x, ref int y) => { }; Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(5, 19), // (9,39): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // var f2 = (ref readonly int () => throw null); Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "=>").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(9, 39)); } [Fact] public void EmitAttribute_LocalFunction_MissingAttributeConstructor() { var sourceA = @"namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : Attribute { private IsReadOnlyAttribute() { } } }"; var sourceB = @"class Program { static void Main() { void L1(ref int x, in int y) { }; int x = 1; int y = 2; L1(ref x, y); ref readonly int L2() => throw null; L2(); } }"; var comp = CreateCompilation(new[] { sourceA, sourceB }); comp.VerifyDiagnostics( // (5,28): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // void L1(ref int x, in int y) { }; Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int y").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(5, 28), // (9,9): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' // ref readonly int L2() => throw null; Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(9, 9)); } private void AssertNoIsReadOnlyAttributeExists(AssemblySymbol assembly) { var isReadOnlyAttributeTypeName = WellKnownTypes.GetMetadataName(WellKnownType.System_Runtime_CompilerServices_IsReadOnlyAttribute); Assert.Null(assembly.GetTypeByMetadataName(isReadOnlyAttributeTypeName)); } private void AssertGeneratedEmbeddedAttribute(AssemblySymbol assembly, string expectedTypeName) { var typeSymbol = assembly.GetTypeByMetadataName(expectedTypeName); Assert.NotNull(typeSymbol); Assert.Equal(Accessibility.Internal, typeSymbol.DeclaredAccessibility); var attributes = typeSymbol.GetAttributes().OrderBy(attribute => attribute.AttributeClass.Name).ToArray(); Assert.Equal(2, attributes.Length); Assert.Equal(WellKnownTypes.GetMetadataName(WellKnownType.System_Runtime_CompilerServices_CompilerGeneratedAttribute), attributes[0].AttributeClass.ToDisplayString()); Assert.Equal(AttributeDescription.CodeAnalysisEmbeddedAttribute.FullName, attributes[1].AttributeClass.ToDisplayString()); } private static bool NeedsGeneratedIsReadOnlyAttribute(CSharpCompilation compilation) { return (compilation.GetNeedsGeneratedAttributes() & EmbeddableAttributes.IsReadOnlyAttribute) != 0; } } }