From 62bf9e9685d4fae4e27f7f1f63f25b947fbd400b Mon Sep 17 00:00:00 2001 From: Omar Tawfik Date: Thu, 21 Sep 2017 14:55:54 -0700 Subject: [PATCH 01/16] Create tests to cover test plans #19216 and #20127 --- .../Portable/Binder/Binder.ValueChecks.cs | 54 +-- .../OverloadResolution/OverloadResolution.cs | 2 +- .../Portable/Syntax/SyntaxNodeExtensions.cs | 7 +- .../CodeGenRefReadOnlyParametersTests.cs | 19 + .../CodeGen/CodeGenRefReadonlyReturnTests.cs | 215 +++++++++++ .../Semantics/AmbiguousOverrideTests.cs | 4 +- .../Test/Semantic/Semantics/NameOfTests.cs | 17 + .../Semantics/RefLocalsAndReturnsTests.cs | 72 ++++ .../Semantic/Semantics/SemanticErrorTests.cs | 70 ++-- .../StackAllocSpanExpressionsTests.cs | 144 +++++++ .../Test/Semantic/Semantics/UnsafeTests.cs | 16 + .../Test/Semantic/Semantics/VarianceTests.cs | 26 ++ .../Syntax/Parsing/RefReadonlyReturnsTests.cs | 153 -------- .../Test/Syntax/Parsing/RefReadonlyTests.cs | 360 ++++++++++++++++++ .../Core/Portable/Symbols/RefKind.cs | 4 +- 15 files changed, 942 insertions(+), 221 deletions(-) delete mode 100644 src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyReturnsTests.cs create mode 100644 src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs diff --git a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs index 0fe92ed05ebfd..3b609a3e2471b 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs @@ -517,7 +517,7 @@ private bool CheckParameterValueKind(SyntaxNode node, BoundParameter parameter, ParameterSymbol parameterSymbol = parameter.ParameterSymbol; // all parameters can be passed by ref/out or assigned to - // except "in" parameters, which are readonly + // except "ref readonly" parameters, which are readonly if (parameterSymbol.RefKind == RefKind.RefReadOnly && RequiresAssignableVariable(valueKind)) { ReportReadOnlyError(parameterSymbol, node, valueKind, checkingReceiver, diagnostics); @@ -968,13 +968,13 @@ bool isRefEscape //by default it is safe to escape uint escapeScope = Binder.ExternalScope; - ArrayBuilder inParametersMatchedWithArgs = null; + ArrayBuilder refReadOnlyParametersMatchedWithArgs = null; if (!args.IsDefault) { for (var argIndex = 0; argIndex < args.Length; argIndex++) { - RefKind effectiveRefKind = GetEffectiveRefKind(argIndex, argRefKinds, parameters, argsToParamsOpt, ref inParametersMatchedWithArgs); + RefKind effectiveRefKind = GetEffectiveRefKind(argIndex, argRefKinds, parameters, argsToParamsOpt, ref refReadOnlyParametersMatchedWithArgs); // ref escape scope is the narrowest of // - ref escape of all byref arguments @@ -993,7 +993,7 @@ bool isRefEscape if (escapeScope >= scopeOfTheContainingExpression) { // no longer needed - inParametersMatchedWithArgs?.Free(); + refReadOnlyParametersMatchedWithArgs?.Free(); // can't get any worse return escapeScope; @@ -1001,12 +1001,12 @@ bool isRefEscape } } - // handle omitted optional "in" parameters if there are any - ParameterSymbol unmatchedInParameter = TryGetUnmatchedInParameterAndFreeMatchedArgs(parameters, ref inParametersMatchedWithArgs); + // handle omitted optional "ref readonly" parameters if there are any + ParameterSymbol unmatchedRefReadOnlyParameter = TryGetUnmatchedRefReadOnlyParameterAndFreeMatchedArgs(parameters, ref refReadOnlyParametersMatchedWithArgs); - // unmatched "in" parameter is the same as a literal, its ref escape is scopeOfTheContainingExpression (can't get any worse) + // unmatched "ref readonly" parameter is the same as a literal, its ref escape is scopeOfTheContainingExpression (can't get any worse) // its val escape is ExternalScope (does not affect overal result) - if (unmatchedInParameter != null && isRefEscape) + if (unmatchedRefReadOnlyParameter != null && isRefEscape) { return scopeOfTheContainingExpression; } @@ -1049,12 +1049,12 @@ bool isRefEscape // o no ref or out argument(excluding the receiver and arguments of ref-like types) may have a narrower ref-safe-to-escape than E1; and // o no argument(including the receiver) may have a narrower safe-to-escape than E1. - ArrayBuilder inParametersMatchedWithArgs = null; + ArrayBuilder refReadOnlyParametersMatchedWithArgs = null; if (!args.IsDefault) { for (var argIndex = 0; argIndex < args.Length; argIndex++) { - RefKind effectiveRefKind = GetEffectiveRefKind(argIndex, argRefKinds, parameters, argsToParamsOpt, ref inParametersMatchedWithArgs); + RefKind effectiveRefKind = GetEffectiveRefKind(argIndex, argRefKinds, parameters, argsToParamsOpt, ref refReadOnlyParametersMatchedWithArgs); // ref escape scope is the narrowest of // - ref escape of all byref arguments @@ -1071,7 +1071,7 @@ bool isRefEscape if (!valid) { // no longer needed - inParametersMatchedWithArgs?.Free(); + refReadOnlyParametersMatchedWithArgs?.Free(); ErrorCode errorCode = GetStandardCallEscapeError(checkingReceiver); var paramIndex = argsToParamsOpt.IsDefault ? argIndex : argsToParamsOpt[argIndex]; @@ -1082,14 +1082,14 @@ bool isRefEscape } } - // handle omitted optional "in" parameters if there are any - ParameterSymbol unmatchedInParameter = TryGetUnmatchedInParameterAndFreeMatchedArgs(parameters, ref inParametersMatchedWithArgs); + // handle omitted optional "ref readonly" parameters if there are any + ParameterSymbol unmatchedRefReadOnlyParameter = TryGetUnmatchedRefReadOnlyParameterAndFreeMatchedArgs(parameters, ref refReadOnlyParametersMatchedWithArgs); - // unmatched "in" parameter is the same as a literal, its ref escape is scopeOfTheContainingExpression (can't get any worse) + // unmatched "ref readonly" parameter is the same as a literal, its ref escape is scopeOfTheContainingExpression (can't get any worse) // its val escape is ExternalScope (does not affect overal result) - if (unmatchedInParameter != null && isRefEscape) + if (unmatchedRefReadOnlyParameter != null && isRefEscape) { - Error(diagnostics, GetStandardCallEscapeError(checkingReceiver), syntax, symbol, unmatchedInParameter.Name); + Error(diagnostics, GetStandardCallEscapeError(checkingReceiver), syntax, symbol, unmatchedRefReadOnlyParameter.Name); return false; } @@ -1180,10 +1180,10 @@ private static bool CheckInvocationArgMixing( /// /// Gets "effective" ref kind of an argument. /// Generally we know if a formal argument is passed as ref/out by looking at the call site. - /// However, to distinguish "in" and regular "val" parameters we need to take a look at corresponding parameter, if such exists. - /// NOTE: there are cases like params/vararg, when a corresponding parameter may not exist, then it cannot be an "in". + /// However, to distinguish "ref readonly" and regular "val" parameters we need to take a look at corresponding parameter, if such exists. + /// NOTE: there are cases like params/vararg, when a corresponding parameter may not exist, then it cannot be a "ref readonly". /// - private static RefKind GetEffectiveRefKind(int argIndex, ImmutableArray argRefKinds, ImmutableArray parameters, ImmutableArray argsToParamsOpt, ref ArrayBuilder inParametersMatchedWithArgs) + private static RefKind GetEffectiveRefKind(int argIndex, ImmutableArray argRefKinds, ImmutableArray parameters, ImmutableArray argsToParamsOpt, ref ArrayBuilder refReadOnlyParametersMatchedWithArgs) { var effectiveRefKind = argRefKinds.IsDefault ? RefKind.None : argRefKinds[argIndex]; if (effectiveRefKind == RefKind.None && argIndex < parameters.Length) @@ -1193,8 +1193,8 @@ private static RefKind GetEffectiveRefKind(int argIndex, ImmutableArray if (parameters[paramIndex].RefKind == RefKind.RefReadOnly) { effectiveRefKind = RefKind.RefReadOnly; - inParametersMatchedWithArgs = inParametersMatchedWithArgs ?? ArrayBuilder.GetInstance(parameters.Length, fillWithValue: false); - inParametersMatchedWithArgs[paramIndex] = true; + refReadOnlyParametersMatchedWithArgs = refReadOnlyParametersMatchedWithArgs ?? ArrayBuilder.GetInstance(parameters.Length, fillWithValue: false); + refReadOnlyParametersMatchedWithArgs[paramIndex] = true; } } @@ -1202,11 +1202,11 @@ private static RefKind GetEffectiveRefKind(int argIndex, ImmutableArray } /// - /// Gets an "in" parameter for which there is no argument supplied, if such exists. - /// That indicates an optional "in" parameter. We treat it as an RValue passed by reference via a temporary. + /// Gets a "ref readonly" parameter for which there is no argument supplied, if such exists. + /// That indicates an optional "ref readonly" parameter. We treat it as an RValue passed by reference via a temporary. /// The effective scope of such variable is the immediately containing scope. /// - private static ParameterSymbol TryGetUnmatchedInParameterAndFreeMatchedArgs(ImmutableArray parameters, ref ArrayBuilder inParametersMatchedWithArgs) + private static ParameterSymbol TryGetUnmatchedRefReadOnlyParameterAndFreeMatchedArgs(ImmutableArray parameters, ref ArrayBuilder refReadOnlyParametersMatchedWithArgs) { try { @@ -1221,7 +1221,7 @@ private static ParameterSymbol TryGetUnmatchedInParameterAndFreeMatchedArgs(Immu } if (parameter.RefKind == RefKind.RefReadOnly && - inParametersMatchedWithArgs?[i] != true && + refReadOnlyParametersMatchedWithArgs?[i] != true && parameter.Type.IsByRefLikeType == false) { return parameter; @@ -1233,9 +1233,9 @@ private static ParameterSymbol TryGetUnmatchedInParameterAndFreeMatchedArgs(Immu } finally { - inParametersMatchedWithArgs?.Free(); + refReadOnlyParametersMatchedWithArgs?.Free(); // make sure noone uses it after. - inParametersMatchedWithArgs = null; + refReadOnlyParametersMatchedWithArgs = null; } } diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs index a0ba5e2462970..6742c711fdd7c 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs @@ -2577,7 +2577,7 @@ private RefKind GetEffectiveParameterRefKind(ParameterSymbol parameter, RefKind if (paramRefKind == RefKind.RefReadOnly) { - // "in" parameters are effectively None for the purpose of overload resolution. + // "ref readonly" parameters are effectively None for the purpose of overload resolution. paramRefKind = RefKind.None; } diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeExtensions.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeExtensions.cs index 5b163542dbb61..d7abfd4f4ab7f 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeExtensions.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeExtensions.cs @@ -130,12 +130,7 @@ internal static bool IsLegalSpanStackAllocPosition(this SyntaxNode node) { Debug.Assert(node != null); - while (node.Parent.IsKind(SyntaxKind.CastExpression)) - { - node = node.Parent; - } - - if (node.Parent.IsKind(SyntaxKind.ConditionalExpression)) + while (node.Parent.IsKind(SyntaxKind.CastExpression) || node.Parent.IsKind(SyntaxKind.ConditionalExpression)) { node = node.Parent; } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs index 2ed43f5c115e9..c1033b9540c12 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs @@ -1563,5 +1563,24 @@ .locals init (T V_0) }"); } + [Fact] + public void RefReadOnlyOptionalParameters() + { + CompileAndVerify(@" +using System; +class Program +{ + static void Print(ref readonly int p = 5) + { + Console.Write(p); + } + static void Main() + { + Print(); + Console.Write(""-""); + Print(9); + } +}", expectedOutput: "5-9"); + } } } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs index a0eb06901ae81..52a22b962ad36 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs @@ -1158,5 +1158,220 @@ .maxstack 1 IL_0001: throw }"); } + + [Fact] + public void RefExtensionMethod_PassThrough_LocalNoCopying() + { + CompileAndVerify(@" +public static class Ext +{ + public static ref int M(ref this int p) => ref p; +} +class Test +{ + void M() + { + int x = 5; + x.M(); + } +}", additionalRefs: new[] { SystemCoreRef }, verify: false).VerifyIL("Test.M", @" +{ + // Code size 11 (0xb) + .maxstack 1 + .locals init (int V_0) //x + IL_0000: ldc.i4.5 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call ""ref int Ext.M(ref int)"" + IL_0009: pop + IL_000a: ret +}"); + } + + [Fact] + public void RefExtensionMethod_PassThrough_FieldNoCopying() + { + CompileAndVerify(@" +public static class Ext +{ + public static ref int M(ref this int p) => ref p; +} +class Test +{ + private int x = 5; + void M() + { + x.M(); + } +}", additionalRefs: new[] { SystemCoreRef }, verify: false).VerifyIL("Test.M", @" +{ + // Code size 13 (0xd) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ldflda ""int Test.x"" + IL_0006: call ""ref int Ext.M(ref int)"" + IL_000b: pop + IL_000c: ret +}"); + } + + [Fact] + public void RefExtensionMethod_PassThrough_ChainNoCopying() + { + CompileAndVerify(@" +public static class Ext +{ + public static ref int M(ref this int p) => ref p; +} +class Test +{ + private int x = 5; + void M() + { + x.M().M().M(); + } +}", additionalRefs: new[] { SystemCoreRef }, verify: false).VerifyIL("Test.M", @" +{ + // Code size 23 (0x17) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ldflda ""int Test.x"" + IL_0006: call ""ref int Ext.M(ref int)"" + IL_000b: call ""ref int Ext.M(ref int)"" + IL_0010: call ""ref int Ext.M(ref int)"" + IL_0015: pop + IL_0016: ret +}"); + } + + [Fact] + public void RefReadOnlyExtensionMethod_PassThrough_TempCopying() + { + CompileAndVerify(@" +public static class Ext +{ + public static ref readonly int M(ref readonly this int p) => ref p; +} +class Test +{ + void M() + { + 5.M(); + } +}", additionalRefs: new[] { SystemCoreRef }, verify: false).VerifyIL("Test.M", @" +{ + // Code size 11 (0xb) + .maxstack 1 + .locals init (int V_0) + IL_0000: ldc.i4.5 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call ""ref readonly int Ext.M(ref readonly int)"" + IL_0009: pop + IL_000a: ret +}"); + } + + [Fact] + public void RefReadOnlyExtensionMethod_PassThrough_LocalNoCopying() + { + CompileAndVerify(@" +public static class Ext +{ + public static ref readonly int M(ref readonly this int p) => ref p; +} +class Test +{ + void M() + { + int x = 5; + x.M(); + } +}", additionalRefs: new[] { SystemCoreRef }, verify: false).VerifyIL("Test.M", @" +{ + // Code size 11 (0xb) + .maxstack 1 + .locals init (int V_0) //x + IL_0000: ldc.i4.5 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call ""ref readonly int Ext.M(ref readonly int)"" + IL_0009: pop + IL_000a: ret +}"); + } + + [Fact] + public void RefReadOnlyExtensionMethod_PassThrough_FieldNoCopying() + { + CompileAndVerify(@" +public static class Ext +{ + public static ref readonly int M(ref readonly this int p) => ref p; +} +class Test +{ + private int x = 5; + void M() + { + x.M(); + } +}", additionalRefs: new[] { SystemCoreRef }, verify: false).VerifyIL("Test.M", @" +{ + // Code size 13 (0xd) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ldflda ""int Test.x"" + IL_0006: call ""ref readonly int Ext.M(ref readonly int)"" + IL_000b: pop + IL_000c: ret +}"); + } + + [Fact] + public void RefReadOnlyExtensionMethod_PassThrough_ChainNoCopying() + { + CompileAndVerify(@" +public static class Ext +{ + public static ref readonly int M(ref readonly this int p) => ref p; +} +class Test +{ + private int x = 5; + void M() + { + x.M().M().M(); + } +}", additionalRefs: new[] { SystemCoreRef }, verify: false).VerifyIL("Test.M", @" +{ + // Code size 23 (0x17) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ldflda ""int Test.x"" + IL_0006: call ""ref readonly int Ext.M(ref readonly int)"" + IL_000b: call ""ref readonly int Ext.M(ref readonly int)"" + IL_0010: call ""ref readonly int Ext.M(ref readonly int)"" + IL_0015: pop + IL_0016: ret +}"); + } + + [Fact] + public void RefReadOnlyReturnOptionalValue() + { + CompileAndVerify(@" +class Program +{ + static ref readonly string M(ref readonly string s = ""optional"") => ref s; + + static void Main() + { + System.Console.Write(M()); + System.Console.Write(""-""); + System.Console.Write(M(""provided"")); + } +}", verify: false, expectedOutput: "optional-provided"); + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs index c8470fbe537ba..61b11cff4f671 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs @@ -1336,7 +1336,7 @@ public void Method(ref readonly int x) { } var comp = CreateStandardCompilation(text).VerifyDiagnostics( // (5,17): error CS0663: 'TestClass' cannot define an overloaded method that differs only on parameter modifiers 'in' and 'ref' // public void Method(ref readonly int x) { } - Diagnostic(ErrorCode.ERR_OverloadRefKind, "Method").WithArguments("TestClass", "method", "in", "ref").WithLocation(5, 17)); + Diagnostic(ErrorCode.ERR_OverloadRefKind, "Method").WithArguments("TestClass", "method", "ref readonly", "ref").WithLocation(5, 17)); } [Fact] @@ -1353,7 +1353,7 @@ public void Method(ref readonly int x) { } var comp = CreateStandardCompilation(text).VerifyDiagnostics( // (5,17): error CS0663: 'TestClass' cannot define an overloaded method that differs only on parameter modifiers 'in' and 'out' // public void Method(ref readonly int x) { } - Diagnostic(ErrorCode.ERR_OverloadRefKind, "Method").WithArguments("TestClass", "method", "in", "out").WithLocation(5, 17)); + Diagnostic(ErrorCode.ERR_OverloadRefKind, "Method").WithArguments("TestClass", "method", "ref readonly", "out").WithLocation(5, 17)); } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs index 203360f3361c4..7a64be353844d 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs @@ -1326,5 +1326,22 @@ public static void Main(string[] args) var compilation = CreateCompilationWithMscorlib45(source, null, new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithAllowUnsafe(true)); CompileAndVerify(compilation, expectedOutput: "normalField fixedField").VerifyDiagnostics(); } + + [Fact] + public void PassingNameOfToRefReadOnlyShouldCopy() + { + CompileAndVerify(@" +class Program +{ + public static void Main() + { + M(nameof(Main)); + } + private static void M(ref readonly string value) + { + System.Console.WriteLine(value); + } +}", expectedOutput: "Main"); + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs index fb3573e2dd8fd..bee602121d1a0 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs @@ -2696,5 +2696,77 @@ async Task TestMethod() Diagnostic(ErrorCode.ERR_RefReturningCallAndAwait, "await Task.FromResult(1)").WithArguments("TestClass.this[int, int].get").WithLocation(36, 22) ); } + + [Fact] + public void RefReadOnlyInAsyncMethodDisallowed() + { + CreateCompilationWithMscorlib45(@" +using System.Threading.Tasks; +class Test +{ + async Task Method(ref readonly int p) + { + await Task.FromResult(0); + } +}").VerifyDiagnostics( + // (5,40): error CS1988: Async methods cannot have ref or out parameters + // async Task Method(ref readonly int p) + Diagnostic(ErrorCode.ERR_BadAsyncArgType, "p").WithLocation(5, 40)); + } + + [Fact] + public void RefReadOnlyIIteratorMethodDisallowed() + { + CreateCompilationWithMscorlib45(@" +using System.Collections.Generic; +class Test +{ + IEnumerable Method(ref readonly int p) + { + yield return 0; + yield return 1; + yield return 2; + } +}").VerifyDiagnostics( + // (5,46): error CS1623: Iterators cannot have ref or out parameters + // IEnumerable Method(ref readonly int p) + Diagnostic(ErrorCode.ERR_BadIteratorArgType, "p").WithLocation(5, 46)); + } + + [Fact] + public void RefReadOnlyInIteratorMethods() + { + CreateStandardCompilation(@" +using System.Collections.Generic; +class Test +{ + public IEnumerator GetEnumerator(ref readonly int p) + { + yield return 0; + } +}").VerifyDiagnostics( + // (5,60): error CS1623: Iterators cannot have ref or out parameters + // public IEnumerator GetEnumerator(ref readonly int p) + Diagnostic(ErrorCode.ERR_BadIteratorArgType, "p").WithLocation(5, 60)); + } + + [Fact] + public void CannotCallRefReadOnlyMethodsUsingDiscardParameter() + { + CreateStandardCompilation(@" +class Test +{ + void M(ref readonly int p) + { + } + void N() + { + M(_); + } +}").VerifyDiagnostics( + // (9,11): error CS0103: The name '_' does not exist in the current context + // M(_); + Diagnostic(ErrorCode.ERR_NameNotInContext, "_").WithArguments("_").WithLocation(9, 11)); + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs index e9c95622e828e..72562a7948b79 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs @@ -8536,41 +8536,51 @@ unsafe public static void Main() } [Fact] - public void CS0255ERR_StackallocInCatchFinally() + public void CS0255ERR_StackallocInFinally() { var text = @" -using System; - -public class TestTryFinally +unsafe class Test { - public static unsafe void Test() - { - int i = 123; - string s = ""Some string""; - object o = s; - - try - { - // Conversion is not valid; o contains a string not an int - i = (int) o; - } - - finally - { - Console.Write(""i = {0}"", i); - int* fib = stackalloc int[100]; // CS0255 - } - } + void M() + { + try + { + // Something + } + finally + { + int* fib = stackalloc int[100]; + } + } +}"; + CreateStandardCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (12,24): error CS0255: stackalloc may not be used in a catch or finally block + // int* fib = stackalloc int[100]; + Diagnostic(ErrorCode.ERR_StackallocInCatchFinally, "stackalloc int[100]").WithLocation(12, 24)); + } - public static void Main() - { - } -} -"; + [Fact] + public void CS0255ERR_StackallocInCatch() + { + var text = @" +unsafe class Test +{ + void M() + { + try + { + // Something + } + catch + { + int* fib = stackalloc int[100]; + } + } +}"; CreateStandardCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( - // (21,21): error CS0255: stackalloc may not be used in a catch or finally block - // int* fib = stackalloc int[100]; // CS0255 - Diagnostic(ErrorCode.ERR_StackallocInCatchFinally, "stackalloc int[100]")); + // (12,24): error CS0255: stackalloc may not be used in a catch or finally block + // int* fib = stackalloc int[100]; + Diagnostic(ErrorCode.ERR_StackallocInCatchFinally, "stackalloc int[100]").WithLocation(12, 24)); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocSpanExpressionsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocSpanExpressionsTests.cs index 5f55c9f2bec66..15e546e292181 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocSpanExpressionsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocSpanExpressionsTests.cs @@ -303,6 +303,29 @@ void M() Diagnostic(ErrorCode.ERR_InvalidQM, "true ? stackalloc int [10] : a").WithArguments("stackalloc int[10]", "System.Span").WithLocation(8, 17)); } + [Fact] + public void ConditionalExpressionOnSpan_Nested() + { + CreateCompilationWithMscorlibAndSpan(@" +class Test +{ + bool N() => true; + + void M() + { + var x = N() + ? N() + ? stackalloc int [1] + : stackalloc int [2] + : N() + ? stackalloc int[3] + : N() + ? stackalloc int[4] + : stackalloc int[5]; + } +}", TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + [Fact] public void BooleanOperatorOnSpan_NoTargetTyping() { @@ -342,6 +365,22 @@ void M() Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "stackalloc int[10]").WithArguments("ref structs", "7.2").WithLocation(7, 23)); } + [Fact] + public void StackAllocSyntaxProducesUnsafeErrorInSafeCode() + { + CreateStandardCompilation(@" +class Test +{ + void M() + { + var x = stackalloc int[10]; + } +}", options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (6,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // var x = stackalloc int[10]; + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "stackalloc int[10]").WithLocation(6, 17)); + } + [Fact] public void StackAllocInUsing1() { @@ -508,5 +547,110 @@ static void Main() Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(7, 16) ); } + + [Fact] + public void StackAllocWithDynamic() + { + CreateStandardCompilation(@" +class Program +{ + static void Main() + { + var d = stackalloc dynamic[10]; + } +}").VerifyDiagnostics( + // (6,33): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('dynamic') + // var d = stackalloc dynamic[10]; + Diagnostic(ErrorCode.ERR_ManagedAddr, "dynamic").WithArguments("dynamic").WithLocation(6, 28)); + } + + [Fact] + public void StackAllocWithDynamicSpan() + { + CreateCompilationWithMscorlibAndSpan(@" +using System; +class Program +{ + static void Main() + { + Span d = stackalloc dynamic[10]; + } +}").VerifyDiagnostics( + // (7,38): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('dynamic') + // Span d = stackalloc dynamic[10]; + Diagnostic(ErrorCode.ERR_ManagedAddr, "dynamic").WithArguments("dynamic").WithLocation(7, 38)); + } + + [Fact] + public void StackAllocAsArgument() + { + CreateStandardCompilation(@" +class Program +{ + static void N(object p) { } + + static void Main() + { + N(stackalloc int[10]); + } +}").VerifyDiagnostics( + // (8,11): error CS1525: Invalid expression term 'stackalloc' + // N(stackalloc int[10]); + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(8, 11)); + } + + [Fact] + public void StackAllocInParenthesis() + { + CreateStandardCompilation(@" +class Program +{ + static void Main() + { + var x = (stackalloc int[10]); + } +}").VerifyDiagnostics( + // (6,18): error CS1525: Invalid expression term 'stackalloc' + // var x = (stackalloc int[10]); + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(6, 18)); + } + + [Fact] + public void StackAllocInNullConditionalOperator() + { + CreateStandardCompilation(@" +class Program +{ + static void Main() + { + var x = stackalloc int[1] ?? stackalloc int[2]; + } +}").VerifyDiagnostics( + // (6,17): error CS1525: Invalid expression term 'stackalloc' + // var x = stackalloc int[1] ?? stackalloc int[2]; + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(6, 17), + // (6,38): error CS1525: Invalid expression term 'stackalloc' + // var x = stackalloc int[1] ?? stackalloc int[2]; + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(6, 38)); + } + + [Fact] + public void StackAllocInCastAndConditionalOperator() + { + CreateCompilationWithMscorlibAndSpan(@" +using System; +class Test +{ + public void Method() + { + Test value = true ? new Test() : (Test)stackalloc int[10]; + } + + public static explicit operator Test(Span value) + { + return new Test(); + } +}", TestOptions.ReleaseDll).VerifyDiagnostics(); + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs index 559c9c11a431a..7c0dadb31601b 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs @@ -8561,6 +8561,22 @@ static unsafe void Main() CompileAndVerify(text, options: TestOptions.UnsafeReleaseExe, expectedOutput: @"4812"); } + [Fact] + public void CannotTakeAddressOfRefReadOnlyParameter() + { + CreateStandardCompilation(@" +public class Test +{ + unsafe void M(ref readonly int p) + { + int* pointer = &p; + } +}", options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (6,25): error CS0211: Cannot take the address of the given expression + // int* pointer = &p; + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "p").WithLocation(6, 25)); + } + #endregion } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/VarianceTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/VarianceTests.cs index 16db7be15c2a0..5793ce918b456 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/VarianceTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/VarianceTests.cs @@ -627,5 +627,31 @@ interface I : // interface I : Diagnostic(ErrorCode.ERR_UnexpectedVariance, "T").WithArguments("I", "T", "covariant", "contravariantly").WithLocation(14, 17)); } + + [Fact] + public void CovarianceBoundariesForRefReadOnly_Parameters() + { + CreateStandardCompilation(@" +interface ITest +{ + void M(ref readonly T p); +}").VerifyDiagnostics( + // (4,25): error CS1961: Invalid variance: The type parameter 'T' must be invariantly valid on 'ITest.M(ref readonly T)'. 'T' is contravariant. + // void M(ref readonly T p); + Diagnostic(ErrorCode.ERR_UnexpectedVariance, "T").WithArguments("ITest.M(ref readonly T)", "T", "contravariant", "invariantly").WithLocation(4, 25)); + } + + [Fact] + public void CovarianceBoundariesForRefReadOnly_ReturnType() + { + CreateStandardCompilation(@" +interface ITest +{ + ref readonly T M(); +}").VerifyDiagnostics( + // (4,5): error CS1961: Invalid variance: The type parameter 'T' must be invariantly valid on 'ITest.M()'. 'T' is contravariant. + // ref readonly T M(); + Diagnostic(ErrorCode.ERR_UnexpectedVariance, "ref readonly T").WithArguments("ITest.M()", "T", "contravariant", "invariantly").WithLocation(4, 5)); + } } } diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyReturnsTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyReturnsTests.cs deleted file mode 100644 index b33ce2f9a2b39..0000000000000 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyReturnsTests.cs +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Xunit; -using System.Linq; -using Microsoft.CodeAnalysis.CSharp.Test.Utilities; -using Microsoft.CodeAnalysis.Test.Utilities; -using Roslyn.Test.Utilities; -using Xunit.Abstractions; - -namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Parsing -{ - [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public class RefReadonlyReturnsTests : ParsingTests - { - public RefReadonlyReturnsTests(ITestOutputHelper output) : base(output) { } - - protected override SyntaxTree ParseTree(string text, CSharpParseOptions options) - { - return SyntaxFactory.ParseSyntaxTree(text, options: options); - } - - [Fact] - public void RefReadonlyReturn_CSharp7() - { - var text = @" -unsafe class Program -{ - delegate ref readonly int D1(); - - static ref readonly T M() - { - return ref (new T[1])[0]; - } - - public virtual ref readonly int* P1 => throw null; - - public ref readonly int[][] this[int i] => throw null; -} -"; - - var comp = CreateCompilationWithMscorlib45(text, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_1), options: TestOptions.UnsafeDebugDll); - comp.VerifyDiagnostics( - // (4,18): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. - // delegate ref readonly int D1(); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "readonly").WithArguments("readonly references", "7.2").WithLocation(4, 18), - // (6,16): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. - // static ref readonly T M() - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "readonly").WithArguments("readonly references", "7.2").WithLocation(6, 16), - // (11,24): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. - // public virtual ref readonly int* P1 => throw null; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "readonly").WithArguments("readonly references", "7.2").WithLocation(11, 24), - // (13,16): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. - // public ref readonly int[][] this[int i] => throw null; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "readonly").WithArguments("readonly references", "7.2").WithLocation(13, 16) - ); - } - - [Fact] - public void RefReadonlyReturn_Unexpected() - { - var text = @" - -class Program -{ - static void Main() - { - } - - ref readonly int Field; - - public static ref readonly Program operator +(Program x, Program y) - { - throw null; - } - - // this parses fine - static async ref readonly Task M() - { - throw null; - } - - public ref readonly virtual int* P1 => throw null; - -} -"; - - ParseAndValidate(text, TestOptions.Regular, - // (9,27): error CS1003: Syntax error, '(' expected - // ref readonly int Field; - Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments("(", ";").WithLocation(9, 27), - // (9,27): error CS1026: ) expected - // ref readonly int Field; - Diagnostic(ErrorCode.ERR_CloseParenExpected, ";").WithLocation(9, 27), - // (11,41): error CS1519: Invalid token 'operator' in class, struct, or interface member declaration - // public static ref readonly Program operator +(Program x, Program y) - Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "operator").WithArguments("operator").WithLocation(11, 41), - // (11,41): error CS1519: Invalid token 'operator' in class, struct, or interface member declaration - // public static ref readonly Program operator +(Program x, Program y) - Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "operator").WithArguments("operator").WithLocation(11, 41), - // (12,5): error CS1519: Invalid token '{' in class, struct, or interface member declaration - // { - Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(12, 5), - // (12,5): error CS1519: Invalid token '{' in class, struct, or interface member declaration - // { - Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(12, 5), - // (22,25): error CS1031: Type expected - // public ref readonly virtual int* P1 => throw null; - Diagnostic(ErrorCode.ERR_TypeExpected, "virtual").WithLocation(22, 25), - // (24,1): error CS1022: Type or namespace definition, or end-of-file expected - // } - Diagnostic(ErrorCode.ERR_EOFExpected, "}").WithLocation(24, 1)); - } - - [Fact] - public void RefReadonlyReturn_UnexpectedBindTime() - { - var text = @" - -class Program -{ - static void Main() - { - ref readonly int local = ref (new int[1])[0]; - - (ref readonly int, ref readonly int Alice)? t = null; - - System.Collections.Generic.List x = null; - - Use(local); - Use(t); - Use(x); - } - - static void Use(T dummy) - { - } -} -"; - var comp = CreateCompilationWithMscorlib45(text, new[] { ValueTupleRef, SystemRuntimeFacadeRef }); - comp.VerifyDiagnostics( - // (9,10): error CS1073: Unexpected token 'ref' - // (ref readonly int, ref readonly int Alice)? t = null; - Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(9, 10), - // (9,28): error CS1073: Unexpected token 'ref' - // (ref readonly int, ref readonly int Alice)? t = null; - Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(9, 28), - // (11,41): error CS1073: Unexpected token 'ref' - // System.Collections.Generic.List x = null; - Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(11, 41) - ); - } - } -} diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs new file mode 100644 index 0000000000000..72ec9b178a76b --- /dev/null +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs @@ -0,0 +1,360 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Xunit; +using System.Linq; +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; +using Xunit.Abstractions; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Parsing +{ + [CompilerTrait(CompilerFeature.ReadOnlyReferences)] + public class RefReadonlyTests : ParsingTests + { + public RefReadonlyTests(ITestOutputHelper output) : base(output) { } + + protected override SyntaxTree ParseTree(string text, CSharpParseOptions options) + { + return SyntaxFactory.ParseSyntaxTree(text, options: options); + } + + [Fact] + public void RefReadonlyReturn_CSharp7() + { + var text = @" +unsafe class Program +{ + delegate ref readonly int D1(); + + static ref readonly T M() + { + return ref (new T[1])[0]; + } + + public virtual ref readonly int* P1 => throw null; + + public ref readonly int[][] this[int i] => throw null; +} +"; + + var comp = CreateCompilationWithMscorlib45(text, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_1), options: TestOptions.UnsafeDebugDll); + comp.VerifyDiagnostics( + // (4,18): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. + // delegate ref readonly int D1(); + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "readonly").WithArguments("readonly references", "7.2").WithLocation(4, 18), + // (6,16): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. + // static ref readonly T M() + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "readonly").WithArguments("readonly references", "7.2").WithLocation(6, 16), + // (11,24): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. + // public virtual ref readonly int* P1 => throw null; + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "readonly").WithArguments("readonly references", "7.2").WithLocation(11, 24), + // (13,16): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. + // public ref readonly int[][] this[int i] => throw null; + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "readonly").WithArguments("readonly references", "7.2").WithLocation(13, 16) + ); + } + + [Fact] + public void RefReadonlyReturn_Unexpected() + { + var text = @" + +class Program +{ + static void Main() + { + } + + ref readonly int Field; + + public static ref readonly Program operator +(Program x, Program y) + { + throw null; + } + + // this parses fine + static async ref readonly Task M() + { + throw null; + } + + public ref readonly virtual int* P1 => throw null; + +} +"; + + ParseAndValidate(text, TestOptions.Regular, + // (9,27): error CS1003: Syntax error, '(' expected + // ref readonly int Field; + Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments("(", ";").WithLocation(9, 27), + // (9,27): error CS1026: ) expected + // ref readonly int Field; + Diagnostic(ErrorCode.ERR_CloseParenExpected, ";").WithLocation(9, 27), + // (11,41): error CS1519: Invalid token 'operator' in class, struct, or interface member declaration + // public static ref readonly Program operator +(Program x, Program y) + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "operator").WithArguments("operator").WithLocation(11, 41), + // (11,41): error CS1519: Invalid token 'operator' in class, struct, or interface member declaration + // public static ref readonly Program operator +(Program x, Program y) + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "operator").WithArguments("operator").WithLocation(11, 41), + // (12,5): error CS1519: Invalid token '{' in class, struct, or interface member declaration + // { + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(12, 5), + // (12,5): error CS1519: Invalid token '{' in class, struct, or interface member declaration + // { + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(12, 5), + // (22,25): error CS1031: Type expected + // public ref readonly virtual int* P1 => throw null; + Diagnostic(ErrorCode.ERR_TypeExpected, "virtual").WithLocation(22, 25), + // (24,1): error CS1022: Type or namespace definition, or end-of-file expected + // } + Diagnostic(ErrorCode.ERR_EOFExpected, "}").WithLocation(24, 1)); + } + + [Fact] + public void RefReadonlyReturn_UnexpectedBindTime() + { + var text = @" + +class Program +{ + static void Main() + { + ref readonly int local = ref (new int[1])[0]; + + (ref readonly int, ref readonly int Alice)? t = null; + + System.Collections.Generic.List x = null; + + Use(local); + Use(t); + Use(x); + } + + static void Use(T dummy) + { + } +} +"; + var comp = CreateCompilationWithMscorlib45(text, new[] { ValueTupleRef, SystemRuntimeFacadeRef }); + comp.VerifyDiagnostics( + // (9,10): error CS1073: Unexpected token 'ref' + // (ref readonly int, ref readonly int Alice)? t = null; + Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(9, 10), + // (9,28): error CS1073: Unexpected token 'ref' + // (ref readonly int, ref readonly int Alice)? t = null; + Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(9, 28), + // (11,41): error CS1073: Unexpected token 'ref' + // System.Collections.Generic.List x = null; + Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(11, 41)); + } + + [Fact] + public void RefReadOnlyLocalsAreDisallowed() + { + CreateStandardCompilation(@" +class Test +{ + void M() + { + int value = 0; + ref int valid = ref value; + ref readonly int invalid = ref readonly value; + } +}").GetParseDiagnostics().Verify( + // (8,40): error CS1525: Invalid expression term 'readonly' + // ref readonly int invalid = ref readonly value; + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "readonly").WithArguments("readonly").WithLocation(8, 40), + // (8,40): error CS1002: ; expected + // ref readonly int invalid = ref readonly value; + Diagnostic(ErrorCode.ERR_SemicolonExpected, "readonly").WithLocation(8, 40), + // (8,40): error CS0106: The modifier 'readonly' is not valid for this item + // ref readonly int invalid = ref readonly value; + Diagnostic(ErrorCode.ERR_BadMemberFlag, "readonly").WithArguments("readonly").WithLocation(8, 40), + // (8,54): error CS1001: Identifier expected + // ref readonly int invalid = ref readonly value; + Diagnostic(ErrorCode.ERR_IdentifierExpected, ";").WithLocation(8, 54)); + } + + [Fact] + public void LocalsWithRefReadOnlyExpressionsAreDisallowed() + { + CreateStandardCompilation(@" +class Test +{ + void M() + { + int value = 0; + ref int valid = ref value; + ref int invalid = ref readonly value; + } +}").GetParseDiagnostics().Verify( + // (8,31): error CS1525: Invalid expression term 'readonly' + // ref int invalid = ref readonly value; + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "readonly").WithArguments("readonly").WithLocation(8, 31), + // (8,31): error CS1002: ; expected + // ref int invalid = ref readonly value; + Diagnostic(ErrorCode.ERR_SemicolonExpected, "readonly").WithLocation(8, 31), + // (8,31): error CS0106: The modifier 'readonly' is not valid for this item + // ref int invalid = ref readonly value; + Diagnostic(ErrorCode.ERR_BadMemberFlag, "readonly").WithArguments("readonly").WithLocation(8, 31), + // (8,45): error CS1001: Identifier expected + // ref int invalid = ref readonly value; + Diagnostic(ErrorCode.ERR_IdentifierExpected, ";").WithLocation(8, 45)); + } + + [Fact] + public void ReturnRefReadOnlyAreDisallowed() + { + CreateStandardCompilation(@" +class Test +{ + int value = 0; + + ref readonly int Valid() => ref value; + ref readonly int Invalid() => ref readonly value; + +}").GetParseDiagnostics().Verify( + // (7,39): error CS1525: Invalid expression term 'readonly' + // ref readonly int Invalid() => ref readonly value; + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "readonly").WithArguments("readonly").WithLocation(7, 39), + // (7,39): error CS1002: ; expected + // ref readonly int Invalid() => ref readonly value; + Diagnostic(ErrorCode.ERR_SemicolonExpected, "readonly").WithLocation(7, 39), + // (7,53): error CS1519: Invalid token ';' in class, struct, or interface member declaration + // ref readonly int Invalid() => ref readonly value; + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(7, 53), + // (7,53): error CS1519: Invalid token ';' in class, struct, or interface member declaration + // ref readonly int Invalid() => ref readonly value; + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(7, 53)); + } + + [Fact] + public void RefReadOnlyForEachAreDisallowed() + { + CreateStandardCompilation(@" +class Test +{ + void M() + { + var ar = new int[] { 1, 2, 3 }; + + foreach(ref readonly v in ar) + { + } + } +}").GetParseDiagnostics().Verify( + // (8,17): error CS1525: Invalid expression term 'ref' + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "ref").WithArguments("ref").WithLocation(8, 17), + // (8,17): error CS1515: 'in' expected + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_InExpected, "ref").WithLocation(8, 17), + // (8,17): error CS0230: Type and identifier are both required in a foreach statement + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_BadForeachDecl, "ref").WithLocation(8, 17), + // (8,17): error CS1525: Invalid expression term 'ref' + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "ref").WithArguments("ref").WithLocation(8, 17), + // (8,17): error CS1026: ) expected + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_CloseParenExpected, "ref").WithLocation(8, 17), + // (8,32): error CS1001: Identifier expected + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_IdentifierExpected, "in").WithLocation(8, 32), + // (8,32): error CS1003: Syntax error, ',' expected + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_SyntaxError, "in").WithArguments(",", "in").WithLocation(8, 32), + // (8,35): error CS1002: ; expected + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_SemicolonExpected, "ar").WithLocation(8, 35), + // (8,37): error CS1002: ; expected + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_SemicolonExpected, ")").WithLocation(8, 37), + // (8,37): error CS1513: } expected + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_RbraceExpected, ")").WithLocation(8, 37)); + } + + [Fact] + public void RefReadOnlyAtCallSite() + { + CreateStandardCompilation(@" +class Test +{ + void M(ref readonly int p) + { + } + void N() + { + int x = 0; + M(ref readonly x); + } +}").GetParseDiagnostics().Verify( + // (10,15): error CS1525: Invalid expression term 'readonly' + // M(ref readonly x); + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "readonly").WithArguments("readonly").WithLocation(10, 15), + // (10,15): error CS1026: ) expected + // M(ref readonly x); + Diagnostic(ErrorCode.ERR_CloseParenExpected, "readonly").WithLocation(10, 15), + // (10,15): error CS1002: ; expected + // M(ref readonly x); + Diagnostic(ErrorCode.ERR_SemicolonExpected, "readonly").WithLocation(10, 15), + // (10,15): error CS0106: The modifier 'readonly' is not valid for this item + // M(ref readonly x); + Diagnostic(ErrorCode.ERR_BadMemberFlag, "readonly").WithArguments("readonly").WithLocation(10, 15), + // (10,25): error CS1001: Identifier expected + // M(ref readonly x); + Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(10, 25), + // (10,25): error CS1002: ; expected + // M(ref readonly x); + Diagnostic(ErrorCode.ERR_SemicolonExpected, ")").WithLocation(10, 25), + // (10,25): error CS1513: } expected + // M(ref readonly x); + Diagnostic(ErrorCode.ERR_RbraceExpected, ")").WithLocation(10, 25)); + } + + [Fact] + public void InverseReadOnlyRefShouldBeIllegal() + { + CreateStandardCompilation(@" +class Test +{ + void M(readonly ref int p) + { + } +}").GetParseDiagnostics().Verify( + // (4,12): error CS1026: ) expected + // void M(readonly ref int p) + Diagnostic(ErrorCode.ERR_CloseParenExpected, "readonly").WithLocation(4, 12), + // (4,12): error CS1002: ; expected + // void M(readonly ref int p) + Diagnostic(ErrorCode.ERR_SemicolonExpected, "readonly").WithLocation(4, 12), + // (4,30): error CS1003: Syntax error, '(' expected + // void M(readonly ref int p) + Diagnostic(ErrorCode.ERR_SyntaxError, ")").WithArguments("(", ")").WithLocation(4, 30)); + } + + [Fact] + public void RefReadOnlyReturnIllegalInOperators() + { + CreateStandardCompilation(@" +public class Test +{ + public static ref readonly bool operator!(Test obj) => throw null; +}").GetParseDiagnostics().Verify( + // (4,37): error CS1519: Invalid token 'operator' in class, struct, or interface member declaration + // public static ref readonly bool operator!(Test obj) => throw null; + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "operator").WithArguments("operator").WithLocation(4, 37), + // (4,37): error CS1519: Invalid token 'operator' in class, struct, or interface member declaration + // public static ref readonly bool operator!(Test obj) => throw null; + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "operator").WithArguments("operator").WithLocation(4, 37), + // (4,55): error CS8124: Tuple must contain at least two elements. + // public static ref readonly bool operator!(Test obj) => throw null; + Diagnostic(ErrorCode.ERR_TupleTooFewElements, ")").WithLocation(4, 55), + // (4,57): error CS1519: Invalid token '=>' in class, struct, or interface member declaration + // public static ref readonly bool operator!(Test obj) => throw null; + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=>").WithArguments("=>").WithLocation(4, 57)); + } + } +} diff --git a/src/Compilers/Core/Portable/Symbols/RefKind.cs b/src/Compilers/Core/Portable/Symbols/RefKind.cs index a3dda24d50e46..085214ca7fd02 100644 --- a/src/Compilers/Core/Portable/Symbols/RefKind.cs +++ b/src/Compilers/Core/Portable/Symbols/RefKind.cs @@ -25,7 +25,7 @@ public enum RefKind : byte Out = 2, /// - /// Indicates a "ref readonly" or an "in" parameter. + /// Indicates a "ref readonly" parameter. /// RefReadOnly = 3, } @@ -38,7 +38,7 @@ internal static string ToParameterDisplayString(this RefKind kind) { case RefKind.Out: return "out"; case RefKind.Ref: return "ref"; - case RefKind.RefReadOnly: return "in"; + case RefKind.RefReadOnly: return "ref readonly"; default: throw new ArgumentException($"Invalid RefKind for parameters: {kind}"); } } From 2b23d057ce406f87ecc0fba0f5d59851a1bc713d Mon Sep 17 00:00:00 2001 From: Omar Tawfik Date: Thu, 21 Sep 2017 19:59:12 -0700 Subject: [PATCH 02/16] clean up --- .../CSharp/Portable/Syntax/SyntaxNodeExtensions.cs | 7 ++++++- .../Test/Semantic/Semantics/AmbiguousOverrideTests.cs | 4 ++-- .../Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeExtensions.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeExtensions.cs index d7abfd4f4ab7f..e5d65c9153164 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeExtensions.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeExtensions.cs @@ -130,7 +130,12 @@ internal static bool IsLegalSpanStackAllocPosition(this SyntaxNode node) { Debug.Assert(node != null); - while (node.Parent.IsKind(SyntaxKind.CastExpression) || node.Parent.IsKind(SyntaxKind.ConditionalExpression)) + if (node.Parent.IsKind(SyntaxKind.CastExpression)) + { + node = node.Parent; + } + + while (node.Parent.IsKind(SyntaxKind.ConditionalExpression)) { node = node.Parent; } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs index 61b11cff4f671..0abd1d9906092 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs @@ -1334,7 +1334,7 @@ public void Method(ref readonly int x) { } }"; var comp = CreateStandardCompilation(text).VerifyDiagnostics( - // (5,17): error CS0663: 'TestClass' cannot define an overloaded method that differs only on parameter modifiers 'in' and 'ref' + // (5,17): error CS0663: 'TestClass' cannot define an overloaded method that differs only on parameter modifiers 'ref readonly' and 'ref' // public void Method(ref readonly int x) { } Diagnostic(ErrorCode.ERR_OverloadRefKind, "Method").WithArguments("TestClass", "method", "ref readonly", "ref").WithLocation(5, 17)); } @@ -1351,7 +1351,7 @@ public void Method(ref readonly int x) { } }"; var comp = CreateStandardCompilation(text).VerifyDiagnostics( - // (5,17): error CS0663: 'TestClass' cannot define an overloaded method that differs only on parameter modifiers 'in' and 'out' + // (5,17): error CS0663: 'TestClass' cannot define an overloaded method that differs only on parameter modifiers 'ref readonly' and 'out' // public void Method(ref readonly int x) { } Diagnostic(ErrorCode.ERR_OverloadRefKind, "Method").WithArguments("TestClass", "method", "ref readonly", "out").WithLocation(5, 17)); } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs index bee602121d1a0..bb2273b1b1af9 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs @@ -2715,7 +2715,7 @@ async Task Method(ref readonly int p) } [Fact] - public void RefReadOnlyIIteratorMethodDisallowed() + public void RefReadOnlyInIteratorMethodsDisallowed() { CreateCompilationWithMscorlib45(@" using System.Collections.Generic; @@ -2734,7 +2734,7 @@ IEnumerable Method(ref readonly int p) } [Fact] - public void RefReadOnlyInIteratorMethods() + public void RefReadOnlyInEnumeratorMethodsDisallowed() { CreateStandardCompilation(@" using System.Collections.Generic; From 3578da70b82f048f7dc63ea11837741365669809 Mon Sep 17 00:00:00 2001 From: Shyam N Date: Thu, 28 Sep 2017 00:58:06 -0700 Subject: [PATCH 03/16] Check for null before registering incremental analyzer in work coordinator. --- .../SolutionCrawler/SolutionCrawlerRegistrationService.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Features/Core/Portable/SolutionCrawler/SolutionCrawlerRegistrationService.cs b/src/Features/Core/Portable/SolutionCrawler/SolutionCrawlerRegistrationService.cs index 27a96aa2a9cdc..e5db7eb09697d 100644 --- a/src/Features/Core/Portable/SolutionCrawler/SolutionCrawlerRegistrationService.cs +++ b/src/Features/Core/Portable/SolutionCrawler/SolutionCrawlerRegistrationService.cs @@ -111,7 +111,10 @@ public void AddAnalyzerProvider(IIncrementalAnalyzerProvider provider, Increment } var analyzer = lazyProvider.Value.CreateIncrementalAnalyzer(workspace); - coordinator.AddAnalyzer(analyzer, metadata.HighPriorityForActiveFile); + if (analyzer != null) + { + coordinator.AddAnalyzer(analyzer, metadata.HighPriorityForActiveFile); + } } } } From b79d701b3613a703b729937bb50fcca9e1fadc25 Mon Sep 17 00:00:00 2001 From: Omar Tawfik Date: Thu, 28 Sep 2017 13:07:36 -0700 Subject: [PATCH 04/16] String rename --- .../Portable/Binder/Binder.ValueChecks.cs | 20 +- .../Portable/Binder/Binder_Statements.cs | 2 +- .../OverloadResolution/OverloadResolution.cs | 2 +- .../CSharp/Portable/Parser/LanguageParser.cs | 17 +- .../Attributes/AttributeTests_Embedded.cs | 20 +- .../Attributes/AttributeTests_IsByRefLike.cs | 12 +- .../AttributeTests_ReadOnlyStruct.cs | 12 +- .../Attributes/AttributeTests_RefReadOnly.cs | 304 +++++++++--------- .../CodeGen/CodeGenReadonlyStructTests.cs | 2 +- .../CodeGenRefConditionalOperatorTests.cs | 4 +- .../CodeGenRefReadOnlyParametersTests.cs | 184 +++++------ .../CodeGen/CodeGenRefReadonlyReturnTests.cs | 72 ++--- .../Emit/CodeGen/CodeGenRefReturnTests.cs | 2 +- .../Emit/CodeGen/CodeGenStructsAndEnum.cs | 16 +- .../Emit/Emit/InAttributeModifierTests.cs | 134 ++++---- .../IOperation/IOperationTests_IArgument.cs | 2 +- .../Semantics/AmbiguousOverrideTests.cs | 16 +- .../Test/Semantic/Semantics/NameOfTests.cs | 2 +- .../Semantics/OverloadResolutionTests.cs | 34 +- .../Semantic/Semantics/RefEscapingTests.cs | 26 +- .../Semantics/RefExtensionMethodsTests.cs | 104 +++--- .../Semantics/RefLocalsAndReturnsTests.cs | 20 +- .../Semantics/SpanStackSafetyTests.cs | 4 +- .../Test/Semantic/Semantics/UnsafeTests.cs | 2 +- .../Test/Semantic/Semantics/VarianceTests.cs | 8 +- .../SymbolDisplay/SymbolDisplayTests.cs | 34 +- ...InterfaceOverriddenOrHiddenMembersTests.cs | 48 +-- .../Symbols/OverriddenOrHiddenMembersTests.cs | 54 ++-- .../Symbol/Symbols/Source/DelegateTests.cs | 8 +- .../Source/ExpressionBodiedPropertyTests.cs | 4 +- .../Syntax/Parsing/ParserErrorMessageTests.cs | 138 ++++---- .../Test/Syntax/Parsing/RefReadonlyTests.cs | 48 ++- .../Core/Portable/PublicAPI.Unshipped.txt | 1 + .../SymbolDisplayParameterOptions.cs | 2 +- .../Core/Portable/Symbols/RefKind.cs | 19 +- .../ExtensionMethods/ExtensionMethodTests.vb | 2 +- .../Metadata/PE/InAttributeModifierTests.vb | 38 +-- .../EditAndContinue/StatementEditingTests.cs | 18 +- .../EditAndContinue/TopLevelEditingTests.cs | 98 +++--- .../ExtractInterface/ExtractInterfaceTests.cs | 8 +- .../ImplementAbstractClassTests.cs | 12 +- .../ImplementInterfaceTests.cs | 12 +- .../UseLocalFunction/UseLocalFunctionTests.cs | 8 +- .../InKeywordRecommenderTests.cs | 121 +++++++ .../ReadOnlyKeywordRecommenderTests.cs | 12 +- .../ExpressionCompilerTests.cs | 6 +- .../ChangeSignatureDialogViewModel.cs | 4 +- .../ChangeSignatureViewModelTests.vb | 6 +- 48 files changed, 933 insertions(+), 789 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs index de7070338d218..abe81619dd764 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs @@ -517,7 +517,7 @@ private bool CheckParameterValueKind(SyntaxNode node, BoundParameter parameter, ParameterSymbol parameterSymbol = parameter.ParameterSymbol; // all parameters can be passed by ref/out or assigned to - // except "ref readonly" parameters, which are readonly + // except "in" parameters, which are readonly if (parameterSymbol.RefKind == RefKind.RefReadOnly && RequiresAssignableVariable(valueKind)) { ReportReadOnlyError(parameterSymbol, node, valueKind, checkingReceiver, diagnostics); @@ -1009,10 +1009,10 @@ bool isRefEscape } } - // handle omitted optional "ref readonly" parameters if there are any + // handle omitted optional "in" parameters if there are any ParameterSymbol unmatchedRefReadOnlyParameter = TryGetUnmatchedRefReadOnlyParameterAndFreeMatchedArgs(parameters, ref refReadOnlyParametersMatchedWithArgs); - // unmatched "ref readonly" parameter is the same as a literal, its ref escape is scopeOfTheContainingExpression (can't get any worse) + // unmatched "in" parameter is the same as a literal, its ref escape is scopeOfTheContainingExpression (can't get any worse) // its val escape is ExternalScope (does not affect overal result) if (unmatchedRefReadOnlyParameter != null && isRefEscape) { @@ -1124,10 +1124,10 @@ bool isRefEscape } } - // handle omitted optional "ref readonly" parameters if there are any + // handle omitted optional "in" parameters if there are any ParameterSymbol unmatchedRefReadOnlyParameter = TryGetUnmatchedRefReadOnlyParameterAndFreeMatchedArgs(parameters, ref refReadOnlyParametersMatchedWithArgs); - // unmatched "ref readonly" parameter is the same as a literal, its ref escape is scopeOfTheContainingExpression (can't get any worse) + // unmatched "in" parameter is the same as a literal, its ref escape is scopeOfTheContainingExpression (can't get any worse) // its val escape is ExternalScope (does not affect overal result) if (unmatchedRefReadOnlyParameter != null && isRefEscape) { @@ -1261,7 +1261,7 @@ private static bool CheckInvocationArgMixing( } } - //NB: we do not care about unmatched "ref readonly" parameters here. + //NB: we do not care about unmatched "in" parameters here. // They have "outer" val escape, so cannot be worse than escapeTo. // check val escape of receiver if ref-like @@ -1276,8 +1276,8 @@ private static bool CheckInvocationArgMixing( /// /// Gets "effective" ref kind of an argument. /// Generally we know if a formal argument is passed as ref/out by looking at the call site. - /// However, to distinguish "ref readonly" and regular "val" parameters we need to take a look at corresponding parameter, if such exists. - /// NOTE: there are cases like params/vararg, when a corresponding parameter may not exist, then it cannot be a "ref readonly". + /// However, to distinguish "in" and regular "val" parameters we need to take a look at corresponding parameter, if such exists. + /// NOTE: there are cases like params/vararg, when a corresponding parameter may not exist, then it cannot be "in". /// private static RefKind GetEffectiveRefKind( int argIndex, @@ -1303,8 +1303,8 @@ private static RefKind GetEffectiveRefKind( } /// - /// Gets a "ref readonly" parameter for which there is no argument supplied, if such exists. - /// That indicates an optional "ref readonly" parameter. We treat it as an RValue passed by reference via a temporary. + /// Gets a "in" parameter for which there is no argument supplied, if such exists. + /// That indicates an optional "in" parameter. We treat it as an RValue passed by reference via a temporary. /// The effective scope of such variable is the immediately containing scope. /// private static ParameterSymbol TryGetUnmatchedRefReadOnlyParameterAndFreeMatchedArgs(ImmutableArray parameters, ref ArrayBuilder refReadOnlyParametersMatchedWithArgs) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs index 0504cc9d31cae..04d4daf196de6 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs @@ -1710,7 +1710,7 @@ internal void GenerateAnonymousFunctionConversionError(DiagnosticBag diagnostics // Parameter {0} is declared as type '{1}{2}' but should be '{3}{4}' Error(diagnostics, ErrorCode.ERR_BadParamType, lambdaParameterLocation, - i + 1, lambdaRefKind.ToPrefix(), distinguisher.First, delegateRefKind.ToPrefix(), distinguisher.Second); + i + 1, lambdaRefKind.ToParameterPrefix(), distinguisher.First, delegateRefKind.ToParameterPrefix(), distinguisher.Second); } else if (lambdaRefKind != delegateRefKind) { diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs index 6742c711fdd7c..a0ba5e2462970 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs @@ -2577,7 +2577,7 @@ private RefKind GetEffectiveParameterRefKind(ParameterSymbol parameter, RefKind if (paramRefKind == RefKind.RefReadOnly) { - // "ref readonly" parameters are effectively None for the purpose of overload resolution. + // "in" parameters are effectively None for the purpose of overload resolution. paramRefKind = RefKind.None; } diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index b4dd965e10933..43ea614b89189 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -3851,15 +3851,20 @@ private void ParseParameterModifiers(SyntaxListBuilder modifiers) { var nextKind = this.CurrentToken.Kind; - // "ref readonly" - if (nextKind == SyntaxKind.ReadOnlyKeyword) + // "ref this" + if (nextKind == SyntaxKind.ThisKeyword) { - modifier = CheckFeatureAvailability(modifier, MessageID.IDS_FeatureReadOnlyReferences); - nextKind = PeekToken(1).Kind; + modifier = CheckFeatureAvailability(modifier, MessageID.IDS_FeatureRefExtensionMethods); } + break; + } - // "ref this" - // "ref readonly this" + case SyntaxKind.InKeyword: + { + modifier = CheckFeatureAvailability(modifier, MessageID.IDS_FeatureReadOnlyReferences); + var nextKind = this.CurrentToken.Kind; + + // "in this" if (nextKind == SyntaxKind.ThisKeyword) { modifier = CheckFeatureAvailability(modifier, MessageID.IDS_FeatureRefExtensionMethods); diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Embedded.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Embedded.cs index 23576e5ceb8aa..2e589169275dd 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Embedded.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Embedded.cs @@ -198,7 +198,7 @@ public class EmbeddedAttribute : System.Attribute { } } class Test { - public void M(ref readonly int p) + public void M(in int p) { // This should trigger generating another EmbeddedAttribute } @@ -224,7 +224,7 @@ public class EmbeddedAttribute : System.Attribute { } var code = @" class Test { - public void M(ref readonly int p) + public void M(in int p) { // This should trigger generating another EmbeddedAttribute } @@ -248,7 +248,7 @@ public class EmbeddedAttribute : System.Attribute { } [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Microsoft.CodeAnalysis.EmbeddedAttribute))] class Test { - public void M(ref readonly int p) + public void M(in int p) { // This should trigger generating another EmbeddedAttribute } @@ -276,7 +276,7 @@ public class TestReference { } class Test { // This should trigger generating another EmbeddedAttribute - public void M(ref readonly int p) + public void M(in int p) { var obj = new OtherNamespace.TestReference(); // This should be fine } @@ -307,7 +307,7 @@ public class Void {} } public class Test { - public void M(ref readonly object x) { } // should trigger synthesizing IsReadOnly + public void M(in object x) { } // should trigger synthesizing IsReadOnly }"; CreateCompilation(code).VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319"), @@ -328,7 +328,7 @@ public class Void {} } public class Test { - public object M(ref readonly object x) { return x; } // should trigger synthesizing IsReadOnly + public object M(in object x) { return x; } // should trigger synthesizing IsReadOnly }"; CreateCompilation(code).VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319"), @@ -342,10 +342,10 @@ public class Test // public class Void {} Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "Void").WithArguments("System.Object").WithLocation(5, 18), // (9,34): error CS0518: Predefined type 'System.Object' is not defined or imported - // public object M(ref readonly object x) { return x; } // should trigger synthesizing IsReadOnly + // public object M(in object x) { return x; } // should trigger synthesizing IsReadOnly Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "object").WithArguments("System.Object").WithLocation(9, 34), // (9,12): error CS0518: Predefined type 'System.Object' is not defined or imported - // public object M(ref readonly object x) { return x; } // should trigger synthesizing IsReadOnly + // public object M(in object x) { return x; } // should trigger synthesizing IsReadOnly Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "object").WithArguments("System.Object").WithLocation(9, 12), // (5,18): error CS1729: 'object' does not contain a constructor that takes 0 arguments // public class Void {} @@ -369,7 +369,7 @@ public class Object {} } public class Test { - public object M(ref readonly object x) { return x; } // should trigger synthesizing IsReadOnly + public object M(in object x) { return x; } // should trigger synthesizing IsReadOnly }"; CreateCompilation(code).VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319"), @@ -400,7 +400,7 @@ public Attribute(object p) { } } public class Test { - public void M(ref readonly object x) { } // should trigger synthesizing IsReadOnly + public void M(in object x) { } // should trigger synthesizing IsReadOnly }"; CreateCompilation(code).VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319"), diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_IsByRefLike.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_IsByRefLike.cs index 38ad361032051..4c41cfb3c61c9 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_IsByRefLike.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_IsByRefLike.cs @@ -154,7 +154,7 @@ public class IsByRefLikeAttribute : System.Attribute { } using System.Runtime.CompilerServices; [IsByRefLike] -public delegate ref readonly int D([IsByRefLike]ref readonly int x); +public delegate ref readonly int D([IsByRefLike]in int x); "; CreateStandardCompilation(codeB, references: new[] { referenceA }).VerifyDiagnostics( @@ -162,7 +162,7 @@ public class IsByRefLikeAttribute : System.Attribute { } // [IsByRefLike] Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsByRefLike").WithArguments("System.Runtime.CompilerServices.IsByRefLikeAttribute").WithLocation(4, 2), // (5,37): error CS8335: Do not use 'System.Runtime.CompilerServices.IsByRefLikeAttribute'. This is reserved for compiler usage. - // public delegate ref readonly int D([IsByRefLike]ref readonly int x); + // public delegate ref readonly int D([IsByRefLike]in int x); Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsByRefLike").WithArguments("System.Runtime.CompilerServices.IsByRefLikeAttribute").WithLocation(5, 37)); } @@ -268,7 +268,7 @@ public class Test { [IsByRefLike] [return: IsByRefLike] - public ref readonly int Method([IsByRefLike]ref readonly int x) + public ref readonly int Method([IsByRefLike]in int x) { return ref x; } @@ -283,7 +283,7 @@ public ref readonly int Method([IsByRefLike]ref readonly int x) // [return: IsByRefLike] Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsByRefLike").WithArguments("System.Runtime.CompilerServices.IsByRefLikeAttribute").WithLocation(7, 14), // (8,37): error CS8335: Do not use 'System.Runtime.CompilerServices.IsByRefLikeAttribute'. This is reserved for compiler usage. - // public ref readonly int Method([IsByRefLike]ref readonly int x) + // public ref readonly int Method([IsByRefLike]in int x) Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsByRefLike").WithArguments("System.Runtime.CompilerServices.IsByRefLikeAttribute").WithLocation(8, 37)); } @@ -304,7 +304,7 @@ public class IsByRefLikeAttribute : System.Attribute { } public class Test { [IsByRefLike] - public ref readonly int this[[IsByRefLike]ref readonly int x] { get { return ref x; } } + public ref readonly int this[[IsByRefLike]in int x] { get { return ref x; } } } "; @@ -313,7 +313,7 @@ public class Test // [IsByRefLike] Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsByRefLike").WithArguments("System.Runtime.CompilerServices.IsByRefLikeAttribute").WithLocation(6, 6), // (7,35): error CS8335: Do not use 'System.Runtime.CompilerServices.IsByRefLikeAttribute'. This is reserved for compiler usage. - // public ref readonly int this[[IsByRefLike]ref readonly int x] { get { return ref x; } } + // public ref readonly int this[[IsByRefLike]in int x] { get { return ref x; } } Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsByRefLike").WithArguments("System.Runtime.CompilerServices.IsByRefLikeAttribute").WithLocation(7, 35)); } diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_ReadOnlyStruct.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_ReadOnlyStruct.cs index 15f7fb3a888f6..4fe23dd33f04f 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_ReadOnlyStruct.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_ReadOnlyStruct.cs @@ -155,7 +155,7 @@ public class IsReadOnlyAttribute : System.Attribute { } using System.Runtime.CompilerServices; [IsReadOnly] -public delegate ref readonly int D([IsReadOnly]ref readonly int x); +public delegate ref readonly int D([IsReadOnly]in int x); "; CreateStandardCompilation(codeB, references: new[] { referenceA }).VerifyDiagnostics( @@ -163,7 +163,7 @@ public class IsReadOnlyAttribute : System.Attribute { } // [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]ref readonly int x); + // public delegate ref readonly int D([IsReadOnly]in int x); Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(5, 37)); } @@ -269,7 +269,7 @@ public class Test { [IsReadOnly] [return: IsReadOnly] - public ref readonly int Method([IsReadOnly]ref readonly int x) + public ref readonly int Method([IsReadOnly]in int x) { return ref x; } @@ -284,7 +284,7 @@ public ref readonly int Method([IsReadOnly]ref readonly int x) // [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]ref readonly int x) + // public ref readonly int Method([IsReadOnly]in int x) Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(8, 37)); } @@ -305,7 +305,7 @@ public class IsReadOnlyAttribute : System.Attribute { } public class Test { [IsReadOnly] - public ref readonly int this[[IsReadOnly]ref readonly int x] { get { return ref x; } } + public ref readonly int this[[IsReadOnly]in int x] { get { return ref x; } } } "; @@ -314,7 +314,7 @@ public class Test // [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]ref readonly int x] { get { return ref x; } } + // 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)); } diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_RefReadOnly.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_RefReadOnly.cs index d8ad0ce78b3cb..d9e01b7f35f74 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_RefReadOnly.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_RefReadOnly.cs @@ -25,7 +25,7 @@ public class IsReadOnlyAttribute : System.Attribute { } } class Test { - public ref readonly int M(ref readonly int x) { return ref x; } + public ref readonly int M(in int x) { return ref x; } } "; @@ -49,7 +49,7 @@ public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Method_Parameter() var text = @" class Test { - public void M(ref readonly int x) { } + public void M(in int x) { } } "; @@ -97,7 +97,7 @@ public class IsReadOnlyAttribute : System.Attribute { } var codeB = @" class Test { - public ref readonly int M(ref readonly int x) { return ref x; } + public ref readonly int M(in int x) { return ref x; } } "; @@ -127,7 +127,7 @@ public class IsReadOnlyAttribute : System.Attribute { } } struct Test { - public static int operator +(ref readonly Test x, ref readonly Test y) { return 0; } + public static int operator +(in Test x, in Test y) { return 0; } } "; @@ -150,7 +150,7 @@ public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Operator_Parameter var text = @" struct Test { - public static int operator +(ref readonly Test x, ref readonly Test y) { return 0; } + public static int operator +(in Test x, in Test y) { return 0; } } "; @@ -180,7 +180,7 @@ public class IsReadOnlyAttribute : System.Attribute { } var codeB = @" struct Test { - public static int operator +(ref readonly Test x, ref readonly Test y) { return 0; } + public static int operator +(in Test x, in Test y) { return 0; } } "; @@ -209,7 +209,7 @@ public class IsReadOnlyAttribute : System.Attribute { } } class Test { - public Test(ref readonly int x) { } + public Test(in int x) { } } "; @@ -228,7 +228,7 @@ public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Constructor_Parame var text = @" class Test { - public Test(ref readonly int x) { } + public Test(in int x) { } } "; @@ -253,7 +253,7 @@ public class IsReadOnlyAttribute : System.Attribute { } var codeB = @" class Test { - public Test(ref readonly int x) { } + public Test(in int x) { } } "; @@ -380,7 +380,7 @@ public class IsReadOnlyAttribute : System.Attribute { } } class Test { - public ref readonly int this[ref readonly int x] { get { return ref x; } } + public ref readonly int this[in int x] { get { return ref x; } } } "; @@ -404,7 +404,7 @@ public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Indexer_Parameter( var text = @" class Test { - public int this[ref readonly int x] { get { return x; } } + public int this[in int x] { get { return x; } } } "; @@ -452,7 +452,7 @@ public class IsReadOnlyAttribute : System.Attribute { } var codeB = @" class Test { - public ref readonly int this[ref readonly int x] { get { return ref x; } } + public ref readonly int this[in int x] { get { return ref x; } } } "; @@ -480,7 +480,7 @@ namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } } -public delegate ref readonly int D(ref readonly int x); +public delegate in int D(in int x); "; CompileAndVerify(text, symbolValidator: module => @@ -501,7 +501,7 @@ public class IsReadOnlyAttribute : System.Attribute { } public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Delegate_Parameter() { var text = @" -public delegate void D(ref readonly int x); +public delegate void D(in int x); "; CompileAndVerify(text, symbolValidator: module => @@ -517,7 +517,7 @@ public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Delegate_Parameter public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Delegate_ReturnType() { var text = @" -public delegate ref readonly int D(); +public delegate in int D(); "; CompileAndVerify(text, symbolValidator: module => @@ -542,7 +542,7 @@ public class IsReadOnlyAttribute : System.Attribute { } var referenceA = CreateStandardCompilation(codeA).VerifyDiagnostics().ToMetadataReference(); var codeB = @" -public delegate ref readonly int D(ref readonly int x); +public delegate ref readonly int D(in int x); "; CompileAndVerify(codeB, additionalRefs: new[] { referenceA }, symbolValidator: module => @@ -573,7 +573,7 @@ public class Test { public void M() { - ref readonly int Inner(ref readonly int x) + ref readonly int Inner(in int x) { return ref x; } @@ -604,7 +604,7 @@ public class Test { public void M() { - void Inner(ref readonly int x) { } + void Inner(in int x) { } } } "; @@ -663,7 +663,7 @@ public class Test { public void M() { - ref readonly int Inner(ref readonly int x) + ref readonly int Inner(in int x) { return ref x; } @@ -696,13 +696,13 @@ namespace System.Runtime.CompilerServices public class IsReadOnlyAttribute : System.Attribute { } } -delegate ref readonly int D(ref readonly int x); +delegate ref readonly int D(in int x); class Test { public void M1() { - M2((ref readonly int x) => ref x); + M2((in int x) => ref x); } public void M2(D value) { } @@ -728,13 +728,13 @@ public void M2(D value) { } public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Lambda_Parameter() { var text = @" -delegate void D(ref readonly int x); +delegate void D(in int x); class Test { public void M1() { - M2((ref readonly int x) => {}); + M2((in int x) => {}); } public void M2(D value) { } @@ -792,13 +792,13 @@ public class IsReadOnlyAttribute : System.Attribute { } var referenceA = CreateStandardCompilation(codeA).VerifyDiagnostics().ToMetadataReference(); var codeB = @" -delegate ref readonly int D(ref readonly int x); +delegate ref readonly int D(in int x); class Test { public void M1() { - M2((ref readonly int x) => ref x); + M2((in int x) => ref x); } public void M2(D value) { } @@ -837,7 +837,7 @@ public class IsReadOnlyAttribute : System.Attribute { } using System.Runtime.CompilerServices; [IsReadOnly] -public delegate ref readonly int D([IsReadOnly]ref readonly int x); +public delegate ref readonly int D([IsReadOnly]in int x); "; CreateStandardCompilation(codeB, references: new[] { referenceA }).VerifyDiagnostics( @@ -845,7 +845,7 @@ public class IsReadOnlyAttribute : System.Attribute { } // [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]ref readonly int x); + // public delegate ref readonly int D([IsReadOnly]in int x); Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(5, 37)); } @@ -951,7 +951,7 @@ public class Test { [IsReadOnly] [return: IsReadOnly] - public ref readonly int Method([IsReadOnly]ref readonly int x) + public ref readonly int Method([IsReadOnly]in int x) { return ref x; } @@ -966,7 +966,7 @@ public ref readonly int Method([IsReadOnly]ref readonly int x) // [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]ref readonly int x) + // public ref readonly int Method([IsReadOnly]in int x) Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "IsReadOnly").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(8, 37)); } @@ -987,7 +987,7 @@ public class IsReadOnlyAttribute : System.Attribute { } public class Test { [IsReadOnly] - public ref readonly int this[[IsReadOnly]ref readonly int x] { get { return ref x; } } + public ref readonly int this[[IsReadOnly]in int x] { get { return ref x; } } } "; @@ -996,7 +996,7 @@ public class Test // [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]ref readonly int x] { get { return ref x; } } + // 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)); } @@ -1007,7 +1007,7 @@ public void UserReferencingEmbeddedAttributeShouldResultInAnError() [Embedded] public class Test { - public ref readonly int M(ref readonly int p) => ref p; + public ref readonly int M(in int p) => ref p; }"; CreateStandardCompilation(code).VerifyDiagnostics( @@ -1026,7 +1026,7 @@ public void UserReferencingIsReadOnlyAttributeShouldResultInAnError() [IsReadOnly] public class Test { - public ref readonly int M(ref readonly int p) => ref p; + public ref readonly int M(in int p) => ref p; }"; CreateStandardCompilation(code).VerifyDiagnostics( @@ -1052,7 +1052,7 @@ public class IsReadOnlyAttribute : System.Attribute { } var code2 = CreateStandardCompilation(@" public class Test1 { - public static ref readonly int M(ref readonly int p) => ref p; + public static ref readonly int M(in int p) => ref p; }", references: new[] { code1.ToMetadataReference() }, options: options); CompileAndVerify(code2, verify: false, symbolValidator: module => @@ -1065,7 +1065,7 @@ public class Test1 var code3 = CreateStandardCompilation(@" public class Test2 { - public static ref readonly int M(ref readonly int p) => ref Test1.M(p); + public static ref readonly int M(in int p) => ref Test1.M(p); }", references: new[] { code2.ToMetadataReference() }, options: options); CompileAndVerify(code3, symbolValidator: module => @@ -1082,13 +1082,13 @@ public void BuildingAModuleRequiresIsReadOnlyAttributeToBeThere_Missing_SourceMe var code = @" public class Test { - public void M(ref readonly int x) { } + public void M(in int x) { } }"; CreateStandardCompilation(code, options: TestOptions.ReleaseModule).VerifyDiagnostics( // (4,19): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsReadOnlyAttribute' is not defined or imported - // public void M(ref readonly int x) { } - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(4, 19)); + // public void M(in int x) { } + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(4, 19)); } [Fact] @@ -1097,17 +1097,17 @@ public void BuildingAModuleRequiresIsReadOnlyAttributeToBeThere_Missing_SourceMe var code = @" public class Test { - public void M1(ref readonly int x) { } - public void M2(ref readonly int x) { } + public void M1(in int x) { } + public void M2(in int x) { } }"; CreateStandardCompilation(code, options: TestOptions.ReleaseModule).VerifyDiagnostics( // (4,20): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsReadOnlyAttribute' is not defined or imported - // public void M1(ref readonly int x) { } - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(4, 20), + // 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(ref readonly int x) { } - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(5, 20)); + // public void M2(in int x) { } + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(5, 20)); } [Fact] @@ -1118,7 +1118,7 @@ public class Test { public void Parent() { - void child(ref readonly int p) { } + void child(in int p) { } int x = 0; child(x); @@ -1127,8 +1127,8 @@ void child(ref readonly int p) { } CreateStandardCompilation(code, options: TestOptions.ReleaseModule).VerifyDiagnostics( // (6,20): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsReadOnlyAttribute' is not defined or imported - // void child(ref readonly int p) { } - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly int p").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(6, 20)); + // void child(in int p) { } + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "in int p").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(6, 20)); } [Fact] @@ -1143,7 +1143,7 @@ public class IsReadOnlyAttribute : System.Attribute { } var code = @" public class Test { - public void M(ref readonly int x) { } + public void M(in int x) { } }"; CompileAndVerify(code, verify: false, additionalRefs: new[] { reference }, options: TestOptions.ReleaseModule, symbolValidator: module => @@ -1165,7 +1165,7 @@ public void ReferencingAnEmbeddedIsReadOnlyAttributeDoesNotUseIt_InternalsVisibl [assembly:System.Runtime.CompilerServices.InternalsVisibleToAttribute(""Assembly2"")] public class Test1 { - public static ref readonly int M(ref readonly int p) => ref p; + public static ref readonly int M(in int p) => ref p; }"; var comp1 = CompileAndVerify(code1, options: options, verify: false, symbolValidator: module => @@ -1177,7 +1177,7 @@ public class Test1 var code2 = @" public class Test2 { - public static ref readonly int M(ref readonly int p) => ref Test1.M(p); + public static ref readonly int M(in int p) => ref Test1.M(p); }"; CompileAndVerify(code2, options: options.WithModuleName("Assembly2"), additionalRefs: new[] { comp1.Compilation.ToMetadataReference() }, symbolValidator: module => @@ -1197,7 +1197,7 @@ public class IsReadOnlyAttribute : System.Attribute { } } class Test { - public ref readonly int M(ref readonly int x) { return ref x; } + public ref readonly int M(in int x) { return ref x; } } "; @@ -1220,13 +1220,13 @@ public IsReadOnlyAttribute(int p) { } } class Test { - public void M(ref readonly int x) { } + public void M(in int x) { } }"; CreateStandardCompilation(text, options: TestOptions.ReleaseModule).VerifyDiagnostics( // (11,19): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' - // public void M(ref readonly int x) { } - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 19)); + // public void M(in int x) { } + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 19)); } [Fact] @@ -1242,13 +1242,13 @@ public IsReadOnlyAttribute(int p) { } } class Test { - public void M(ref readonly int x) { } + public void M(in int x) { } }"; CreateStandardCompilation(text).VerifyEmitDiagnostics( // (11,19): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' - // public void M(ref readonly int x) { } - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 19)); + // public void M(in int x) { } + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 19)); } [Fact] @@ -1264,13 +1264,13 @@ private IsReadOnlyAttribute() { } } class Test { - public void M(ref readonly int x) { } + public void M(in int x) { } }"; CreateStandardCompilation(text).VerifyEmitDiagnostics( // (11,19): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' - // public void M(ref readonly int x) { } - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 19)); + // public void M(in int x) { } + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 19)); } [Fact] @@ -1286,7 +1286,7 @@ public void IsReadOnlyAttributesAreNotPortedInNoPia() public interface Test { ref readonly int Property { get; } - ref readonly int Method(ref readonly int x); + ref readonly int Method(in int x); }"); CompileAndVerify(comAssembly, symbolValidator: module => @@ -1349,7 +1349,7 @@ void symbolValidator(ModuleSymbol module) public void TryingToBindFromSemanticModelDoesNotPolluteCompilation_Lambdas_Parameters() { var reference = CreateStandardCompilation(@" -public delegate int D (ref readonly int x); +public delegate int D (in int x); ").VerifyEmitDiagnostics(); Assert.True(reference.NeedsGeneratedIsReadOnlyAttribute); @@ -1372,7 +1372,7 @@ void User() var userFunction = tree.GetRoot().DescendantNodes().OfType().Single(method => method.Identifier.Text == "User"); var position = userFunction.Body.CloseBraceToken.Position; - var newInvocation = SyntaxFactory.ParseExpression("Process((ref readonly int x) => x)"); + var newInvocation = SyntaxFactory.ParseExpression("Process((in int x) => x)"); var result = model.GetSpeculativeSymbolInfo(position, newInvocation, SpeculativeBindingOption.BindAsExpression); Assert.NotNull(result.Symbol); @@ -1443,7 +1443,7 @@ void User() var userFunction = tree.GetRoot().DescendantNodes().OfType().Single(method => method.Identifier.Text == "User"); var position = userFunction.Body.CloseBraceToken.Position; - var localfunction = SyntaxFactory.ParseStatement("int localFunction(ref readonly int x) { return x; }"); + 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); @@ -1509,7 +1509,7 @@ void User() public void RefReadOnlyErrorsForLambdasDoNotPolluteCompilationDeclarationsDiagnostics() { var reference = CreateStandardCompilation(@" -public delegate int D (ref readonly int x); +public delegate int D (in int x); ").EmitToImageReference(); var code = @" @@ -1519,7 +1519,7 @@ public void Process(D lambda) { } void User() { - Process((ref readonly int p) => p); + Process((in int p) => p); } }"; @@ -1529,8 +1529,8 @@ void User() compilation.VerifyDiagnostics( // (8,18): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsReadOnlyAttribute' is not defined or imported - // Process((ref readonly int p) => p); - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly int p").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(8, 18)); + // Process((in int p) => p); + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "in int p").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(8, 18)); } [Fact] @@ -1542,7 +1542,7 @@ public class Test private int x = 0; void User() { - void local(ref readonly int x) { } + void local(in int x) { } local(x); } }"; @@ -1553,8 +1553,8 @@ void local(ref readonly int x) { } compilation.VerifyDiagnostics( // (7,20): error CS0518: Predefined type 'System.Runtime.CompilerServices.IsReadOnlyAttribute' is not defined or imported - // void local(ref readonly int x) { } - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(7, 20)); + // void local(in int x) { } + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute").WithLocation(7, 20)); } [Fact] @@ -1567,13 +1567,13 @@ public class IsReadOnlyAttribute { private int value; - public ref readonly int Method(ref readonly int x) => ref value; + public ref readonly int Method(in int x) => ref value; - public static int operator +(ref readonly IsReadOnlyAttribute x, ref readonly IsReadOnlyAttribute y) => 0; + public static int operator +(in IsReadOnlyAttribute x, in IsReadOnlyAttribute y) => 0; public ref readonly int Property => ref value; - public ref readonly int this[ref readonly int x] => ref value; + public ref readonly int this[in int x] => ref value; } }"; @@ -1609,13 +1609,13 @@ public class IsReadOnlyAttribute : System.Attribute { private int value; - public ref readonly int Method(ref readonly int x) => ref value; + public ref readonly int Method(in int x) => ref value; - public static int operator +(ref readonly IsReadOnlyAttribute x, ref readonly IsReadOnlyAttribute y) => 0; + public static int operator +(in IsReadOnlyAttribute x, in IsReadOnlyAttribute y) => 0; public ref readonly int Property => ref value; - public ref readonly int this[ref readonly int x] => ref value; + public ref readonly int this[in int x] => ref value; } }"; @@ -1655,13 +1655,13 @@ public class Child : System.Runtime.CompilerServices.IsReadOnlyAttribute { private int value; - public ref readonly int Method(ref readonly int x) => ref value; + public ref readonly int Method(in int x) => ref value; - public static int operator +(ref readonly Child x, ref readonly Child y) => 0; + public static int operator +(in Child x, in Child y) => 0; public ref readonly int Property => ref value; - public ref readonly int this[ref readonly int x] => ref value; + public ref readonly int this[in int x] => ref value; }"; CompileAndVerify(code, verify: false, symbolValidator: module => @@ -1695,22 +1695,22 @@ public abstract class IsReadOnlyAttribute : System.Attribute { public IsReadOnlyAttribute() { } - public abstract ref readonly int Method(ref readonly int x); + public abstract ref readonly int Method(in int x); public abstract ref readonly int Property { get; } - public abstract ref readonly int this[ref readonly int x] { 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(ref readonly int x) => ref 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[ref readonly int x] => ref value; + public override ref readonly int this[in int x] => ref value; }"; CompileAndVerify(code, verify: false, symbolValidator: module => @@ -1740,11 +1740,11 @@ public abstract class IsReadOnlyAttribute : System.Attribute { public IsReadOnlyAttribute() { } - public abstract ref readonly int Method(ref readonly int x); + public abstract ref readonly int Method(in int x); public abstract ref readonly int Property { get; } - public abstract ref readonly int this[ref readonly int x] { get; } + public abstract ref readonly int this[in int x] { get; } } }", assemblyName: "testRef").ToMetadataReference(); @@ -1753,11 +1753,11 @@ public class Child : System.Runtime.CompilerServices.IsReadOnlyAttribute { private int value; - public override ref readonly int Method(ref readonly int x) => ref 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[ref readonly int x] => ref value; + public override ref readonly int this[in int x] => ref value; }"; CompileAndVerify(code, verify: false, additionalRefs: new[] { reference }, symbolValidator: module => @@ -1785,21 +1785,21 @@ namespace System.Runtime.CompilerServices { public abstract class Parent : System.Attribute { - public abstract ref readonly int Method(ref readonly int x); + public abstract ref readonly int Method(in int x); public abstract ref readonly int Property { get; } - public abstract ref readonly int this[ref readonly int x] { get; } + public abstract ref readonly int this[in int x] { get; } } public class IsReadOnlyAttribute : Parent { private int value; - public override ref readonly int Method(ref readonly int x) => ref 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[ref readonly int x] => ref value; + public override ref readonly int this[in int x] => ref value; } }"; @@ -1829,11 +1829,11 @@ namespace System.Runtime.CompilerServices { public abstract class Parent : System.Attribute { - public abstract ref readonly int Method(ref readonly int x); + public abstract ref readonly int Method(in int x); public abstract ref readonly int Property { get; } - public abstract ref readonly int this[ref readonly int x] { get; } + public abstract ref readonly int this[in int x] { get; } } }").ToMetadataReference(); @@ -1844,11 +1844,11 @@ public class IsReadOnlyAttribute : Parent { private int value; - public override ref readonly int Method(ref readonly int x) => ref 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[ref readonly int x] => ref value; + public override ref readonly int this[in int x] => ref value; } }"; @@ -1882,13 +1882,13 @@ public class IsReadOnlyAttribute : TestParent { private int value; - public ref readonly int Method(ref readonly int x) => ref value; + public ref readonly int Method(in int x) => ref value; - public static int operator +(ref readonly IsReadOnlyAttribute x, ref readonly IsReadOnlyAttribute y) => 0; + public static int operator +(in IsReadOnlyAttribute x, in IsReadOnlyAttribute y) => 0; public ref readonly int Property => ref value; - public ref readonly int this[ref readonly int x] => ref value; + public ref readonly int this[in int x] => ref value; } }"; @@ -1922,16 +1922,16 @@ namespace System.Runtime.CompilerServices { public interface IsReadOnlyAttribute { - ref readonly int Method(ref readonly int x); + ref readonly int Method(in int x); } }"; CreateStandardCompilation(code).VerifyEmitDiagnostics( // (6,9): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' - // ref readonly int Method(ref readonly int x); + // 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(ref readonly int x); + // ref readonly int Method(in int x); Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(6, 33)); } @@ -1943,21 +1943,21 @@ namespace System.Runtime.CompilerServices { public interface ITest { - ref readonly int Method(ref readonly int x); + ref readonly int Method(in int x); ref readonly int Property { get; } - ref readonly int this[ref readonly int x] { get; } + ref readonly int this[in int x] { get; } } public class IsReadOnlyAttribute : ITest { private int value; - ref readonly int ITest.Method(ref readonly int x) => ref value; + ref readonly int ITest.Method(in int x) => ref value; ref readonly int ITest.Property => ref value; - ref readonly int ITest.this[ref readonly int x] => ref value; + ref readonly int ITest.this[in int x] => ref value; } }"; @@ -1987,11 +1987,11 @@ namespace System.Runtime.CompilerServices { public interface ITest { - ref readonly int Method(ref readonly int x); + ref readonly int Method(in int x); ref readonly int Property { get; } - ref readonly int this[ref readonly int x] { get; } + ref readonly int this[in int x] { get; } } }").ToMetadataReference(); @@ -2002,11 +2002,11 @@ public class IsReadOnlyAttribute : ITest { private int value; - ref readonly int ITest.Method(ref readonly int x) => ref value; + ref readonly int ITest.Method(in int x) => ref value; ref readonly int ITest.Property => ref value; - ref readonly int ITest.this[ref readonly int x] => ref value; + ref readonly int ITest.this[in int x] => ref value; } }"; @@ -2034,21 +2034,21 @@ public void IsReadOnlyAttributeIsGenerated_ExplicitInterfaceImplementation_SameA var code = @" public interface ITest { - ref readonly int Method(ref readonly int x); + ref readonly int Method(in int x); ref readonly int Property { get; } - ref readonly int this[ref readonly int x] { get; } + ref readonly int this[in int x] { get; } } public class TestImpl : ITest { private int value; - ref readonly int ITest.Method(ref readonly int x) => ref value; + ref readonly int ITest.Method(in int x) => ref value; ref readonly int ITest.Property => ref value; - ref readonly int ITest.this[ref readonly int x] => ref value; + ref readonly int ITest.this[in int x] => ref value; }"; CompileAndVerify(code, verify: false, symbolValidator: module => @@ -2074,11 +2074,11 @@ public void IsReadOnlyAttributeIsGenerated_ExplicitInterfaceImplementation_Exter var reference = CreateStandardCompilation(@" public interface ITest { - ref readonly int Method(ref readonly int x); + ref readonly int Method(in int x); ref readonly int Property { get; } - ref readonly int this[ref readonly int x] { get; } + ref readonly int this[in int x] { get; } }").ToMetadataReference(); var code = @" @@ -2086,11 +2086,11 @@ public class TestImpl : ITest { private int value; - ref readonly int ITest.Method(ref readonly int x) => ref value; + ref readonly int ITest.Method(in int x) => ref value; ref readonly int ITest.Property => ref value; - ref readonly int ITest.this[ref readonly int x] => ref value; + ref readonly int ITest.this[in int x] => ref value; }"; CompileAndVerify(code, verify: false, additionalRefs: new[] { reference }, symbolValidator: module => @@ -2116,16 +2116,16 @@ public void RefReadOnlyDefinitionsInsideUserDefinedIsReadOnlyAttribute_Delegate( var code = @" namespace System.Runtime.CompilerServices { - public delegate ref readonly int IsReadOnlyAttribute(ref readonly int x); + public delegate in int IsReadOnlyAttribute(in int x); }"; CreateStandardCompilation(code).VerifyEmitDiagnostics( // (4,21): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' - // public delegate ref readonly int IsReadOnlyAttribute(ref readonly int x); - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(4, 21), + // public delegate in int IsReadOnlyAttribute(in int x); + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in 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(ref readonly int x); - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(4, 58)); + // public delegate in int IsReadOnlyAttribute(in int x); + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(4, 58)); } [Fact] @@ -2141,13 +2141,13 @@ public IsReadOnlyAttribute(int p) { } } public class Test { - public Test(ref readonly int x) { } + public Test(in int x) { } }"; CreateStandardCompilation(text).VerifyEmitDiagnostics( // (11,17): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' - // public Test(ref readonly int x) { } - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 17)); + // public Test(in int x) { } + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 17)); } [Fact] @@ -2163,16 +2163,16 @@ public IsReadOnlyAttribute(int p) { } } public class Test { - public ref readonly int Method(ref readonly int x) => ref x; + public ref readonly int Method(in int x) => ref x; }"; CreateStandardCompilation(text).VerifyEmitDiagnostics( // (11,12): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' - // public ref readonly int Method(ref readonly int x) => ref x; - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 12), + // public ref readonly int Method(in int x) => ref x; + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in 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(ref readonly int x) => ref x; - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 36)); + // 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] @@ -2192,7 +2192,7 @@ public void M() { int x = 0; - ref readonly int local(ref readonly int p) + ref readonly int local(in int p) { return ref p; } @@ -2203,18 +2203,18 @@ ref readonly int local(ref readonly int p) CreateStandardCompilation(text).VerifyEmitDiagnostics( // (15,9): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' - // ref readonly int local(ref readonly int p) - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(15, 9), + // ref readonly int local(in int p) + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in 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(ref readonly int p) - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int p").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(15, 32)); + // 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 = CreateStandardCompilation(@" -public delegate ref readonly int D(ref readonly int x); +public delegate in int D(in int x); ").EmitToImageReference(); var text = @" @@ -2230,7 +2230,7 @@ class Test { public void M1() { - M2((ref readonly int x) => ref x); + M2((in int x) => ref x); } public void M2(D value) { } @@ -2238,11 +2238,11 @@ public void M2(D value) { } CreateStandardCompilation(text, references: new[] { reference }).VerifyEmitDiagnostics( // (14,33): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' - // M2((ref readonly int x) => ref x); + // M2((in int x) => ref x); Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "=>").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(14, 33), // (14,13): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' - // M2((ref readonly int x) => ref x); - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(14, 13)); + // M2((in int x) => ref x); + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(14, 13)); } [Fact] @@ -2265,7 +2265,7 @@ public class Test CreateStandardCompilation(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)); + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(12, 12)); } [Fact] @@ -2282,16 +2282,16 @@ public IsReadOnlyAttribute(int p) { } public class Test { - public ref readonly int this[ref readonly int x] => ref x; + public ref readonly int this[in int x] => ref x; }"; CreateStandardCompilation(text).VerifyEmitDiagnostics( // (12,12): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' - // public ref readonly int this[ref readonly int x] => ref x; - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(12, 12), + // public ref readonly int this[in int x] => ref x; + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in 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[ref readonly int x] => ref x; - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(12, 34)); + // 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] @@ -2307,16 +2307,16 @@ public IsReadOnlyAttribute(int p) { } } public class Test { - public static int operator + (ref readonly Test x, ref readonly Test y) => 0; + public static int operator + (in Test x, in Test y) => 0; }"; CreateStandardCompilation(text).VerifyEmitDiagnostics( // (11,35): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' - // public static int operator + (ref readonly Test x, ref readonly Test y) => 0; - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly Test x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 35), + // 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,56): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' - // public static int operator + (ref readonly Test x, ref readonly Test y) => 0; - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly Test y").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 56)); + // 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, 56)); } private void AssertReferencedIsReadOnlyAttribute(Accessibility accessibility, ImmutableArray attributes, string assemblyName) diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenReadonlyStructTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenReadonlyStructTests.cs index 0984edfab3ad9..e98a12aeccc62 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenReadonlyStructTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenReadonlyStructTests.cs @@ -387,7 +387,7 @@ static void Main() { Test(default(S1)); } - static void Test(ref readonly S1 arg) + static void Test(in S1 arg) { System.Console.Write(arg.M1()); System.Console.Write(arg.ToString()); diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefConditionalOperatorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefConditionalOperatorTests.cs index aad20e5c6d6e1..f475bd8cf8a34 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefConditionalOperatorTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefConditionalOperatorTests.cs @@ -1018,7 +1018,7 @@ public override string ToString() public static class S1Ext { - public static void RoExtension(ref readonly this S1 self) + public static void RoExtension(in this S1 self) { // do nothing } @@ -1062,7 +1062,7 @@ .locals init (C1 V_0, //o IL_0045: br.s IL_004d IL_0047: ldloc.0 IL_0048: ldflda ""S1 C1.field"" - IL_004d: call ""void S1Ext.RoExtension(ref readonly S1)"" + IL_004d: call ""void S1Ext.RoExtension(in S1)"" IL_0052: ldloc.0 IL_0053: ldflda ""S1 C1.field"" IL_0058: ldfld ""int S1.value"" diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs index c1033b9540c12..300b653511769 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs @@ -21,7 +21,7 @@ public void RefReturnParamAccess() var text = @" class Program { - static ref readonly int M(ref readonly int x) + static ref readonly int M(in int x) { return ref x; } @@ -30,7 +30,7 @@ static ref readonly int M(ref readonly int x) var comp = CompileAndVerify(text, parseOptions: TestOptions.Regular, verify: false); - comp.VerifyIL("Program.M(ref readonly int)", @" + comp.VerifyIL("Program.M(in int)", @" { // Code size 2 (0x2) .maxstack 1 @@ -58,7 +58,7 @@ public static void Main() System.Console.WriteLine(s1.X); } - static ref readonly int M(ref readonly int x) + static ref readonly int M(in int x) { return ref x; } @@ -68,7 +68,7 @@ struct S1 { public int X; - public static S1 operator +(ref readonly S1 x, ref readonly S1 y) + public static S1 operator +(in S1 x, in S1 y) { return new S1(){X = x.X + y.X}; } @@ -88,7 +88,7 @@ .locals init (int V_0, //local IL_0000: ldc.i4.s 42 IL_0002: stloc.0 IL_0003: ldloca.s V_0 - IL_0005: call ""ref readonly int Program.M(ref readonly int)"" + IL_0005: call ""ref readonly int Program.M(in int)"" IL_000a: ldind.i4 IL_000b: call ""void System.Console.WriteLine(int)"" IL_0010: ldloca.s V_1 @@ -98,7 +98,7 @@ .locals init (int V_0, //local IL_001c: stfld ""int Program.S1.X"" IL_0021: ldloca.s V_1 IL_0023: ldloca.s V_1 - IL_0025: call ""Program.S1 Program.S1.op_Addition(ref readonly Program.S1, ref readonly Program.S1)"" + IL_0025: call ""Program.S1 Program.S1.op_Addition(in Program.S1, in Program.S1)"" IL_002a: stloc.1 IL_002b: ldloc.1 IL_002c: ldfld ""int Program.S1.X"" @@ -121,12 +121,12 @@ public static void Main() System.Console.WriteLine(M(42)); } - static ref readonly int M(ref readonly int x) + static ref readonly int M(in int x) { return ref x; } - int this[ref readonly int x, ref readonly int y] => x + y; + int this[in int x, in int y] => x + y; } "; @@ -144,7 +144,7 @@ .locals init (int V_0, IL_0000: ldc.i4.s 42 IL_0002: stloc.0 IL_0003: ldloca.s V_0 - IL_0005: call ""ref readonly int Program.M(ref readonly int)"" + IL_0005: call ""ref readonly int Program.M(in int)"" IL_000a: ldind.i4 IL_000b: call ""void System.Console.WriteLine(int)"" IL_0010: newobj ""Program..ctor()"" @@ -154,18 +154,18 @@ .locals init (int V_0, IL_0019: ldc.i4.6 IL_001a: stloc.1 IL_001b: ldloca.s V_1 - IL_001d: call ""int Program.this[ref readonly int, ref readonly int].get"" + IL_001d: call ""int Program.this[in int, in int].get"" IL_0022: call ""void System.Console.WriteLine(int)"" IL_0027: ldc.i4.s 42 IL_0029: stloc.0 IL_002a: ldloca.s V_0 - IL_002c: call ""ref readonly int Program.M(ref readonly int)"" + IL_002c: call ""ref readonly int Program.M(in int)"" IL_0031: ldind.i4 IL_0032: call ""void System.Console.WriteLine(int)"" IL_0037: ldc.i4.s 42 IL_0039: stloc.0 IL_003a: ldloca.s V_0 - IL_003c: call ""ref readonly int Program.M(ref readonly int)"" + IL_003c: call ""ref readonly int Program.M(in int)"" IL_0041: ldind.i4 IL_0042: call ""void System.Console.WriteLine(int)"" IL_0047: ret @@ -186,7 +186,7 @@ public static void Main() System.Console.WriteLine(M(F)); } - static ref readonly int M(ref readonly int x) + static ref readonly int M(in int x) { return ref x; } @@ -200,14 +200,14 @@ static ref readonly int M(ref readonly int x) // Code size 17 (0x11) .maxstack 1 IL_0000: ldsflda ""int Program.F"" - IL_0005: call ""ref readonly int Program.M(ref readonly int)"" + IL_0005: call ""ref readonly int Program.M(in int)"" IL_000a: ldind.i4 IL_000b: call ""void System.Console.WriteLine(int)"" IL_0010: ret }"); - comp.VerifyIL("Program.M(ref readonly int)", @" + comp.VerifyIL("Program.M(in int)", @" { // Code size 2 (0x2) .maxstack 1 @@ -225,7 +225,7 @@ .locals init (int V_0) IL_0000: ldsfld ""int Program.F"" IL_0005: stloc.0 IL_0006: ldloca.s V_0 - IL_0008: call ""ref readonly int Program.M(ref readonly int)"" + IL_0008: call ""ref readonly int Program.M(in int)"" IL_000d: ldind.i4 IL_000e: call ""void System.Console.WriteLine(int)"" IL_0013: ret @@ -246,12 +246,12 @@ public static void Main() System.Console.WriteLine(M(F)); } - static ref readonly int M(ref readonly int x) + static ref readonly int M(in int x) { return ref M1(x); } - static ref readonly int M1(ref readonly int x) + static ref readonly int M1(in int x) { return ref x; } @@ -260,12 +260,12 @@ static ref readonly int M1(ref readonly int x) var comp = CompileAndVerify(text, parseOptions: TestOptions.Regular, verify: false, expectedOutput: "42"); - comp.VerifyIL("Program.M(ref readonly int)", @" + comp.VerifyIL("Program.M(in int)", @" { // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 - IL_0001: call ""ref readonly int Program.M1(ref readonly int)"" + IL_0001: call ""ref readonly int Program.M1(in int)"" IL_0006: ret }"); } @@ -292,7 +292,7 @@ public Program(ref readonly string x) SI = x; } - public virtual ref readonly int M(ref readonly int x) + public virtual ref readonly int M(in int x) { return ref x; } @@ -302,7 +302,7 @@ class P1 : Program { public P1(ref readonly string x) : base(x){} - public override ref readonly int M(ref readonly int x) + public override ref readonly int M(in int x) { return ref base.M(x); } @@ -312,23 +312,23 @@ public override ref readonly int M(ref readonly int x) var comp = CompileAndVerify(text, parseOptions: TestOptions.Regular, verify: false, expectedOutput: @"hi 42"); - comp.VerifyIL("P1..ctor(ref readonly string)", @" + comp.VerifyIL("P1..ctor(in string)", @" { // Code size 8 (0x8) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: call ""Program..ctor(ref readonly string)"" + IL_0002: call ""Program..ctor(in string)"" IL_0007: ret }"); - comp.VerifyIL("P1.M(ref readonly int)", @" + comp.VerifyIL("P1.M(in int)", @" { // Code size 8 (0x8) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldarg.1 - IL_0002: call ""ref readonly int Program.M(ref readonly int)"" + IL_0002: call ""ref readonly int Program.M(in int)"" IL_0007: ret }"); } @@ -339,7 +339,7 @@ public void RefReturnParamAccess1() var text = @" class Program { - static ref readonly int M(ref readonly int x) + static ref readonly int M(in int x) { return ref x; } @@ -348,7 +348,7 @@ static ref readonly int M(ref readonly int x) var comp = CompileAndVerify(text, parseOptions: TestOptions.Regular, verify: false); - comp.VerifyIL("Program.M(ref readonly int)", @" + comp.VerifyIL("Program.M(in int)", @" { // Code size 2 (0x2) .maxstack 1 @@ -363,7 +363,7 @@ public void ReadonlyParamCannotAssign() var text = @" class Program { - static void M(ref readonly int arg1, ref readonly (int Alice, int Bob) arg2) + static void M(in int arg1, in (int Alice, int Bob) arg2) { arg1 = 1; arg2.Alice = 2; @@ -379,24 +379,24 @@ static void M(ref readonly int arg1, ref readonly (int Alice, int Bob) arg2) var comp = CreateCompilationWithMscorlib45(text, new[] { ValueTupleRef, SystemRuntimeFacadeRef }); comp.VerifyDiagnostics( - // (6,9): error CS8408: Cannot assign to variable 'ref readonly int' because it is a readonly variable + // (6,9): error CS8408: Cannot assign to variable 'in int' because it is a readonly variable // arg1 = 1; - Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "arg1").WithArguments("variable", "ref readonly int").WithLocation(6, 9), - // (7,9): error CS8409: Cannot assign to a member of variable 'ref readonly (int Alice, int Bob)' because it is a readonly variable + Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "arg1").WithArguments("variable", "in int").WithLocation(6, 9), + // (7,9): error CS8409: Cannot assign to a member of variable 'in (int Alice, int Bob)' because it is a readonly variable // arg2.Alice = 2; - Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "arg2.Alice").WithArguments("variable", "ref readonly (int Alice, int Bob)").WithLocation(7, 9), - // (9,9): error CS8408: Cannot assign to variable 'ref readonly int' because it is a readonly variable + Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "arg2.Alice").WithArguments("variable", "in (int Alice, int Bob)").WithLocation(7, 9), + // (9,9): error CS8408: Cannot assign to variable 'in int' because it is a readonly variable // arg1 ++; - Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "arg1").WithArguments("variable", "ref readonly int").WithLocation(9, 9), - // (10,9): error CS8409: Cannot assign to a member of variable 'ref readonly (int Alice, int Bob)' because it is a readonly variable + Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "arg1").WithArguments("variable", "in int").WithLocation(9, 9), + // (10,9): error CS8409: Cannot assign to a member of variable 'in (int Alice, int Bob)' because it is a readonly variable // arg2.Alice --; - Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "arg2.Alice").WithArguments("variable", "ref readonly (int Alice, int Bob)").WithLocation(10, 9), - // (12,9): error CS8408: Cannot assign to variable 'ref readonly int' because it is a readonly variable + Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "arg2.Alice").WithArguments("variable", "in (int Alice, int Bob)").WithLocation(10, 9), + // (12,9): error CS8408: Cannot assign to variable 'in int' because it is a readonly variable // arg1 += 1; - Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "arg1").WithArguments("variable", "ref readonly int"), - // (13,9): error CS8409: Cannot assign to a member of variable 'ref readonly (int Alice, int Bob)' because it is a readonly variable + Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "arg1").WithArguments("variable", "in int"), + // (13,9): error CS8409: Cannot assign to a member of variable 'in (int Alice, int Bob)' because it is a readonly variable // arg2.Alice -= 2; - Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "arg2.Alice").WithArguments("variable", "ref readonly (int Alice, int Bob)")); + Diagnostic(ErrorCode.ERR_AssignReadonlyNotField2, "arg2.Alice").WithArguments("variable", "in (int Alice, int Bob)")); } [Fact] @@ -405,24 +405,24 @@ public void ReadonlyParamCannotRefReturn() var text = @" class Program { - static ref readonly int M1_baseline(ref readonly int arg1, ref readonly (int Alice, int Bob) arg2) + static ref readonly int M1_baseline(in int arg1, in (int Alice, int Bob) arg2) { // valid return ref arg1; } - static ref readonly int M2_baseline(ref readonly int arg1, ref readonly (int Alice, int Bob) arg2) + static ref readonly int M2_baseline(in int arg1, in (int Alice, int Bob) arg2) { // valid return ref arg2.Alice; } - static ref int M1(ref readonly int arg1, ref readonly (int Alice, int Bob) arg2) + static ref int M1(in int arg1, in (int Alice, int Bob) arg2) { return ref arg1; } - static ref int M2(ref readonly int arg1, ref readonly (int Alice, int Bob) arg2) + static ref int M2(in int arg1, in (int Alice, int Bob) arg2) { return ref arg2.Alice; } @@ -431,12 +431,12 @@ static ref int M2(ref readonly int arg1, ref readonly (int Alice, int Bob) arg2) var comp = CreateCompilationWithMscorlib45(text, new[] { ValueTupleRef, SystemRuntimeFacadeRef }); comp.VerifyDiagnostics( - // (18,20): error CS8410: Cannot return variable 'ref readonly int' by writable reference because it is a readonly variable + // (18,20): error CS8410: Cannot return variable 'in int' by writable reference because it is a readonly variable // return ref arg1; - Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "arg1").WithArguments("variable", "ref readonly int").WithLocation(18, 20), - // (23,20): error CS8411: Members of variable 'ref readonly (int Alice, int Bob)' cannot be returned by writable reference because it is a readonly variable + Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "arg1").WithArguments("variable", "in int").WithLocation(18, 20), + // (23,20): error CS8411: Members of variable 'in (int Alice, int Bob)' cannot be returned by writable reference because it is a readonly variable // return ref arg2.Alice; - Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField2, "arg2.Alice").WithArguments("variable", "ref readonly (int Alice, int Bob)").WithLocation(23, 20) + Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField2, "arg2.Alice").WithArguments("variable", "in (int Alice, int Bob)").WithLocation(23, 20) ); } @@ -446,7 +446,7 @@ public void ReadonlyParamCannotAssignByref() var text = @" class Program { - static void M(ref readonly int arg1, ref readonly (int Alice, int Bob) arg2) + static void M(in int arg1, in (int Alice, int Bob) arg2) { ref var y = ref arg1; ref int a = ref arg2.Alice; @@ -456,12 +456,12 @@ static void M(ref readonly int arg1, ref readonly (int Alice, int Bob) arg2) var comp = CreateCompilationWithMscorlib45(text, new[] { ValueTupleRef, SystemRuntimeFacadeRef }); comp.VerifyDiagnostics( - // (6,25): error CS8406: Cannot use variable 'ref readonly int' as a ref or out value because it is a readonly variable + // (6,25): error CS8406: Cannot use variable 'in int' as a ref or out value because it is a readonly variable // ref var y = ref arg1; - Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "arg1").WithArguments("variable", "ref readonly int"), - // (7,25): error CS8407: Members of variable 'ref readonly (int Alice, int Bob)' cannot be used as a ref or out value because it is a readonly variable + Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "arg1").WithArguments("variable", "in int"), + // (7,25): error CS8407: Members of variable 'in (int Alice, int Bob)' cannot be used as a ref or out value because it is a readonly variable // ref int a = ref arg2.Alice; - Diagnostic(ErrorCode.ERR_RefReadonlyNotField2, "arg2.Alice").WithArguments("variable", "ref readonly (int Alice, int Bob)")); + Diagnostic(ErrorCode.ERR_RefReadonlyNotField2, "arg2.Alice").WithArguments("variable", "in (int Alice, int Bob)")); } [Fact] @@ -470,7 +470,7 @@ public void ReadonlyParamCannotTakePtr() var text = @" class Program { - unsafe static void M(ref readonly int arg1, ref readonly (int Alice, int Bob) arg2) + unsafe static void M(in int arg1, in (int Alice, int Bob) arg2) { int* a = & arg1; int* b = & arg2.Alice; @@ -509,7 +509,7 @@ public void ReadonlyParamCannotReturnByOrdinaryRef() var text = @" class Program { - static ref int M(ref readonly int arg1, ref readonly (int Alice, int Bob) arg2) + static ref int M(in int arg1, in (int Alice, int Bob) arg2) { bool b = true; @@ -527,12 +527,12 @@ static ref int M(ref readonly int arg1, ref readonly (int Alice, int Bob) arg2) var comp = CreateCompilationWithMscorlib45(text, new[] { ValueTupleRef, SystemRuntimeFacadeRef }); comp.VerifyDiagnostics( - // (10,24): error CS8410: Cannot return variable 'ref readonly int' by writable reference because it is a readonly variable + // (10,24): error CS8410: Cannot return variable 'in int' by writable reference because it is a readonly variable // return ref arg1; - Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "arg1").WithArguments("variable", "ref readonly int").WithLocation(10, 24), - // (14,24): error CS8411: Members of variable 'ref readonly (int Alice, int Bob)' cannot be returned by writable reference because it is a readonly variable + Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "arg1").WithArguments("variable", "in int").WithLocation(10, 24), + // (14,24): error CS8411: Members of variable 'in (int Alice, int Bob)' cannot be returned by writable reference because it is a readonly variable // return ref arg2.Alice; - Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField2, "arg2.Alice").WithArguments("variable", "ref readonly (int Alice, int Bob)").WithLocation(14, 24) + Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField2, "arg2.Alice").WithArguments("variable", "in (int Alice, int Bob)").WithLocation(14, 24) ); } @@ -542,7 +542,7 @@ public void ReadonlyParamCanReturnByRefReadonly() var text = @" class Program { - static ref readonly int M(ref readonly int arg1, ref readonly (int Alice, int Bob) arg2) + static ref readonly int M(in int arg1, in (int Alice, int Bob) arg2) { bool b = true; @@ -580,9 +580,9 @@ public void ReadonlyParamCanReturnByRefReadonlyNested() var text = @" class Program { - static ref readonly int M(ref readonly int arg1, ref readonly (int Alice, int Bob) arg2) + static ref readonly int M(in int arg1, in (int Alice, int Bob) arg2) { - ref readonly int M1(ref readonly int arg11, ref readonly (int Alice, int Bob) arg21) + ref readonly int M1(in int arg11, in (int Alice, int Bob) arg21) { bool b = true; @@ -603,7 +603,7 @@ ref readonly int M1(ref readonly int arg11, ref readonly (int Alice, int Bob) ar var comp = CompileAndVerify(text, new[] { ValueTupleRef, SystemRuntimeFacadeRef }, parseOptions: TestOptions.Regular, verify: false); - comp.VerifyIL("Program.g__M1|0_0(ref readonly int, ref readonly (int Alice, int Bob))", @" + comp.VerifyIL("Program.g__M1|0_0(in int, in (int Alice, int Bob))", @" { // Code size 12 (0xc) .maxstack 1 @@ -623,9 +623,9 @@ public void ReadonlyParamCannotReturnByRefNested() var text = @" class Program { - static ref readonly int M(ref readonly int arg1, ref readonly (int Alice, int Bob) arg2) + static ref readonly int M(in int arg1, in (int Alice, int Bob) arg2) { - ref int M1(ref readonly int arg11, ref readonly (int Alice, int Bob) arg21) + ref int M1(in int arg11, in (int Alice, int Bob) arg21) { bool b = true; @@ -646,12 +646,12 @@ ref int M1(ref readonly int arg11, ref readonly (int Alice, int Bob) arg21) var comp = CreateCompilationWithMscorlib45(text, new[] { ValueTupleRef, SystemRuntimeFacadeRef }); comp.VerifyDiagnostics( - // (12,28): error CS8410: Cannot return variable 'ref readonly int' by writable reference because it is a readonly variable + // (12,28): error CS8410: Cannot return variable 'in int' by writable reference because it is a readonly variable // return ref arg11; - Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "arg11").WithArguments("variable", "ref readonly int").WithLocation(12, 28), - // (16,28): error CS8411: Members of variable 'ref readonly (int Alice, int Bob)' cannot be returned by writable reference because it is a readonly variable + Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "arg11").WithArguments("variable", "in int").WithLocation(12, 28), + // (16,28): error CS8411: Members of variable 'in (int Alice, int Bob)' cannot be returned by writable reference because it is a readonly variable // return ref arg21.Alice; - Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField2, "arg21.Alice").WithArguments("variable", "ref readonly (int Alice, int Bob)").WithLocation(16, 28) + Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField2, "arg21.Alice").WithArguments("variable", "in (int Alice, int Bob)").WithLocation(16, 28) ); } @@ -666,7 +666,7 @@ static void Main() System.Console.WriteLine(M()); } - static int M(ref readonly int x = 42) => x; + static int M(in int x = 42) => x; } "; @@ -681,7 +681,7 @@ .locals init (int V_0) IL_0000: ldc.i4.s 42 IL_0002: stloc.0 IL_0003: ldloca.s V_0 - IL_0005: call ""int Program.M(ref readonly int)"" + IL_0005: call ""int Program.M(in int)"" IL_000a: call ""void System.Console.WriteLine(int)"" IL_000f: ret }"); @@ -699,7 +699,7 @@ static void Main() System.Console.WriteLine(M(arg)); } - static double M(ref readonly double x) => x; + static double M(in double x) => x; } "; @@ -715,7 +715,7 @@ .locals init (double V_0) IL_0002: conv.r8 IL_0003: stloc.0 IL_0004: ldloca.s V_0 - IL_0006: call ""double Program.M(ref readonly double)"" + IL_0006: call ""double Program.M(in double)"" IL_000b: call ""void System.Console.WriteLine(double)"" IL_0010: ret }"); @@ -745,7 +745,7 @@ public static async Task GetT(T val) return val; } - public static void M1(ref readonly int arg1, ref readonly int arg2, ref readonly int arg3) + public static void M1(in int arg1, in int arg2, in int arg3) { System.Console.WriteLine(arg1 + arg2 + arg3); } @@ -781,7 +781,7 @@ public static async Task GetT(T val) return val; } - public static void M1(ref readonly int arg1, ref readonly int arg2, ref readonly int arg3) + public static void M1(in int arg1, in int arg2, in int arg3) { System.Console.WriteLine(arg1 + arg2 + arg3); } @@ -833,7 +833,7 @@ public static async Task GetT(T val) return val; } - public static void M1(ref readonly int arg1, ref readonly int arg2, ref readonly int arg3, ref readonly int arg4) + public static void M1(in int arg1, in int arg2, in int arg3, in int arg4) { System.Console.WriteLine(arg1); System.Console.WriteLine(arg2); @@ -901,7 +901,7 @@ public static async Task GetT(T val) return val; } - public static void M1(ref readonly int arg1, ref readonly int arg2, ref readonly int arg3, ref readonly int arg4) + public static void M1(in int arg1, in int arg2, in int arg3, in int arg4) { System.Console.WriteLine(arg1); System.Console.WriteLine(arg2); @@ -964,7 +964,7 @@ public static async Task GetT(T val) return val; } - public static void M1(ref readonly int arg1, ref readonly int arg2, ref readonly int arg3, ref readonly int arg4) + public static void M1(in int arg1, in int arg2, in int arg3, in int arg4) { System.Console.WriteLine(arg1); System.Console.WriteLine(arg2); @@ -1021,7 +1021,7 @@ public static async Task GetT(T val) return val; } - public static void M1(ref readonly int arg1, ref readonly int arg2, ref readonly int arg3, ref readonly int arg4) + public static void M1(in int arg1, in int arg2, in int arg3, in int arg4) { System.Console.WriteLine(arg1); System.Console.WriteLine(arg2); @@ -1081,7 +1081,7 @@ public static async Task GetT(T val) static class Ext { - public static void M1(ref readonly this int arg1, ref readonly int arg2, ref readonly int arg3, ref readonly int arg4) + public static void M1(in this int arg1, in int arg2, in int arg3, in int arg4) { System.Console.WriteLine(arg1); System.Console.WriteLine(arg2); @@ -1166,7 +1166,7 @@ public S1(int val) this.f = val; } - public void M1(ref readonly int arg2, ref readonly int arg3, ref readonly int arg4) + public void M1(in int arg2, in int arg3, in int arg4) { System.Console.WriteLine(this.f); System.Console.WriteLine(arg2); @@ -1247,7 +1247,7 @@ public S1(int val) this.f = val; } - public void M1(ref readonly S1 arg2, ref readonly S1 arg3, ref readonly S1 arg4) + public void M1(in S1 arg2, in S1 arg3, in S1 arg4) { System.Console.WriteLine(this.f); System.Console.WriteLine(arg2.f); @@ -1319,7 +1319,7 @@ .locals init (int V_0, IL_006c: ldsflda ""S1 Program.s2"" IL_0071: ldloca.s V_1 IL_0073: ldsflda ""S1 Program.s4"" - IL_0078: call ""void S1.M1(ref readonly S1, ref readonly S1, ref readonly S1)"" + IL_0078: call ""void S1.M1(in S1, in S1, in S1)"" IL_007d: leave.s IL_0096 } catch System.Exception @@ -1415,7 +1415,7 @@ .locals init (int V_0, IL_007a: ldsfld ""S1 Program.s4"" IL_007f: stloc.s V_5 IL_0081: ldloca.s V_5 - IL_0083: call ""void S1.M1(ref readonly S1, ref readonly S1, ref readonly S1)"" + IL_0083: call ""void S1.M1(in S1, in S1, in S1)"" IL_0088: leave.s IL_00a3 } catch System.Exception @@ -1461,12 +1461,12 @@ static void Main(string[] args) abstract class C { - public abstract void M1(ref readonly T arg) where T : U, I1; + public abstract void M1(in T arg) where T : U, I1; } class D: C { - public override void M1(ref readonly T arg) + public override void M1(in T arg) { arg.M3(); } @@ -1490,7 +1490,7 @@ interface I1 var comp = CompileAndVerify(text, parseOptions: TestOptions.Regular, verify: false, expectedOutput: @"0"); - comp.VerifyIL("D.M1(ref readonly T)", @" + comp.VerifyIL("D.M1(in T)", @" { // Code size 21 (0x15) .maxstack 1 @@ -1522,12 +1522,12 @@ static void Main(string[] args) abstract class C { - public abstract void M1(ref readonly T arg) where T : U, I1; + public abstract void M1(in T arg) where T : U, I1; } class D: C { - public override void M1(ref readonly T arg) + public override void M1(in T arg) { arg.M3(); } @@ -1548,7 +1548,7 @@ interface I1 var comp = CompileAndVerify(text, parseOptions: TestOptions.Regular, verify: false, expectedOutput: @""); - comp.VerifyIL("D.M1(ref readonly T)", @" + comp.VerifyIL("D.M1(in T)", @" { // Code size 21 (0x15) .maxstack 1 @@ -1570,7 +1570,7 @@ public void RefReadOnlyOptionalParameters() using System; class Program { - static void Print(ref readonly int p = 5) + static void Print(in int p = 5) { Console.Write(p); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs index 52a22b962ad36..d37193a75be9b 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs @@ -40,14 +40,14 @@ class C ref readonly S M() { - ref readonly S rs1 = ref s1; + in S rs1 = ref s1; rs1.AddOne(); - ref readonly S rs2 = ref s2; + in S rs2 = ref s2; rs2.AddOne(); - ref readonly S2 rs3 = ref s3; + in S2 rs3 = ref s3; rs3.AddOne(); - ref readonly S2 rs4 = ref s4; + in S2 rs4 = ref s4; rs4.AddOne(); return ref rs1; @@ -226,7 +226,7 @@ public static void Main() { M(new S(0)); } - static void M(ref readonly S rs) + static void M(in S rs) { Console.WriteLine(rs.X); rs.AddOne(); @@ -284,7 +284,7 @@ class C { public static void Main() { - void L(ref readonly int p) + void L(in int p) { Console.WriteLine(p); } @@ -312,9 +312,9 @@ .locals init (int V_0, //i IL_0004: ldc.i4.s 10 IL_0006: stloc.1 IL_0007: ldloca.s V_1 - IL_0009: call ""void C.
g__L|0_0(ref readonly int)"" + IL_0009: call ""void C.
g__L|0_0(in int)"" IL_000e: ldloca.s V_0 - IL_0010: call ""void C.
g__L|0_0(ref readonly int)"" + IL_0010: call ""void C.
g__L|0_0(in int)"" IL_0015: ldloc.0 IL_0016: ldc.i4.1 IL_0017: add @@ -954,7 +954,7 @@ ref readonly int Test() return ref this[local]; } - ref readonly int this[ref readonly int x] => ref x; + ref readonly int this[in int x] => ref x; } "; @@ -964,9 +964,9 @@ ref readonly int Test() // (8,25): error CS8168: Cannot return local 'local' by reference because it is not a ref local // return ref this[local]; Diagnostic(ErrorCode.ERR_RefReturnLocal, "local").WithArguments("local").WithLocation(8, 25), - // (8,20): error CS8521: Cannot use a result of 'Program.this[ref readonly int]' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope + // (8,20): error CS8521: Cannot use a result of 'Program.this[in int]' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope // return ref this[local]; - Diagnostic(ErrorCode.ERR_EscapeCall, "this[local]").WithArguments("Program.this[ref readonly int]", "x").WithLocation(8, 20) + Diagnostic(ErrorCode.ERR_EscapeCall, "this[local]").WithArguments("Program.this[in int]", "x").WithLocation(8, 20) ); } @@ -981,7 +981,7 @@ ref readonly int Test() return ref this[42]; } - ref readonly int this[ref readonly int x] => ref x; + ref readonly int this[in int x] => ref x; } "; @@ -991,9 +991,9 @@ ref readonly int Test() // (6,25): error CS8156: An expression cannot be used in this context because it may not be returned by reference // return ref this[42]; Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "42").WithLocation(6, 25), - // (6,20): error CS8521: Cannot use a result of 'Program.this[ref readonly int]' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope + // (6,20): error CS8521: Cannot use a result of 'Program.this[in int]' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope // return ref this[42]; - Diagnostic(ErrorCode.ERR_EscapeCall, "this[42]").WithArguments("Program.this[ref readonly int]", "x").WithLocation(6, 20) + Diagnostic(ErrorCode.ERR_EscapeCall, "this[42]").WithArguments("Program.this[in int]", "x").WithLocation(6, 20) ); } @@ -1011,7 +1011,7 @@ ref readonly S1 Test() return ref this; } - ref readonly int this[ref readonly int i] => ref x; + ref readonly int this[in int i] => ref x; } "; @@ -1022,7 +1022,7 @@ ref readonly S1 Test() // return ref this; Diagnostic(ErrorCode.ERR_RefReturnStructThis, "this").WithArguments("this").WithLocation(8, 20), // (11,44): error CS8170: Struct members cannot return 'this' or other instance members by reference - // ref readonly int this[ref readonly int i] => ref x; + // in int this[in int i] => ref x; Diagnostic(ErrorCode.ERR_RefReturnStructThis, "x").WithArguments("this").WithLocation(11, 54) ); } @@ -1061,7 +1061,7 @@ ref readonly int Test() return ref M(42); } - ref readonly int M(ref readonly int x) => ref x; + ref readonly int M(in int x) => ref x; } "; @@ -1071,9 +1071,9 @@ ref readonly int Test() // (6,22): error CS8156: An expression cannot be used in this context because it may not be returned by reference // return ref M(42); Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "42").WithLocation(6, 22), - // (6,20): error CS8521: Cannot use a result of 'Program.M(ref readonly int)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope + // (6,20): error CS8521: Cannot use a result of 'Program.M(in int)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope // return ref M(42); - Diagnostic(ErrorCode.ERR_EscapeCall, "M(42)").WithArguments("Program.M(ref readonly int)", "x").WithLocation(6, 20) + Diagnostic(ErrorCode.ERR_EscapeCall, "M(42)").WithArguments("Program.M(in int)", "x").WithLocation(6, 20) ); } @@ -1088,16 +1088,16 @@ ref readonly int Test() return ref M(); } - ref readonly int M(ref readonly int x = 42) => ref x; + ref readonly int M(in int x = 42) => ref x; } "; var comp = CreateCompilationWithMscorlib45(text, new[] { ValueTupleRef, SystemRuntimeFacadeRef }); comp.VerifyDiagnostics( - // (6,20): error CS8521: Cannot use a result of 'Program.M(ref readonly int)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope + // (6,20): error CS8521: Cannot use a result of 'Program.M(in int)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope // return ref M(); - Diagnostic(ErrorCode.ERR_EscapeCall, "M()").WithArguments("Program.M(ref readonly int)", "x").WithLocation(6, 20) + Diagnostic(ErrorCode.ERR_EscapeCall, "M()").WithArguments("Program.M(in int)", "x").WithLocation(6, 20) ); } @@ -1113,7 +1113,7 @@ ref readonly int Test() return ref M(b); } - ref readonly int M(ref readonly int x) => ref x; + ref readonly int M(in int x) => ref x; } "; @@ -1123,9 +1123,9 @@ ref readonly int Test() // (7,22): error CS8156: An expression cannot be used in this context because it may not be returned by reference // return ref M(b); Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "b").WithLocation(7, 22), - // (7,20): error CS8521: Cannot use a result of 'Program.M(ref readonly int)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope + // (7,20): error CS8521: Cannot use a result of 'Program.M(in int)' in this context because it may expose variables referenced by parameter 'x' outside of their declaration scope // return ref M(b); - Diagnostic(ErrorCode.ERR_EscapeCall, "M(b)").WithArguments("Program.M(ref readonly int)", "x").WithLocation(7, 20) + Diagnostic(ErrorCode.ERR_EscapeCall, "M(b)").WithArguments("Program.M(in int)", "x").WithLocation(7, 20) ); } @@ -1250,7 +1250,7 @@ public void RefReadOnlyExtensionMethod_PassThrough_TempCopying() CompileAndVerify(@" public static class Ext { - public static ref readonly int M(ref readonly this int p) => ref p; + public static ref readonly int M(in this int p) => ref p; } class Test { @@ -1266,7 +1266,7 @@ .locals init (int V_0) IL_0000: ldc.i4.5 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: call ""ref readonly int Ext.M(ref readonly int)"" + IL_0004: call ""ref readonly int Ext.M(in int)"" IL_0009: pop IL_000a: ret }"); @@ -1278,7 +1278,7 @@ public void RefReadOnlyExtensionMethod_PassThrough_LocalNoCopying() CompileAndVerify(@" public static class Ext { - public static ref readonly int M(ref readonly this int p) => ref p; + public static ref readonly int M(in this int p) => ref p; } class Test { @@ -1295,7 +1295,7 @@ .locals init (int V_0) //x IL_0000: ldc.i4.5 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: call ""ref readonly int Ext.M(ref readonly int)"" + IL_0004: call ""ref readonly int Ext.M(in int)"" IL_0009: pop IL_000a: ret }"); @@ -1307,7 +1307,7 @@ public void RefReadOnlyExtensionMethod_PassThrough_FieldNoCopying() CompileAndVerify(@" public static class Ext { - public static ref readonly int M(ref readonly this int p) => ref p; + public static ref readonly int M(in this int p) => ref p; } class Test { @@ -1322,7 +1322,7 @@ void M() .maxstack 1 IL_0000: ldarg.0 IL_0001: ldflda ""int Test.x"" - IL_0006: call ""ref readonly int Ext.M(ref readonly int)"" + IL_0006: call ""ref readonly int Ext.M(in int)"" IL_000b: pop IL_000c: ret }"); @@ -1334,7 +1334,7 @@ public void RefReadOnlyExtensionMethod_PassThrough_ChainNoCopying() CompileAndVerify(@" public static class Ext { - public static ref readonly int M(ref readonly this int p) => ref p; + public static ref readonly int M(in this int p) => ref p; } class Test { @@ -1349,9 +1349,9 @@ void M() .maxstack 1 IL_0000: ldarg.0 IL_0001: ldflda ""int Test.x"" - IL_0006: call ""ref readonly int Ext.M(ref readonly int)"" - IL_000b: call ""ref readonly int Ext.M(ref readonly int)"" - IL_0010: call ""ref readonly int Ext.M(ref readonly int)"" + IL_0006: call ""ref readonly int Ext.M(in int)"" + IL_000b: call ""ref readonly int Ext.M(in int)"" + IL_0010: call ""ref readonly int Ext.M(in int)"" IL_0015: pop IL_0016: ret }"); @@ -1363,7 +1363,7 @@ public void RefReadOnlyReturnOptionalValue() CompileAndVerify(@" class Program { - static ref readonly string M(ref readonly string s = ""optional"") => ref s; + static ref readonly string M(in string s = ""optional"") => ref s; static void Main() { diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReturnTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReturnTests.cs index 014060ddce742..dc83053a4159b 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReturnTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReturnTests.cs @@ -3009,7 +3009,7 @@ public static dynamic F(ref dynamic d) return temp1; } - public static ref dynamic F1(ref readonly int arg1, ref dynamic d, ref readonly int arg2) + public static ref dynamic F1(in int arg1, ref dynamic d, in int arg2) { if (arg1 == arg2) throw null; diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenStructsAndEnum.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenStructsAndEnum.cs index 6af8dea604a0d..b939bd10c5168 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenStructsAndEnum.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenStructsAndEnum.cs @@ -2047,12 +2047,12 @@ static void Main() RefMethod(arg2: I(0), arg1: I(0)))); } - public static ref readonly S RefMethod(ref readonly S arg1, ref readonly S arg2) + public static ref readonly S RefMethod(in S arg1, in S arg2) { return ref arg2; } - public bool GreaterThan(ref readonly S arg) + public bool GreaterThan(in S arg) { return this.x > arg.x; } @@ -2088,7 +2088,7 @@ .locals init (S& V_0, IL_0010: stloc.2 IL_0011: ldloca.s V_2 IL_0013: ldloc.0 - IL_0014: call ""ref readonly S S.RefMethod(ref readonly S, ref readonly S)"" + IL_0014: call ""ref readonly S S.RefMethod(in S, in S)"" IL_0019: ldc.i4.0 IL_001a: call ""S S.I(int)"" IL_001f: stloc.s V_4 @@ -2099,8 +2099,8 @@ .locals init (S& V_0, IL_002a: stloc.s V_5 IL_002c: ldloca.s V_5 IL_002e: ldloc.3 - IL_002f: call ""ref readonly S S.RefMethod(ref readonly S, ref readonly S)"" - IL_0034: call ""bool S.GreaterThan(ref readonly S)"" + IL_002f: call ""ref readonly S S.RefMethod(in S, in S)"" + IL_0034: call ""bool S.GreaterThan(in S)"" IL_0039: call ""void System.Console.WriteLine(bool)"" IL_003e: ret } @@ -2143,7 +2143,7 @@ static ref readonly S TestRO() } } - public static ref readonly S RefMethodRO(ref readonly S arg1, ref readonly S arg2) + public static ref readonly S RefMethodRO(in S arg1, in S arg2) { System.Console.Write(arg2.x); return ref arg2; @@ -2205,7 +2205,7 @@ .locals init (S& V_0, IL_0007: ldc.i4.3 IL_0008: call ""ref S S.I(int)"" IL_000d: ldloc.0 - IL_000e: call ""ref readonly S S.RefMethodRO(ref readonly S, ref readonly S)"" + IL_000e: call ""ref readonly S S.RefMethodRO(in S, in S)"" IL_0013: stloc.1 IL_0014: leave.s IL_002e } @@ -2219,7 +2219,7 @@ .locals init (S& V_0, IL_0020: ldc.i4.3 IL_0021: call ""ref S S.I(int)"" IL_0026: ldloc.0 - IL_0027: call ""ref readonly S S.RefMethodRO(ref readonly S, ref readonly S)"" + IL_0027: call ""ref readonly S S.RefMethodRO(in S, in S)"" IL_002c: pop IL_002d: endfinally } diff --git a/src/Compilers/CSharp/Test/Emit/Emit/InAttributeModifierTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/InAttributeModifierTests.cs index cd12ec6702f3d..1a04602fa77b2 100644 --- a/src/Compilers/CSharp/Test/Emit/Emit/InAttributeModifierTests.cs +++ b/src/Compilers/CSharp/Test/Emit/Emit/InAttributeModifierTests.cs @@ -18,7 +18,7 @@ public void InAttributeModReqIsConsumedInRefCustomModifiersPosition_Methods_Para var reference = CreateStandardCompilation(@" public class TestRef { - public void M(ref readonly int p) + public void M(in int p) { System.Console.WriteLine(p); } @@ -96,7 +96,7 @@ public void InAttributeModReqIsConsumedInRefCustomModifiersPosition_Indexers_Par var reference = CreateStandardCompilation(@" public class TestRef { - public int this[ref readonly int p] + public int this[in int p] { set { System.Console.WriteLine(p); } } @@ -145,7 +145,7 @@ public static void Main() public void InAttributeModReqIsConsumedInRefCustomModifiersPosition_Delegates_Parameters() { var reference = CreateStandardCompilation(@" -public delegate void D(ref readonly int p); +public delegate void D(in int p); "); var code = @" @@ -153,7 +153,7 @@ public class Test { public static void Main() { - Process((ref readonly int p) => System.Console.WriteLine(p)); + Process((in int p) => System.Console.WriteLine(p)); } private static void Process(D func) @@ -506,7 +506,7 @@ public class Test { public static void Main() { - Process((ref readonly int p) => System.Console.WriteLine(p)); + Process((in int p) => System.Console.WriteLine(p)); } private static void Process(D func) @@ -619,9 +619,9 @@ public static void Main() }"; CreateStandardCompilation(code, references: new[] { reference }).VerifyDiagnostics( - // (8,13): error CS0570: 'TestRef.M(ref readonly ?)' is not supported by the language + // (8,13): error CS0570: 'TestRef.M(in ?)' is not supported by the language // obj.M(value); - Diagnostic(ErrorCode.ERR_BindToBogus, "M").WithArguments("TestRef.M(ref readonly ?)").WithLocation(8, 13)); + Diagnostic(ErrorCode.ERR_BindToBogus, "M").WithArguments("TestRef.M(in ?)").WithLocation(8, 13)); } [Fact] @@ -805,9 +805,9 @@ public static void Main() }"; CreateStandardCompilation(code, references: new[] { reference }).VerifyDiagnostics( - // (8,9): error CS1546: Property, indexer, or event 'TestRef.this[ref readonly ?]' is not supported by the language; try directly calling accessor method 'TestRef.set_Item(ref readonly ?, ?)' + // (8,9): error CS1546: Property, indexer, or event 'TestRef.this[in ?]' is not supported by the language; try directly calling accessor method 'TestRef.set_Item(in ?, ?)' // obj[value] = 0; - Diagnostic(ErrorCode.ERR_BindToBogusProp1, "obj[value]").WithArguments("TestRef.this[ref readonly ?]", "TestRef.set_Item(ref readonly ?, ?)").WithLocation(8, 9)); + Diagnostic(ErrorCode.ERR_BindToBogusProp1, "obj[value]").WithArguments("TestRef.this[in ?]", "TestRef.set_Item(in ?, ?)").WithLocation(8, 9)); code = @" public class Test @@ -821,9 +821,9 @@ public static void Main() }"; CreateStandardCompilation(code, references: new[] { reference }).VerifyDiagnostics( - // (8,13): error CS0570: 'TestRef.set_Item(ref readonly ?, ?)' is not supported by the language + // (8,13): error CS0570: 'TestRef.set_Item(in ?, ?)' is not supported by the language // obj.set_Item(value, 0); - Diagnostic(ErrorCode.ERR_BindToBogus, "set_Item").WithArguments("TestRef.set_Item(ref readonly ?, ?)").WithLocation(8, 13)); + Diagnostic(ErrorCode.ERR_BindToBogus, "set_Item").WithArguments("TestRef.set_Item(in ?, ?)").WithLocation(8, 13)); } [Fact] @@ -945,7 +945,7 @@ public class Test { public static void Main() { - Process((ref readonly int p) => System.Console.WriteLine(p)); + Process((in int p) => System.Console.WriteLine(p)); } private static void Process(D func) @@ -956,12 +956,12 @@ private static void Process(D func) }"; CreateStandardCompilation(code, references: new[] { reference }).VerifyDiagnostics( - // (6,17): error CS0570: 'D.Invoke(ref readonly ?)' is not supported by the language - // Process((ref readonly int p) => System.Console.WriteLine(p)); - Diagnostic(ErrorCode.ERR_BindToBogus, "(ref readonly int p) => System.Console.WriteLine(p)").WithArguments("D.Invoke(ref readonly ?)").WithLocation(6, 17), - // (12,9): error CS0570: 'D.Invoke(ref readonly ?)' is not supported by the language + // (6,17): error CS0570: 'D.Invoke(in ?)' is not supported by the language + // Process((in int p) => System.Console.WriteLine(p)); + Diagnostic(ErrorCode.ERR_BindToBogus, "(in int p) => System.Console.WriteLine(p)").WithArguments("D.Invoke(in ?)").WithLocation(6, 17), + // (12,9): error CS0570: 'D.Invoke(in ?)' is not supported by the language // func(value); - Diagnostic(ErrorCode.ERR_BindToBogus, "func(value)").WithArguments("D.Invoke(ref readonly ?)").WithLocation(12, 9)); + Diagnostic(ErrorCode.ERR_BindToBogus, "func(value)").WithArguments("D.Invoke(in ?)").WithLocation(12, 9)); } [Fact] @@ -1396,7 +1396,7 @@ public class Test { public static void Main() { - Process((ref readonly int p) => System.Console.WriteLine(p)); + Process((in int p) => System.Console.WriteLine(p)); } private static void Process(D func) @@ -1408,8 +1408,8 @@ private static void Process(D func) CreateStandardCompilation(code, references: new[] { reference }).VerifyDiagnostics( // (6,17): error CS0570: 'D.Invoke(?)' is not supported by the language - // Process((ref readonly int p) => System.Console.WriteLine(p)); - Diagnostic(ErrorCode.ERR_BindToBogus, "(ref readonly int p) => System.Console.WriteLine(p)").WithArguments("D.Invoke(?)").WithLocation(6, 17), + // Process((in int p) => System.Console.WriteLine(p)); + Diagnostic(ErrorCode.ERR_BindToBogus, "(in int p) => System.Console.WriteLine(p)").WithArguments("D.Invoke(?)").WithLocation(6, 17), // (12,9): error CS0570: 'D.Invoke(?)' is not supported by the language // func(value); Diagnostic(ErrorCode.ERR_BindToBogus, "func(value)").WithArguments("D.Invoke(?)").WithLocation(12, 9)); @@ -1485,13 +1485,13 @@ public class Void {} } class Test { - public virtual void M(ref readonly object x) { } + public virtual void M(in object x) { } }"; CreateCompilation(code).VerifyDiagnostics( // (9,27): error CS0518: Predefined type 'System.Runtime.InteropServices.InAttribute' is not defined or imported - // public virtual void M(ref readonly object x) { } - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly object x").WithArguments("System.Runtime.InteropServices.InAttribute").WithLocation(9, 27)); + // public virtual void M(in object x) { } + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "in object x").WithArguments("System.Runtime.InteropServices.InAttribute").WithLocation(9, 27)); } [Fact] @@ -1547,13 +1547,13 @@ public class Void {} } class Test { - public virtual object this[ref readonly object p] => null; + public virtual object this[in object p] => null; }"; CreateCompilation(code).VerifyDiagnostics( // (9,32): error CS0518: Predefined type 'System.Runtime.InteropServices.InAttribute' is not defined or imported - // public virtual object this[ref readonly object p] => null; - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly object p").WithArguments("System.Runtime.InteropServices.InAttribute").WithLocation(9, 32)); + // public virtual object this[in object p] => null; + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "in object p").WithArguments("System.Runtime.InteropServices.InAttribute").WithLocation(9, 32)); } [Fact] @@ -1590,12 +1590,12 @@ public class Int32 {} public class Delegate {} public class MulticastDelegate : Delegate {} } -public delegate void D(ref readonly int p);"; +public delegate void D(in int p);"; CreateCompilation(code).VerifyDiagnostics( // (11,24): error CS0518: Predefined type 'System.Runtime.InteropServices.InAttribute' is not defined or imported - // public delegate void D(ref readonly int p); - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly int p").WithArguments("System.Runtime.InteropServices.InAttribute").WithLocation(11, 24)); + // public delegate void D(in int p); + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "in int p").WithArguments("System.Runtime.InteropServices.InAttribute").WithLocation(11, 24)); } [Fact] @@ -1625,7 +1625,7 @@ public void InAttributeIsWrittenOnRefReadOnlyMembers_Methods_Parameters_Virtual( var code = @" class Test { - public virtual void Method(ref readonly int x) { } + public virtual void Method(in int x) { } }"; Action validator = module => @@ -1645,7 +1645,7 @@ public void InAttributeIsWrittenOnRefReadOnlyMembers_Methods_Parameters_Abstract var code = @" abstract class Test { - public abstract void Method(ref readonly int x); + public abstract void Method(in int x); }"; Action validator = module => @@ -1831,7 +1831,7 @@ public void InAttributeIsWrittenOnRefReadOnlyMembers_Indexers_Parameters_Virtual var code = @" class Test { - public virtual int this[ref readonly int x] => x; + public virtual int this[in int x] => x; }"; Action validator = module => @@ -1851,7 +1851,7 @@ public void InAttributeIsWrittenOnRefReadOnlyMembers_Indexers_Parameters_Abstrac var code = @" abstract class Test { - public abstract int this[ref readonly int x] { get; } + public abstract int this[in int x] { get; } }"; Action validator = module => @@ -1931,7 +1931,7 @@ class Test [Fact] public void InAttributeIsWrittenOnRefReadOnlyMembers_Delegates_Parameters() { - var code = "public delegate void D(ref readonly int p);"; + var code = "public delegate void D(in int p);"; Action validator = module => { @@ -1980,7 +1980,7 @@ public void InAttributeIsNotWrittenOnRefReadOnlyMembers_Methods_Parameters_NoMod var code = @" class Test { - public void Method(ref readonly int x) { } + public void Method(in int x) { } }"; Action validator = module => @@ -2000,7 +2000,7 @@ public void InAttributeIsNotWrittenOnRefReadOnlyMembers_Methods_Parameters_Stati var code = @" class Test { - public static void Method(ref readonly int x) { } + public static void Method(in int x) { } }"; Action validator = module => @@ -2020,7 +2020,7 @@ public void InAttributeIsNotWrittenOnRefReadOnlyMembers_Indexers_Parameters_NoMo var code = @" class Test { - public int this[ref readonly int x] => x; + public int this[in int x] => x; }"; Action validator = module => @@ -2040,7 +2040,7 @@ public void InAttributeIsNotWrittenOnRefReadOnlyMembers_Operators_Unary() var code = @" public class Test { - public static bool operator!(ref readonly Test obj) => false; + public static bool operator!(in Test obj) => false; }"; Action validator = module => @@ -2060,7 +2060,7 @@ public void InAttributeIsNotWrittenOnRefReadOnlyMembers_Operators_Binary() var code = @" public class Test { - public static bool operator+(ref readonly Test obj1, ref readonly Test obj2) => false; + public static bool operator+(in Test obj1, in Test obj2) => false; }"; Action validator = module => @@ -2084,7 +2084,7 @@ public void InAttributeIsNotWrittenOnRefReadOnlyMembers_Constructors() var code = @" public class Test { - public Test(ref readonly int x) { } + public Test(in int x) { } }"; Action validator = module => @@ -2392,7 +2392,7 @@ public class Test { public static void Main() { - Process((ref readonly int p) => System.Console.WriteLine(p)); + Process((in int p) => System.Console.WriteLine(p)); } private static void Process(D func) @@ -2404,8 +2404,8 @@ private static void Process(D func) CreateStandardCompilation(code, references: new[] { CompileIL(ilSource) }).VerifyDiagnostics( // (6,17): error CS0570: 'D.Invoke(ref int)' is not supported by the language - // Process((ref readonly int p) => System.Console.WriteLine(p)); - Diagnostic(ErrorCode.ERR_BindToBogus, "(ref readonly int p) => System.Console.WriteLine(p)").WithArguments("D.Invoke(ref int)").WithLocation(6, 17), + // Process((in int p) => System.Console.WriteLine(p)); + Diagnostic(ErrorCode.ERR_BindToBogus, "(in int p) => System.Console.WriteLine(p)").WithArguments("D.Invoke(ref int)").WithLocation(6, 17), // (12,9): error CS0570: 'D.Invoke(ref int)' is not supported by the language // func(value); Diagnostic(ErrorCode.ERR_BindToBogus, "func(value)").WithArguments("D.Invoke(ref int)").WithLocation(12, 9)); @@ -2470,7 +2470,7 @@ public void WhenImplementingParentWithModifiersCopyThem_Methods_Parameters_Class var reference = CreateStandardCompilation(@" public abstract class Parent { - public abstract void M(ref readonly int p); + public abstract void M(in int p); }"); CompileAndVerify(reference, symbolValidator: module => @@ -2485,7 +2485,7 @@ public abstract class Parent var code = @" public class Child : Parent { - public override void M(ref readonly int p) + public override void M(in int p) { System.Console.WriteLine(p); } @@ -2518,7 +2518,7 @@ public void WhenImplementingParentWithModifiersCopyThem_Methods_Parameters_Class var reference = CreateStandardCompilation(@" public class Parent { - public virtual void M(ref readonly int p) {} + public virtual void M(in int p) {} }"); CompileAndVerify(reference, symbolValidator: module => @@ -2533,7 +2533,7 @@ public virtual void M(ref readonly int p) {} var code = @" public class Child : Parent { - public override void M(ref readonly int p) + public override void M(in int p) { System.Console.WriteLine(p); } @@ -2565,7 +2565,7 @@ public void WhenImplementingParentWithModifiersCopyThem_Methods_Parameters_Impli var reference = CreateStandardCompilation(@" public interface Parent { - void M(ref readonly int p); + void M(in int p); }"); CompileAndVerify(reference, symbolValidator: module => @@ -2580,7 +2580,7 @@ public interface Parent var code = @" public class Child : Parent { - public void M(ref readonly int p) + public void M(in int p) { System.Console.WriteLine(p); } @@ -2603,7 +2603,7 @@ public static void Main() Assert.Empty(implicitParameter.RefCustomModifiers); var explicitImplementation = type.GetMethod("Parent.M"); - Assert.Equal("void Parent.M(ref readonly modreq(System.Runtime.InteropServices.InAttribute) System.Int32 p)", explicitImplementation.ExplicitInterfaceImplementations.Single().ToTestDisplayString()); + Assert.Equal("void Parent.M(in modreq(System.Runtime.InteropServices.InAttribute) System.Int32 p)", explicitImplementation.ExplicitInterfaceImplementations.Single().ToTestDisplayString()); var explicitParameter = explicitImplementation.Parameters.Single(); Assert.Empty(explicitParameter.CustomModifiers); @@ -2620,7 +2620,7 @@ public void WhenImplementingParentWithModifiersCopyThem_Methods_Parameters_Impli var reference = CreateStandardCompilation(@" public interface Parent { - void M(ref readonly int p); + void M(in int p); }"); CompileAndVerify(reference, symbolValidator: module => @@ -2635,7 +2635,7 @@ public interface Parent var code = @" public class Child : Parent { - public virtual void M(ref readonly int p) + public virtual void M(in int p) { System.Console.WriteLine(p); } @@ -2668,7 +2668,7 @@ public void WhenImplementingParentWithModifiersCopyThem_Methods_Parameters_Expli var reference = CreateStandardCompilation(@" public interface Parent { - void M(ref readonly int p); + void M(in int p); }"); CompileAndVerify(reference, symbolValidator: module => @@ -2683,7 +2683,7 @@ public interface Parent var code = @" public class Child : Parent { - void Parent.M(ref readonly int p) + void Parent.M(in int p) { System.Console.WriteLine(p); } @@ -3169,7 +3169,7 @@ public void WhenImplementingParentWithModifiersCopyThem_Indexers_Parameters_Clas var reference = CreateStandardCompilation(@" public abstract class Parent { - public abstract int this[ref readonly int p] { set; } + public abstract int this[in int p] { set; } }"); CompileAndVerify(reference, symbolValidator: module => @@ -3184,7 +3184,7 @@ public abstract class Parent var code = @" public class Child : Parent { - public override int this[ref readonly int p] + public override int this[in int p] { set { System.Console.WriteLine(p); } } @@ -3217,7 +3217,7 @@ public void WhenImplementingParentWithModifiersCopyThem_Indexers_Parameters_Clas var reference = CreateStandardCompilation(@" public class Parent { - public virtual int this[ref readonly int p] { set { } } + public virtual int this[in int p] { set { } } }"); CompileAndVerify(reference, symbolValidator: module => @@ -3232,7 +3232,7 @@ public virtual int this[ref readonly int p] { set { } } var code = @" public class Child : Parent { - public override int this[ref readonly int p] + public override int this[in int p] { set { System.Console.WriteLine(p); } } @@ -3265,7 +3265,7 @@ public void WhenImplementingParentWithModifiersCopyThem_Indexers_Parameters_Impl var reference = CreateStandardCompilation(@" public interface Parent { - int this[ref readonly int p] { set; } + int this[in int p] { set; } }"); CompileAndVerify(reference, symbolValidator: module => @@ -3280,7 +3280,7 @@ public interface Parent var code = @" public class Child : Parent { - public int this[ref readonly int p] + public int this[in int p] { set { System.Console.WriteLine(p); } } @@ -3303,7 +3303,7 @@ public static void Main() Assert.Empty(implicitParameter.RefCustomModifiers); var explicitImplementation = type.GetMethod("Parent.set_Item"); - Assert.Equal("void Parent.this[ref readonly modreq(System.Runtime.InteropServices.InAttribute) System.Int32 p].set", explicitImplementation.ExplicitInterfaceImplementations.Single().ToTestDisplayString()); + Assert.Equal("void Parent.this[in modreq(System.Runtime.InteropServices.InAttribute) System.Int32 p].set", explicitImplementation.ExplicitInterfaceImplementations.Single().ToTestDisplayString()); var explicitParameter = explicitImplementation.Parameters.First(); Assert.Empty(explicitParameter.CustomModifiers); @@ -3320,7 +3320,7 @@ public void WhenImplementingParentWithModifiersCopyThem_Indexers_Parameters_Impl var reference = CreateStandardCompilation(@" public interface Parent { - int this[ref readonly int p] { set; } + int this[in int p] { set; } }"); CompileAndVerify(reference, symbolValidator: module => @@ -3335,7 +3335,7 @@ public interface Parent var code = @" public class Child : Parent { - public virtual int this[ref readonly int p] + public virtual int this[in int p] { set { System.Console.WriteLine(p); } } @@ -3368,7 +3368,7 @@ public void WhenImplementingParentWithModifiersCopyThem_Indexers_Parameters_Expl var reference = CreateStandardCompilation(@" public interface Parent { - int this[ref readonly int p] { set; } + int this[in int p] { set; } }"); CompileAndVerify(reference, symbolValidator: module => @@ -3383,7 +3383,7 @@ public interface Parent var code = @" public class Child : Parent { - int Parent.this[ref readonly int p] + int Parent.this[in int p] { set { System.Console.WriteLine(p); } } @@ -3643,7 +3643,7 @@ public static void Main() [Fact] public void CreatingLambdasOfDelegatesWithModifiersCanBeExecuted_Parameters() { - var reference = CreateStandardCompilation("public delegate void D(ref readonly int p);"); + var reference = CreateStandardCompilation("public delegate void D(in int p);"); CompileAndVerify(reference, symbolValidator: module => { @@ -3658,7 +3658,7 @@ public class Test { public static void Main() { - Run((ref readonly int p) => System.Console.WriteLine(p)); + Run((in int p) => System.Console.WriteLine(p)); } public static void Run(D lambda) diff --git a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IArgument.cs b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IArgument.cs index da25a4ec2314c..0b9e6818f22c8 100644 --- a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IArgument.cs +++ b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IArgument.cs @@ -2311,7 +2311,7 @@ static void M1() ref int refI = ref i; M2(/**/refI/**/); } - static void M2(ref readonly int i) { } + static void M2(in int i) { } } "; string expectedOperationTree = @" diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs index 0abd1d9906092..cb9437b583938 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs @@ -1330,13 +1330,13 @@ public void OverloadsWithDifferentParameterModifiers_Ref_RefReadOnly() abstract class TestClass { public void Method(ref int x) { } - public void Method(ref readonly int x) { } + public void Method(in int x) { } }"; var comp = CreateStandardCompilation(text).VerifyDiagnostics( - // (5,17): error CS0663: 'TestClass' cannot define an overloaded method that differs only on parameter modifiers 'ref readonly' and 'ref' - // public void Method(ref readonly int x) { } - Diagnostic(ErrorCode.ERR_OverloadRefKind, "Method").WithArguments("TestClass", "method", "ref readonly", "ref").WithLocation(5, 17)); + // (5,17): error CS0663: 'TestClass' cannot define an overloaded method that differs only on parameter modifiers 'in' and 'ref' + // public void Method(in int x) { } + Diagnostic(ErrorCode.ERR_OverloadRefKind, "Method").WithArguments("TestClass", "method", "in", "ref").WithLocation(5, 17)); } [Fact] @@ -1347,13 +1347,13 @@ public void OverloadsWithDifferentParameterModifiers_Out_RefReadOnly() abstract class TestClass { public void Method(out int x) { x = 0; } - public void Method(ref readonly int x) { } + public void Method(in int x) { } }"; var comp = CreateStandardCompilation(text).VerifyDiagnostics( - // (5,17): error CS0663: 'TestClass' cannot define an overloaded method that differs only on parameter modifiers 'ref readonly' and 'out' - // public void Method(ref readonly int x) { } - Diagnostic(ErrorCode.ERR_OverloadRefKind, "Method").WithArguments("TestClass", "method", "ref readonly", "out").WithLocation(5, 17)); + // (5,17): error CS0663: 'TestClass' cannot define an overloaded method that differs only on parameter modifiers 'in' and 'out' + // public void Method(in int x) { } + Diagnostic(ErrorCode.ERR_OverloadRefKind, "Method").WithArguments("TestClass", "method", "in", "out").WithLocation(5, 17)); } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs index 7a64be353844d..867cf5c42d541 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs @@ -1337,7 +1337,7 @@ public static void Main() { M(nameof(Main)); } - private static void M(ref readonly string value) + private static void M(in string value) { System.Console.WriteLine(value); } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs index 5fae13d8fffbb..41591ca93c95b 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs @@ -9320,7 +9320,7 @@ public void PassingArgumentsToRefReadOnlyParameters_RefKind_None() var code = @" public static class Program { - public static void Method(ref readonly int p) + public static void Method(in int p) { System.Console.WriteLine(p); } @@ -9340,7 +9340,7 @@ public void PassingArgumentsToRefReadOnlyParameters_RefKind_Ref() var code = @" public static class Program { - public static void Method(ref readonly int p) + public static void Method(in int p) { System.Console.WriteLine(p); } @@ -9364,7 +9364,7 @@ public void PassingArgumentsToRefReadOnlyParameters_RefKind_None_WrongType() var code = @" public static class Program { - public static void Method(ref readonly int p) + public static void Method(in int p) { System.Console.WriteLine(p); } @@ -9376,9 +9376,9 @@ public static void Main() }"; CreateStandardCompilation(code).VerifyDiagnostics( - // (11,16): error CS1503: Argument 1: cannot convert from 'System.Exception' to 'ref readonly int' + // (11,16): error CS1503: Argument 1: cannot convert from 'System.Exception' to 'in int' // Method(x); - Diagnostic(ErrorCode.ERR_BadArgType, "x").WithArguments("1", "System.Exception", "ref readonly int").WithLocation(11, 16) + Diagnostic(ErrorCode.ERR_BadArgType, "x").WithArguments("1", "System.Exception", "in int").WithLocation(11, 16) ); } @@ -9413,41 +9413,41 @@ public void PassingArgumentsToRefReadOnlyParameters_RefKind_RefReadOnly() var code = @" public static class Program { - public static void Method(ref readonly int p) + public static void Method(in int p) { System.Console.WriteLine(p); } public static void Main() { int x = 5; - Method(ref readonly x); + Method(in x); } }"; CreateStandardCompilation(code).VerifyDiagnostics( // (11,20): error CS1525: Invalid expression term 'readonly' - // Method(ref readonly x); + // Method(in x); Diagnostic(ErrorCode.ERR_InvalidExprTerm, "readonly").WithArguments("readonly").WithLocation(11, 20), // (11,20): error CS1026: ) expected - // Method(ref readonly x); + // Method(in x); Diagnostic(ErrorCode.ERR_CloseParenExpected, "readonly").WithLocation(11, 20), // (11,20): error CS1002: ; expected - // Method(ref readonly x); + // Method(in x); Diagnostic(ErrorCode.ERR_SemicolonExpected, "readonly").WithLocation(11, 20), // (11,20): error CS0106: The modifier 'readonly' is not valid for this item - // Method(ref readonly x); + // Method(in x); Diagnostic(ErrorCode.ERR_BadMemberFlag, "readonly").WithArguments("readonly").WithLocation(11, 20), // (11,30): error CS1001: Identifier expected - // Method(ref readonly x); + // Method(in x); Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(11, 30), // (11,30): error CS1002: ; expected - // Method(ref readonly x); + // Method(in x); Diagnostic(ErrorCode.ERR_SemicolonExpected, ")").WithLocation(11, 30), // (11,30): error CS1513: } expected - // Method(ref readonly x); + // Method(in x); Diagnostic(ErrorCode.ERR_RbraceExpected, ")").WithLocation(11, 30), // (11,29): error CS0118: 'x' is a variable but is used like a type - // Method(ref readonly x); + // Method(in x); Diagnostic(ErrorCode.ERR_BadSKknown, "x").WithArguments("x", "variable", "type").WithLocation(11, 29), // (10,13): warning CS0219: The variable 'x' is assigned but its value is never used // int x = 5; @@ -9460,7 +9460,7 @@ public void PassingArgumentsToRefReadOnlyParameters_RefKind_In() var code = @" public static class Program { - public static void Method(ref readonly int p) + public static void Method(in int p) { System.Console.WriteLine(p); } @@ -9483,7 +9483,7 @@ public void PassingArgumentsToRefReadOnlyParameters_RefKind_Out() var code = @" public static class Program { - public static void Method(ref readonly int p) + public static void Method(in int p) { System.Console.WriteLine(p); } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefEscapingTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefEscapingTests.cs index dbeefa50f40ea..9fef55ab0cd4f 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefEscapingTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefEscapingTests.cs @@ -234,7 +234,7 @@ static ref int Test1(S1 arg) return ref (new int[1])[0]; } - static S1 MayWrap(ref readonly Span arg) + static S1 MayWrap(in Span arg) { return default; } @@ -287,7 +287,7 @@ static ref int Test1(S1 arg) return ref (new int[1])[0]; } - static S1 MayNotWrap(ref readonly int arg = 123) + static S1 MayNotWrap(in int arg = 123) { return default; } @@ -1226,7 +1226,7 @@ void Test1() int dummy3 = this[inner, rOuter]; } - int this[ref readonly int arg1, ref readonly S1 arg2] + int this[in int arg1, in S1 arg2] { get { @@ -1236,7 +1236,7 @@ void Test1() } } - int this[ref readonly S1 arg1, ref readonly S1 arg2] + int this[in S1 arg1, in S1 arg2] { get { @@ -1293,7 +1293,7 @@ void Test1() int dummy4 = rOuter[inner]; } - static S1 MayWrap(ref readonly Span arg) + static S1 MayWrap(in Span arg) { return default; } @@ -1302,7 +1302,7 @@ ref struct S1 { public Span field; - public int this[ref readonly Span arg1] + public int this[in Span arg1] { get { @@ -1312,7 +1312,7 @@ public int this[ref readonly Span arg1] } } - public int this[ref readonly S1 arg1] + public int this[in S1 arg1] { get { @@ -1332,15 +1332,15 @@ public int this[ref readonly S1 arg1] // (24,29): error CS8526: Cannot use local 'rInner' in this context because it may expose referenced variables outside of their declaration scope // int dummy3 = rOuter[rInner]; Diagnostic(ErrorCode.ERR_EscapeLocal, "rInner").WithArguments("rInner").WithLocation(24, 29), - // (24,22): error CS8524: This combination of arguments to 'Program.S1.this[ref readonly Program.S1]' is disallowed because it may expose variables referenced by parameter 'arg1' outside of their declaration scope + // (24,22): error CS8524: This combination of arguments to 'Program.S1.this[in Program.S1]' is disallowed because it may expose variables referenced by parameter 'arg1' outside of their declaration scope // int dummy3 = rOuter[rInner]; - Diagnostic(ErrorCode.ERR_CallArgMixing, "rOuter[rInner]").WithArguments("Program.S1.this[ref readonly Program.S1]", "arg1").WithLocation(24, 22), + Diagnostic(ErrorCode.ERR_CallArgMixing, "rOuter[rInner]").WithArguments("Program.S1.this[in Program.S1]", "arg1").WithLocation(24, 22), // (27,29): error CS8526: Cannot use local 'inner' in this context because it may expose referenced variables outside of their declaration scope // int dummy4 = rOuter[inner]; Diagnostic(ErrorCode.ERR_EscapeLocal, "inner").WithArguments("inner").WithLocation(27, 29), - // (27,22): error CS8524: This combination of arguments to 'Program.S1.this[ref readonly Span]' is disallowed because it may expose variables referenced by parameter 'arg1' outside of their declaration scope + // (27,22): error CS8524: This combination of arguments to 'Program.S1.this[in Span]' is disallowed because it may expose variables referenced by parameter 'arg1' outside of their declaration scope // int dummy4 = rOuter[inner]; - Diagnostic(ErrorCode.ERR_CallArgMixing, "rOuter[inner]").WithArguments("Program.S1.this[ref readonly System.Span]", "arg1").WithLocation(27, 22) + Diagnostic(ErrorCode.ERR_CallArgMixing, "rOuter[inner]").WithArguments("Program.S1.this[in System.Span]", "arg1").WithLocation(27, 22) ); } @@ -1907,12 +1907,12 @@ void Test1() MayAssign(ref rInner); } - static void MayAssign(ref S1 arg1, ref readonly Span arg2 = default) + static void MayAssign(ref S1 arg1, in Span arg2 = default) { arg1 = MayWrap(arg2); } - static S1 MayWrap(ref readonly Span arg) + static S1 MayWrap(in Span arg) { return default; } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefExtensionMethodsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefExtensionMethodsTests.cs index 0683e195f3575..45bbd2226711b 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefExtensionMethodsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefExtensionMethodsTests.cs @@ -68,7 +68,7 @@ public void ExtensionMethods_RValues_RefReadOnly_Allowed() var code = @" public static class Extensions { - public static void PrintValue(ref readonly this int p) + public static void PrintValue(in this int p) { System.Console.Write(p); } @@ -91,7 +91,7 @@ public void ExtensionMethods_LValues_RefReadOnly_Allowed() var code = @" public static class Extensions { - public static void PrintValue(ref readonly this int p) + public static void PrintValue(in this int p) { System.Console.Write(p); } @@ -142,7 +142,7 @@ public struct TestType } public static class Extensions { - public static void Call(ref readonly this TestType obj) + public static void Call(in this TestType obj) { var value1 = obj?.GetValue(); // This should be an error var value2 = obj.GetValue(); // This should be OK @@ -706,7 +706,7 @@ public void RefReadOnlyExtensionMethodsReceiverTypes_ValueTypes_Allowed() var reference = CreateCompilationWithMscorlibAndSystemCore(@" public static class Extensions { - public static void PrintValue(ref readonly this int p) + public static void PrintValue(in this int p) { System.Console.Write(p); } @@ -744,7 +744,7 @@ public void RefReadOnlyExtensionMethodsReceiverTypes_ReferenceTypes_NotAllowed() var code = @" public static class Extensions { - public static void PrintValue(ref readonly this string p) + public static void PrintValue(in this string p) { System.Console.WriteLine(p); } @@ -761,7 +761,7 @@ public static void Main() var reference = CreateCompilationWithMscorlibAndSystemCore(code).VerifyDiagnostics( // (4,24): error CS8338: The first parameter of the readonly reference extension method 'PrintValue' must be a value type. - // public static void PrintValue(ref readonly this string p) + // public static void PrintValue(in this string p) Diagnostic(ErrorCode.ERR_RefReadOnlyExtensionMustBeValueType, "PrintValue").WithArguments("PrintValue").WithLocation(4, 24), // (14,11): error CS1061: 'string' does not contain a definition for 'PrintValue' and no extension method 'PrintValue' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) // x.PrintValue(); @@ -788,7 +788,7 @@ public void RefReadOnlyExtensionMethodsReceiverTypes_InterfaceTypes_NotAllowed() var code = @" public static class Extensions { - public static void PrintValue(ref readonly this System.IComparable p) + public static void PrintValue(in this System.IComparable p) { System.Console.WriteLine(p); } @@ -805,7 +805,7 @@ public static void Main() var reference = CreateCompilationWithMscorlibAndSystemCore(code).VerifyDiagnostics( // (4,24): error CS8338: The first parameter of the readonly reference extension method 'PrintValue' must be a value type. - // public static void PrintValue(ref readonly this System.IComparable p) + // public static void PrintValue(in this System.IComparable p) Diagnostic(ErrorCode.ERR_RefReadOnlyExtensionMustBeValueType, "PrintValue").WithArguments("PrintValue").WithLocation(4, 24), // (14,11): error CS1061: 'IComparable' does not contain a definition for 'PrintValue' and no extension method 'PrintValue' accepting a first argument of type 'IComparable' could be found (are you missing a using directive or an assembly reference?) // x.PrintValue(); @@ -832,7 +832,7 @@ public void RefReadOnlyExtensionMethodsReceiverTypes_UnconstrainedGenericTypes_N var code = @" public static class Extensions { - public static void PrintValue(ref readonly this T p) + public static void PrintValue(in this T p) { System.Console.WriteLine(p); } @@ -849,7 +849,7 @@ public static void Main() var reference = CreateCompilationWithMscorlibAndSystemCore(code).VerifyDiagnostics( // (4,24): error CS8338: The first parameter of the readonly reference extension method 'PrintValue' must be a value type. - // public static void PrintValue(ref readonly this T p) + // public static void PrintValue(in this T p) Diagnostic(ErrorCode.ERR_RefReadOnlyExtensionMustBeValueType, "PrintValue").WithArguments("PrintValue").WithLocation(4, 24), // (14,11): error CS1061: 'string' does not contain a definition for 'PrintValue' and no extension method 'PrintValue' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) // x.PrintValue(); @@ -876,7 +876,7 @@ public void RefReadOnlyExtensionMethodsReceiverTypes_StructConstrainedGenericTyp var code = @" public static class Extensions { - public static void PrintValue(ref readonly this T p) where T : struct + public static void PrintValue(in this T p) where T : struct { System.Console.WriteLine(p); } @@ -893,7 +893,7 @@ public static void Main() var reference = CreateCompilationWithMscorlibAndSystemCore(code).VerifyDiagnostics( // (4,24): error CS8338: The first parameter of the readonly reference extension method 'PrintValue' must be a value type. - // public static void PrintValue(ref readonly this T p) where T : struct + // public static void PrintValue(in this T p) where T : struct Diagnostic(ErrorCode.ERR_RefReadOnlyExtensionMustBeValueType, "PrintValue").WithArguments("PrintValue").WithLocation(4, 24), // (14,11): error CS1061: 'int' does not contain a definition for 'PrintValue' and no extension method 'PrintValue' accepting a first argument of type 'int' could be found (are you missing a using directive or an assembly reference?) // x.PrintValue(); @@ -920,7 +920,7 @@ public void RefReadOnlyExtensionMethodsReceiverTypes_ClassConstrainedGenericType var code = @" public static class Extensions { - public static void PrintValue(ref readonly this T p) where T : class + public static void PrintValue(in this T p) where T : class { System.Console.WriteLine(p); } @@ -937,7 +937,7 @@ public static void Main() var reference = CreateCompilationWithMscorlibAndSystemCore(code).VerifyDiagnostics( // (4,24): error CS8338: The first parameter of the readonly reference extension method 'PrintValue' must be a value type. - // public static void PrintValue(ref readonly this T p) where T : class + // public static void PrintValue(in this T p) where T : class Diagnostic(ErrorCode.ERR_RefReadOnlyExtensionMustBeValueType, "PrintValue").WithArguments("PrintValue").WithLocation(4, 24), // (14,11): error CS1061: 'string' does not contain a definition for 'PrintValue' and no extension method 'PrintValue' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) // x.PrintValue(); @@ -964,7 +964,7 @@ public void RefReadOnlyExtensionMethodsReceiverTypes_InterfaceConstrainedGeneric var code = @" public static class Extensions { - public static void PrintValue(ref readonly this T p) where T : System.IComparable + public static void PrintValue(in this T p) where T : System.IComparable { System.Console.WriteLine(p); } @@ -981,7 +981,7 @@ public static void Main() var reference = CreateCompilationWithMscorlibAndSystemCore(code).VerifyDiagnostics( // (4,24): error CS8338: The first parameter of the readonly reference extension method 'PrintValue' must be a value type. - // public static void PrintValue(ref readonly this T p) where T : System.IComparable + // public static void PrintValue(in this T p) where T : System.IComparable Diagnostic(ErrorCode.ERR_RefReadOnlyExtensionMustBeValueType, "PrintValue").WithArguments("PrintValue").WithLocation(4, 24), // (14,11): error CS1061: 'string' does not contain a definition for 'PrintValue' and no extension method 'PrintValue' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) // x.PrintValue(); @@ -1279,7 +1279,7 @@ public void RefReadOnlyErrorsArePropagatedThroughExtensionMethods() var code = @" public static class Extensions { - public static void Modify(ref readonly this int p) + public static void Modify(in this int p) { p++; } @@ -1294,9 +1294,9 @@ public static void Main() }"; CreateCompilationWithMscorlibAndSystemCore(code).VerifyDiagnostics( - // (6,9): error CS8408: Cannot assign to variable 'ref readonly int' because it is a readonly variable + // (6,9): error CS8408: Cannot assign to variable 'in int' because it is a readonly variable // p++; - Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "p").WithArguments("variable", "ref readonly int").WithLocation(6, 9)); + Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "p").WithArguments("variable", "in int").WithLocation(6, 9)); } [Fact] @@ -1363,7 +1363,7 @@ public void RefReadOnlyExtensionMethods_CodeGen() var code = @" public static class Extensions { - public static void Print(ref readonly this int x) + public static void Print(in this int x) { System.Console.Write(x); } @@ -1388,7 +1388,7 @@ .locals init (int V_0) //value IL_0000: ldc.i4.0 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: call ""void Extensions.Print(ref readonly int)"" + IL_0004: call ""void Extensions.Print(in int)"" IL_0009: ret }"); @@ -1438,7 +1438,7 @@ public void Conversions_Numeric_RefReadOnlyExtensionMethods_NotAllowed() var code = @" public static class Extensions { - public static void Print(ref readonly this long x) + public static void Print(in this long x) { System.Console.WriteLine(x); } @@ -1456,9 +1456,9 @@ public static void Main() }"; CreateCompilationWithMscorlibAndSystemCore(code).VerifyDiagnostics( - // (14,9): error CS1929: 'int' does not contain a definition for 'Print' and the best extension method overload 'Extensions.Print(ref readonly long)' requires a receiver of type 'ref readonly long' + // (14,9): error CS1929: 'int' does not contain a definition for 'Print' and the best extension method overload 'Extensions.Print(in long)' requires a receiver of type 'in long' // intValue.Print(); // Should be an error - Diagnostic(ErrorCode.ERR_BadInstanceArgType, "intValue").WithArguments("int", "Print", "Extensions.Print(ref readonly long)", "ref readonly long").WithLocation(14, 9)); + Diagnostic(ErrorCode.ERR_BadInstanceArgType, "intValue").WithArguments("int", "Print", "Extensions.Print(in long)", "in long").WithLocation(14, 9)); } [Fact] @@ -1500,7 +1500,7 @@ public void Conversion_Tuples_RefReadOnlyExtensionMethods_NotAllowed() var code = @" public static class Extensions { - public static void Print(ref readonly this (long, long) x) + public static void Print(in this (long, long) x) { System.Console.WriteLine(x); } @@ -1522,9 +1522,9 @@ public static void Main() }"; CreateCompilationWithMscorlibAndSystemCore(code, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }).VerifyDiagnostics( - // (16,9): error CS1929: '(int intValue1, int intValue2)' does not contain a definition for 'Print' and the best extension method overload 'Extensions.Print(ref readonly (long, long))' requires a receiver of type 'ref readonly (long, long)' + // (16,9): error CS1929: '(int intValue1, int intValue2)' does not contain a definition for 'Print' and the best extension method overload 'Extensions.Print(in (long, long))' requires a receiver of type 'in (long, long)' // intTuple.Print(); // Should be an error - Diagnostic(ErrorCode.ERR_BadInstanceArgType, "intTuple").WithArguments("(int intValue1, int intValue2)", "Print", "Extensions.Print(ref readonly (long, long))", "ref readonly (long, long)").WithLocation(16, 9)); + Diagnostic(ErrorCode.ERR_BadInstanceArgType, "intTuple").WithArguments("(int intValue1, int intValue2)", "Print", "Extensions.Print(in (long, long))", "in (long, long)").WithLocation(16, 9)); } [Fact] @@ -1567,7 +1567,7 @@ public void Conversions_Nullables_RefReadOnlyExtensionMethods_NotAllowed() var code = @" public static class Extensions { - public static void Print(ref readonly this int? x) + public static void Print(in this int? x) { System.Console.WriteLine(x.Value); } @@ -1587,12 +1587,12 @@ public static void Main() }"; CreateCompilationWithMscorlibAndSystemCore(code).VerifyDiagnostics( - // (13,9): error CS1929: 'int' does not contain a definition for 'Print' and the best extension method overload 'Extensions.Print(ref readonly int?)' requires a receiver of type 'ref readonly int?' + // (13,9): error CS1929: 'int' does not contain a definition for 'Print' and the best extension method overload 'Extensions.Print(in int?)' requires a receiver of type 'in int?' // 0.Print(); // Should be an error - Diagnostic(ErrorCode.ERR_BadInstanceArgType, "0").WithArguments("int", "Print", "Extensions.Print(ref readonly int?)", "ref readonly int?").WithLocation(13, 9), - // (16,9): error CS1929: 'int' does not contain a definition for 'Print' and the best extension method overload 'Extensions.Print(ref readonly int?)' requires a receiver of type 'ref readonly int?' + Diagnostic(ErrorCode.ERR_BadInstanceArgType, "0").WithArguments("int", "Print", "Extensions.Print(in int?)", "in int?").WithLocation(13, 9), + // (16,9): error CS1929: 'int' does not contain a definition for 'Print' and the best extension method overload 'Extensions.Print(in int?)' requires a receiver of type 'in int?' // intValue.Print(); // Should be an error - Diagnostic(ErrorCode.ERR_BadInstanceArgType, "intValue").WithArguments("int", "Print", "Extensions.Print(ref readonly int?)", "ref readonly int?").WithLocation(16, 9)); + Diagnostic(ErrorCode.ERR_BadInstanceArgType, "intValue").WithArguments("int", "Print", "Extensions.Print(in int?)", "in int?").WithLocation(16, 9)); } [Fact] @@ -1713,7 +1713,7 @@ public static void Static() } public static class Extensions { - public static void Extension(ref readonly this Color x) + public static void Extension(in this Color x) { System.Console.Write(""Extension""); } @@ -1810,7 +1810,7 @@ public void Mutate() } public static class Extensions { - public static void PrintValue(ref readonly this S1 obj, S1 other) + public static void PrintValue(in this S1 obj, S1 other) { if (other.i > 0) { @@ -1849,7 +1849,7 @@ public static void Print(ref this int p) } public static class Ext2 { - public static void Print(ref readonly this int p) + public static void Print(in this int p) { System.Console.WriteLine(p); } @@ -1864,9 +1864,9 @@ public static void Main() }"; CreateCompilationWithMscorlibAndSystemCore(code).VerifyDiagnostics( - // (20,11): error CS0121: The call is ambiguous between the following methods or properties: 'Ext1.Print(ref int)' and 'Ext2.Print(ref readonly int)' + // (20,11): error CS0121: The call is ambiguous between the following methods or properties: 'Ext1.Print(ref int)' and 'Ext2.Print(in int)' // 0.Print(); // Error - Diagnostic(ErrorCode.ERR_AmbigCall, "Print").WithArguments("Ext1.Print(ref int)", "Ext2.Print(ref readonly int)").WithLocation(20, 11)); + Diagnostic(ErrorCode.ERR_AmbigCall, "Print").WithArguments("Ext1.Print(ref int)", "Ext2.Print(in int)").WithLocation(20, 11)); } [Fact] @@ -1882,7 +1882,7 @@ public static void Print(ref this int p) } public static class Ext2 { - public static void Print(ref readonly this int p) + public static void Print(in this int p) { System.Console.WriteLine(p); } @@ -1900,9 +1900,9 @@ public static void Main() }"; CreateCompilationWithMscorlibAndSystemCore(code).VerifyDiagnostics( - // (21,15): error CS0121: The call is ambiguous between the following methods or properties: 'Ext1.Print(ref int)' and 'Ext2.Print(ref readonly int)' + // (21,15): error CS0121: The call is ambiguous between the following methods or properties: 'Ext1.Print(ref int)' and 'Ext2.Print(in int)' // value.Print(); // Error - Diagnostic(ErrorCode.ERR_AmbigCall, "Print").WithArguments("Ext1.Print(ref int)", "Ext2.Print(ref readonly int)").WithLocation(21, 15)); + Diagnostic(ErrorCode.ERR_AmbigCall, "Print").WithArguments("Ext1.Print(ref int)", "Ext2.Print(in int)").WithLocation(21, 15)); } [Fact] @@ -1911,7 +1911,7 @@ public void ReadOnlynessPreservedThroughMultipleCalls() var code = @" public static class Ext { - public static void ReadOnly(ref readonly int p) + public static void ReadOnly(in int p) { Ref(ref p); // Should be an error } @@ -1922,9 +1922,9 @@ public static void Ref(ref int p) }"; CreateCompilationWithMscorlibAndSystemCore(code).VerifyDiagnostics( - // (6,17): error CS8406: Cannot use variable 'ref readonly int' as a ref or out value because it is a readonly variable + // (6,17): error CS8406: Cannot use variable 'in int' as a ref or out value because it is a readonly variable // Ref(ref p); // Should be an error - Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "p").WithArguments("variable", "ref readonly int").WithLocation(6, 17)); + Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "p").WithArguments("variable", "in int").WithLocation(6, 17)); } [Fact] @@ -1952,7 +1952,7 @@ public void ParameterSymbolsRetrievedThroughSemanticModel_RefReadOnlyExtensionMe var code = @" public static class Ext { - public static void Method(ref readonly this int p) { } + public static void Method(in this int p) { } }"; var comp = CreateCompilationWithMscorlibAndSystemCore(code).VerifyDiagnostics(); @@ -2045,7 +2045,7 @@ public void UsingRefExtensionMethodsBeforeVersion7_2ProducesDiagnostics_RefReadO var code = @" public static class Ext { - public static void Print(ref readonly this int p) + public static void Print(in this int p) { System.Console.WriteLine(p); } @@ -2061,10 +2061,10 @@ public static void Main() CreateCompilationWithMscorlibAndSystemCore(code, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_1)).VerifyDiagnostics( // (4,30): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. - // public static void Print(ref readonly this int p) + // public static void Print(in this int p) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "ref").WithArguments("readonly references", "7.2").WithLocation(4, 30), // (4,30): error CS8302: Feature 'ref extension methods' is not available in C# 7.1. Please use language version 7.2 or greater. - // public static void Print(ref readonly this int p) + // public static void Print(in this int p) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "ref").WithArguments("ref extension methods", "7.2").WithLocation(4, 30), // (14,9): error CS8302: Feature 'ref extension methods' is not available in C# 7.1. Please use language version 7.2 or greater. // p.Print(); @@ -2080,7 +2080,7 @@ public void UsingRefExtensionMethodsBeforeVersion7_2ProducesDiagnostics_RefReadO var reference = CreateCompilationWithMscorlibAndSystemCore(@" public static class Ext { - public static void Print(ref readonly this int p) + public static void Print(in this int p) { System.Console.WriteLine(p); } @@ -2122,7 +2122,7 @@ public void UsingRefExtensionMethodsBeforeVersion7_2ProducesDiagnostics_InSyntax var code = @" public static class Ext { - public static void Print(ref readonly this int p) + public static void Print(in this int p) { System.Console.WriteLine(p); } @@ -2138,10 +2138,10 @@ public static void Main() CreateCompilationWithMscorlibAndSystemCore(code, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_1)).VerifyDiagnostics( // (4,30): error CS8302: Feature 'ref extension methods' is not available in C# 7.1. Please use language version 7.2 or greater. - // public static void Print(ref readonly this int p) + // public static void Print(in this int p) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "ref").WithArguments("ref extension methods", "7.2").WithLocation(4, 30), // (4,30): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. - // public static void Print(ref readonly this int p) + // public static void Print(in this int p) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "ref").WithArguments("readonly references", "7.2").WithLocation(4, 30), // (14,9): error CS8302: Feature 'ref extension methods' is not available in C# 7.1. Please use language version 7.2 or greater. // p.Print(); @@ -2157,7 +2157,7 @@ public void UsingRefExtensionMethodsBeforeVersion7_2ProducesDiagnostics_InSyntax var reference = CreateCompilationWithMscorlibAndSystemCore(@" public static class Ext { - public static void Print(ref readonly this int p) + public static void Print(in this int p) { System.Console.WriteLine(p); } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs index bb2273b1b1af9..3acc98bc0ef08 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs @@ -277,7 +277,7 @@ class C { void M() { - void L(ref int x, ref readonly int y) + void L(ref int x, in int y) { L(ref x, y); L(ref y, x); @@ -291,9 +291,9 @@ void L(ref int x, ref readonly int y) } }"); comp.VerifyDiagnostics( - // (9,19): error CS8329: Cannot use variable 'ref readonly int' as a ref or out value because it is a readonly variable + // (9,19): error CS8329: Cannot use variable 'in int' as a ref or out value because it is a readonly variable // L(ref y, x); - Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "y").WithArguments("variable", "ref readonly int").WithLocation(9, 19), + Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "y").WithArguments("variable", "in int").WithLocation(9, 19), // (10,26): error CS1615: Argument 2 may not be passed with the 'ref' keyword // L(ref x, ref x); Diagnostic(ErrorCode.ERR_BadArgExtraRef, "x").WithArguments("2", "ref").WithLocation(10, 26), @@ -2704,13 +2704,13 @@ public void RefReadOnlyInAsyncMethodDisallowed() using System.Threading.Tasks; class Test { - async Task Method(ref readonly int p) + async Task Method(in int p) { await Task.FromResult(0); } }").VerifyDiagnostics( // (5,40): error CS1988: Async methods cannot have ref or out parameters - // async Task Method(ref readonly int p) + // async Task Method(in int p) Diagnostic(ErrorCode.ERR_BadAsyncArgType, "p").WithLocation(5, 40)); } @@ -2721,7 +2721,7 @@ public void RefReadOnlyInIteratorMethodsDisallowed() using System.Collections.Generic; class Test { - IEnumerable Method(ref readonly int p) + IEnumerable Method(in int p) { yield return 0; yield return 1; @@ -2729,7 +2729,7 @@ IEnumerable Method(ref readonly int p) } }").VerifyDiagnostics( // (5,46): error CS1623: Iterators cannot have ref or out parameters - // IEnumerable Method(ref readonly int p) + // IEnumerable Method(in int p) Diagnostic(ErrorCode.ERR_BadIteratorArgType, "p").WithLocation(5, 46)); } @@ -2740,13 +2740,13 @@ public void RefReadOnlyInEnumeratorMethodsDisallowed() using System.Collections.Generic; class Test { - public IEnumerator GetEnumerator(ref readonly int p) + public IEnumerator GetEnumerator(in int p) { yield return 0; } }").VerifyDiagnostics( // (5,60): error CS1623: Iterators cannot have ref or out parameters - // public IEnumerator GetEnumerator(ref readonly int p) + // public IEnumerator GetEnumerator(in int p) Diagnostic(ErrorCode.ERR_BadIteratorArgType, "p").WithLocation(5, 60)); } @@ -2756,7 +2756,7 @@ public void CannotCallRefReadOnlyMethodsUsingDiscardParameter() CreateStandardCompilation(@" class Test { - void M(ref readonly int p) + void M(in int p) { } void N() diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SpanStackSafetyTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SpanStackSafetyTests.cs index 8f654a49f6941..9fe7185a7a957 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/SpanStackSafetyTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SpanStackSafetyTests.cs @@ -188,12 +188,12 @@ static void M2(out SpanLike ss) } // OK - static void M3(ref readonly Span ss) + static void M3(in Span ss) { } // OK - static void M3l(ref readonly SpanLike ss) + static void M3l(in SpanLike ss) { } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs index 7c0dadb31601b..4be79b2fa407d 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs @@ -8567,7 +8567,7 @@ public void CannotTakeAddressOfRefReadOnlyParameter() CreateStandardCompilation(@" public class Test { - unsafe void M(ref readonly int p) + unsafe void M(in int p) { int* pointer = &p; } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/VarianceTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/VarianceTests.cs index 5793ce918b456..f14d71c584832 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/VarianceTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/VarianceTests.cs @@ -634,11 +634,11 @@ public void CovarianceBoundariesForRefReadOnly_Parameters() CreateStandardCompilation(@" interface ITest { - void M(ref readonly T p); + void M(in T p); }").VerifyDiagnostics( - // (4,25): error CS1961: Invalid variance: The type parameter 'T' must be invariantly valid on 'ITest.M(ref readonly T)'. 'T' is contravariant. - // void M(ref readonly T p); - Diagnostic(ErrorCode.ERR_UnexpectedVariance, "T").WithArguments("ITest.M(ref readonly T)", "T", "contravariant", "invariantly").WithLocation(4, 25)); + // (4,25): error CS1961: Invalid variance: The type parameter 'T' must be invariantly valid on 'ITest.M(in T)'. 'T' is contravariant. + // void M(in T p); + Diagnostic(ErrorCode.ERR_UnexpectedVariance, "T").WithArguments("ITest.M(in T)", "T", "contravariant", "invariantly").WithLocation(4, 25)); } [Fact] diff --git a/src/Compilers/CSharp/Test/Symbol/SymbolDisplay/SymbolDisplayTests.cs b/src/Compilers/CSharp/Test/Symbol/SymbolDisplay/SymbolDisplayTests.cs index 618af8bf5578d..4771e4b030c26 100644 --- a/src/Compilers/CSharp/Test/Symbol/SymbolDisplay/SymbolDisplayTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/SymbolDisplay/SymbolDisplayTests.cs @@ -5531,10 +5531,10 @@ public void RefReadonlyReturn() @"public delegate ref readonly int D(); public class C { - public ref readonly int F(ref readonly int i) => ref i; + public ref readonly int F(in int i) => ref i; int _p; public ref readonly int P => ref _p; - public ref readonly int this[ref readonly int i] => ref _p; + public ref readonly int this[in int i] => ref _p; }"; var compA = CreateStandardCompilation(sourceA); compA.VerifyDiagnostics(); @@ -5556,10 +5556,10 @@ public void RefReadonlyReturn1() @"public delegate ref readonly int D(); public class C { - public ref readonly int F(ref readonly int i) => ref i; + public ref readonly int F(in int i) => ref i; int _p; public ref readonly int P => ref _p; - public ref readonly int this[ref readonly int i] => ref _p; + public ref readonly int this[in int i] => ref _p; }"; var compA = CreateStandardCompilation(sourceA); compA.VerifyDiagnostics(); @@ -5598,7 +5598,7 @@ private static void RefReadonlyReturnInternal(Compilation comp) // Method without IncludeRef. Verify( SymbolDisplay.ToDisplayParts(method, formatWithoutRef), - "int F(ref readonly int)", + "int F(in int)", SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Space, SymbolDisplayPartKind.MethodName, @@ -5606,8 +5606,6 @@ private static void RefReadonlyReturnInternal(Compilation comp) SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Space, SymbolDisplayPartKind.Keyword, - SymbolDisplayPartKind.Space, - SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Punctuation); // Property without IncludeRef. @@ -5628,7 +5626,7 @@ private static void RefReadonlyReturnInternal(Compilation comp) // Indexer without IncludeRef. Verify( SymbolDisplay.ToDisplayParts(indexer, formatWithoutRef), - "int this[ref readonly int] { get; }", + "int this[in int] { get; }", SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Space, SymbolDisplayPartKind.Keyword, @@ -5636,8 +5634,6 @@ private static void RefReadonlyReturnInternal(Compilation comp) SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Space, SymbolDisplayPartKind.Keyword, - SymbolDisplayPartKind.Space, - SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.Space, SymbolDisplayPartKind.Punctuation, @@ -5660,7 +5656,7 @@ private static void RefReadonlyReturnInternal(Compilation comp) // Method with IncludeRef. Verify( SymbolDisplay.ToDisplayParts(method, formatWithRef), - "ref readonly int F(ref readonly int)", + "ref readonly int F(in int)", SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Space, SymbolDisplayPartKind.Keyword, @@ -5672,8 +5668,6 @@ private static void RefReadonlyReturnInternal(Compilation comp) SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Space, SymbolDisplayPartKind.Keyword, - SymbolDisplayPartKind.Space, - SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Punctuation); // Property with IncludeRef. @@ -5698,9 +5692,7 @@ private static void RefReadonlyReturnInternal(Compilation comp) // Indexer with IncludeRef. Verify( SymbolDisplay.ToDisplayParts(indexer, formatWithRef), - "ref readonly int this[ref readonly int] { get; }", - SymbolDisplayPartKind.Keyword, - SymbolDisplayPartKind.Space, + "ref readonly int this[in int] { get; }", SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Space, SymbolDisplayPartKind.Keyword, @@ -5710,8 +5702,6 @@ private static void RefReadonlyReturnInternal(Compilation comp) SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Space, SymbolDisplayPartKind.Keyword, - SymbolDisplayPartKind.Space, - SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.Space, SymbolDisplayPartKind.Punctuation, @@ -5738,14 +5728,12 @@ private static void RefReadonlyReturnInternal(Compilation comp) // Method without IncludeType, with IncludeRef. Verify( SymbolDisplay.ToDisplayParts(method, formatWithoutTypeWithRef), - "F(ref readonly int)", + "F(in int)", SymbolDisplayPartKind.MethodName, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Space, SymbolDisplayPartKind.Keyword, - SymbolDisplayPartKind.Space, - SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Punctuation); } @@ -5923,7 +5911,7 @@ class C { void M() { - async unsafe Task Local(ref readonly int* x, out char? c) + async unsafe Task Local(in int* x, out char? c) { } } @@ -5939,7 +5927,7 @@ async unsafe Task Local(ref readonly int* x, out char? c) semanticModel.GetDeclaredSymbol(local)); Verify(localSymbol.ToDisplayParts(SymbolDisplayFormat.TestFormat), - "System.Threading.Tasks.Task Local(ref readonly System.Int32* x, out System.Char? c)", + "System.Threading.Tasks.Task Local(in System.Int32* x, out System.Char? c)", SymbolDisplayPartKind.NamespaceName, // System SymbolDisplayPartKind.Punctuation, // . SymbolDisplayPartKind.NamespaceName, // Threading diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/InterfaceOverriddenOrHiddenMembersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/InterfaceOverriddenOrHiddenMembersTests.cs index 4fe51c9406247..074cc1b0f7e03 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/InterfaceOverriddenOrHiddenMembersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/InterfaceOverriddenOrHiddenMembersTests.cs @@ -827,17 +827,17 @@ public void HidingMethodWithRefReadOnlyParameter() var code = @" interface A { - void M(ref readonly int x); + void M(in int x); } interface B : A { - void M(ref readonly int x); + void M(in int x); }"; var comp = CreateStandardCompilation(code).VerifyDiagnostics( - // (8,10): warning CS0108: 'B.M(ref readonly int)' hides inherited member 'A.M(ref readonly int)'. Use the new keyword if hiding was intended. - // void M(ref readonly int x); - Diagnostic(ErrorCode.WRN_NewRequired, "M").WithArguments("B.M(ref readonly int)", "A.M(ref readonly int)").WithLocation(8, 10)); + // (8,10): warning CS0108: 'B.M(in int)' hides inherited member 'A.M(in int)'. Use the new keyword if hiding was intended. + // void M(in int x); + Diagnostic(ErrorCode.WRN_NewRequired, "M").WithArguments("B.M(in int)", "A.M(in int)").WithLocation(8, 10)); var aMethod = comp.GetMember("A.M"); var bMethod = comp.GetMember("B.M"); @@ -1030,11 +1030,11 @@ public void HidingMethodWithRefReadOnlyParameterAndNewKeyword() var code = @" interface A { - void M(ref readonly int x); + void M(in int x); } interface B : A { - new void M(ref readonly int x); + new void M(in int x); }"; var comp = CreateStandardCompilation(code).VerifyDiagnostics(); @@ -1108,11 +1108,11 @@ public void ImplementingMethodWithRefReadOnlyParameter() var code = @" interface A { - void M(ref readonly int x); + void M(in int x); } class B : A { - public void M(ref readonly int x) { } + public void M(in int x) { } }"; var comp = CreateStandardCompilation(code).VerifyDiagnostics(); @@ -1161,7 +1161,7 @@ public void ImplementingMethodWithDifferentParameterRefness() var code = @" interface A { - void M(ref readonly int x); + void M(in int x); } class B : A { @@ -1169,9 +1169,9 @@ public void M(ref int x) { } }"; var comp = CreateStandardCompilation(code).VerifyDiagnostics( - // (6,11): error CS0535: 'B' does not implement interface member 'A.M(ref readonly int)' + // (6,11): error CS0535: 'B' does not implement interface member 'A.M(in int)' // class B : A - Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "A").WithArguments("B", "A.M(ref readonly int)").WithLocation(6, 11)); + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "A").WithArguments("B", "A.M(in int)").WithLocation(6, 11)); } [Fact] @@ -1181,7 +1181,7 @@ public void ImplementingRefReadOnlyMembersWillOverwriteTheCorrectSlot() var text = @" interface BaseInterface { - ref readonly int Method1(ref readonly int a); + ref readonly int Method1(in int a); ref readonly int Property1 { get; } ref readonly int this[int a] { get; } } @@ -1189,7 +1189,7 @@ interface BaseInterface class DerivedClass : BaseInterface { protected int field; - public ref readonly int Method1(ref readonly int a) { return ref field; } + public ref readonly int Method1(in int a) { return ref field; } public ref readonly int Property1 { get { return ref field; } } public ref readonly int this[int a] { get { return ref field; } } }"; @@ -1205,18 +1205,18 @@ public void MethodImplementationsShouldPreserveReadOnlyRefnessInParameters() interface BaseInterface { void Method1(ref int x); - void Method2(ref readonly int x); + void Method2(in int x); } class ChildClass : BaseInterface { - public void Method1(ref readonly int x) { } + public void Method1(in int x) { } public void Method2(ref int x) { } }"; var comp = CreateStandardCompilation(text).VerifyDiagnostics( - // (7,20): error CS0535: 'ChildClass' does not implement interface member 'BaseInterface.Method2(ref readonly int)' + // (7,20): error CS0535: 'ChildClass' does not implement interface member 'BaseInterface.Method2(in int)' // class ChildClass : BaseInterface - Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "BaseInterface").WithArguments("ChildClass", "BaseInterface.Method2(ref readonly int)").WithLocation(7, 20), + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "BaseInterface").WithArguments("ChildClass", "BaseInterface.Method2(in int)").WithLocation(7, 20), // (7,20): error CS0535: 'ChildClass' does not implement interface member 'BaseInterface.Method1(ref int)' // class ChildClass : BaseInterface Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "BaseInterface").WithArguments("ChildClass", "BaseInterface.Method1(ref int)").WithLocation(7, 20)); @@ -1323,11 +1323,11 @@ public void IndexerImplementationsShouldPreserveReadOnlyRefnessInIndexes_Valid() var code = @" interface A { - int this[ref readonly int p] { get; } + int this[in int p] { get; } } class B : A { - public int this[ref readonly int p] { get { return p; } } + public int this[in int p] { get { return p; } } }"; var comp = CreateStandardCompilation(code).VerifyDiagnostics(); @@ -1340,7 +1340,7 @@ public void IndexerImplementationsShouldPreserveReadOnlyRefnessInIndexes_Source( var code = @" interface A { - int this[ref readonly int p] { get; } + int this[in int p] { get; } } class B : A { @@ -1348,9 +1348,9 @@ class B : A }"; var comp = CreateStandardCompilation(code).VerifyDiagnostics( - // (6,11): error CS0535: 'B' does not implement interface member 'A.this[ref readonly int]' + // (6,11): error CS0535: 'B' does not implement interface member 'A.this[in int]' // class B : A - Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "A").WithArguments("B", "A.this[ref readonly int]").WithLocation(6, 11)); + Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "A").WithArguments("B", "A.this[in int]").WithLocation(6, 11)); } [Fact] @@ -1364,7 +1364,7 @@ interface A } class B : A { - public int this[ref readonly int p] { get { return p; } } + public int this[in int p] { get { return p; } } }"; var comp = CreateStandardCompilation(code).VerifyDiagnostics( diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/OverriddenOrHiddenMembersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/OverriddenOrHiddenMembersTests.cs index 8523a80172f37..361cb7cece4c7 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/OverriddenOrHiddenMembersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/OverriddenOrHiddenMembersTests.cs @@ -3992,17 +3992,17 @@ public void HidingMethodWithRefReadOnlyParameter() var code = @" class A { - public void M(ref readonly int x) { } + public void M(in int x) { } } class B : A { - public void M(ref readonly int x) { } + public void M(in int x) { } }"; var comp = CreateStandardCompilation(code).VerifyDiagnostics( - // (8,17): warning CS0108: 'B.M(ref readonly int)' hides inherited member 'A.M(ref readonly int)'. Use the new keyword if hiding was intended. - // public void M(ref readonly int x) { } - Diagnostic(ErrorCode.WRN_NewRequired, "M").WithArguments("B.M(ref readonly int)", "A.M(ref readonly int)").WithLocation(8, 17)); + // (8,17): warning CS0108: 'B.M(in int)' hides inherited member 'A.M(in int)'. Use the new keyword if hiding was intended. + // public void M(in int x) { } + Diagnostic(ErrorCode.WRN_NewRequired, "M").WithArguments("B.M(in int)", "A.M(in int)").WithLocation(8, 17)); var aMethod = comp.GetMember("A.M"); var bMethod = comp.GetMember("B.M"); @@ -4201,11 +4201,11 @@ public void HidingMethodWithRefReadOnlyParameterAndNewKeyword() var code = @" class A { - public void M(ref readonly int x) { } + public void M(in int x) { } } class B : A { - public new void M(ref readonly int x) { } + public new void M(in int x) { } }"; var comp = CreateStandardCompilation(code).VerifyDiagnostics(); @@ -4281,11 +4281,11 @@ public void OverridingMethodWithRefReadOnlyParameter() var code = @" class A { - public virtual void M(ref readonly int x) { } + public virtual void M(in int x) { } } class B : A { - public override void M(ref readonly int x) { } + public override void M(in int x) { } }"; var comp = CreateStandardCompilation(code).VerifyDiagnostics(); @@ -4361,7 +4361,7 @@ public void DeclaringMethodWithDifferentParameterRefness() var code = @" class A { - public void M(ref readonly int x) { } + public void M(in int x) { } } class B : A { @@ -4390,14 +4390,14 @@ public void OverriddingRefReadOnlyMembersWillOverwriteTheCorrectSlot() class BaseClass { protected int field; - public virtual ref readonly int Method1(ref readonly BaseClass a) { return ref field; } + public virtual ref readonly int Method1(in BaseClass a) { return ref field; } public virtual ref readonly int Property1 { get { return ref field; } } public virtual ref readonly int this[int a] { get { return ref field; } } } class DerivedClass : BaseClass { - public override ref readonly int Method1(ref readonly BaseClass a) { return ref field; } + public override ref readonly int Method1(in BaseClass a) { return ref field; } public override ref readonly int Property1 { get { return ref field; } } public override ref readonly int this[int a] { get { return ref field; } } }"; @@ -4439,11 +4439,11 @@ public void MethodOverloadsShouldPreserveReadOnlyRefnessInParameters() abstract class BaseClass { public virtual void Method1(ref int x) { } - public virtual void Method2(ref readonly int x) { } + public virtual void Method2(in int x) { } } class ChildClass : BaseClass { - public override void Method1(ref readonly int x) { } + public override void Method1(in int x) { } public override void Method2(ref int x) { } }"; @@ -4451,9 +4451,9 @@ public override void Method2(ref int x) { } // (10,26): error CS0115: 'ChildClass.Method2(ref int)': no suitable method found to override // public override void Method2(ref int x) { } Diagnostic(ErrorCode.ERR_OverrideNotExpected, "Method2").WithArguments("ChildClass.Method2(ref int)").WithLocation(10, 26), - // (9,26): error CS0115: 'ChildClass.Method1(ref readonly int)': no suitable method found to override - // public override void Method1(ref readonly int x) { } - Diagnostic(ErrorCode.ERR_OverrideNotExpected, "Method1").WithArguments("ChildClass.Method1(ref readonly int)").WithLocation(9, 26)); + // (9,26): error CS0115: 'ChildClass.Method1(in int)': no suitable method found to override + // public override void Method1(in int x) { } + Diagnostic(ErrorCode.ERR_OverrideNotExpected, "Method1").WithArguments("ChildClass.Method1(in int)").WithLocation(9, 26)); } [Fact] @@ -4478,7 +4478,7 @@ class ChildClass : BaseClass // public override ref int Method2() { return ref x; } Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method2").WithArguments("ChildClass.Method2()", "BaseClass.Method2()").WithLocation(11, 29), // (10,38): error CS8148: 'ChildClass.Method1()' must match by reference return of overridden member 'BaseClass.Method1()' - // public override ref readonly int Method1() { return ref x; } + // public override in int Method1() { return ref x; } Diagnostic(ErrorCode.ERR_CantChangeRefReturnOnOverride, "Method1").WithArguments("ChildClass.Method1()", "BaseClass.Method1()").WithLocation(10, 38)); } @@ -4557,11 +4557,11 @@ public void IndexerOverloadsShouldPreserveReadOnlyRefnessInIndexes_Valid() var code = @" abstract class A { - public abstract int this[ref readonly int p] { get; } + public abstract int this[in int p] { get; } } class B : A { - public override int this[ref readonly int p] { get { return p; } } + public override int this[in int p] { get { return p; } } }"; var comp = CreateStandardCompilation(code).VerifyDiagnostics(); @@ -4574,7 +4574,7 @@ public void IndexerOverloadsShouldPreserveReadOnlyRefnessInIndexes_Source() var code = @" abstract class A { - public abstract int this[ref readonly int p] { get; } + public abstract int this[in int p] { get; } } class B : A { @@ -4585,9 +4585,9 @@ class B : A // (8,25): error CS0115: 'B.this[int]': no suitable method found to override // public override int this[int p] { get { return p; } } Diagnostic(ErrorCode.ERR_OverrideNotExpected, "this").WithArguments("B.this[int]").WithLocation(8, 25), - // (6,7): error CS0534: 'B' does not implement inherited abstract member 'A.this[ref readonly int].get' + // (6,7): error CS0534: 'B' does not implement inherited abstract member 'A.this[in int].get' // class B : A - Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "B").WithArguments("B", "A.this[ref readonly int].get").WithLocation(6, 7)); + Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "B").WithArguments("B", "A.this[in int].get").WithLocation(6, 7)); } [Fact] @@ -4601,13 +4601,13 @@ abstract class A } class B : A { - public override int this[ref readonly int p] { get { return p; } } + public override int this[in int p] { get { return p; } } }"; var comp = CreateStandardCompilation(code).VerifyDiagnostics( - // (8,25): error CS0115: 'B.this[ref readonly int]': no suitable method found to override - // public override int this[ref readonly int p] { get { return p; } } - Diagnostic(ErrorCode.ERR_OverrideNotExpected, "this").WithArguments("B.this[ref readonly int]").WithLocation(8, 25), + // (8,25): error CS0115: 'B.this[in int]': no suitable method found to override + // public override int this[in int p] { get { return p; } } + Diagnostic(ErrorCode.ERR_OverrideNotExpected, "this").WithArguments("B.this[in int]").WithLocation(8, 25), // (6,7): error CS0534: 'B' does not implement inherited abstract member 'A.this[int].get' // class B : A Diagnostic(ErrorCode.ERR_UnimplementedAbstractMethod, "B").WithArguments("B", "A.this[int].get").WithLocation(6, 7)); diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/DelegateTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/DelegateTests.cs index 1707c95f4a5e8..24b3efb59ad53 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/DelegateTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/DelegateTests.cs @@ -738,7 +738,7 @@ public void RefReturningDelegate() [CompilerTrait(CompilerFeature.ReadOnlyReferences)] public void RefReadonlyReturningDelegate() { - var source = @"delegate ref readonly int D(ref readonly int arg);"; + var source = @"delegate ref readonly int D(in int arg);"; var comp = CreateCompilationWithMscorlib45(source); comp.VerifyDiagnostics(); @@ -760,13 +760,13 @@ public void RefReadonlysInlambda() var source = @" class C { - public delegate ref readonly T DD(ref readonly T arg); + public delegate ref readonly T DD(in T arg); public static void Main() { - DD d1 = (ref readonly int a) => ref a; + DD d1 = (in int a) => ref a; - DD d2 = delegate(ref readonly int a){return ref a;}; + DD d2 = delegate(in int a){return ref a;}; } }"; var tree = SyntaxFactory.ParseSyntaxTree(source, options: TestOptions.Regular); diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/ExpressionBodiedPropertyTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/ExpressionBodiedPropertyTests.cs index 9a99242b183a9..54d5e344f1918 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/ExpressionBodiedPropertyTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/ExpressionBodiedPropertyTests.cs @@ -541,7 +541,7 @@ public void RefReadonlyReturningExpressionBodiedIndexer() class C { int field = 0; - public ref readonly int this[ref readonly int arg] => ref field; + public ref readonly int this[in int arg] => ref field; }"); comp.VerifyDiagnostics(); @@ -569,7 +569,7 @@ public void RefReadonlyReturningExpressionBodiedIndexer1() class C { int field = 0; - public ref readonly int this[ref readonly int arg] => ref field; + public ref readonly int this[in int arg] => ref field; }"); comp.VerifyDiagnostics(); diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs index a5162d86f92d3..e00f739d2a6ba 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs @@ -3154,12 +3154,12 @@ public void RefReadOnlyParametersWouldErrorOutInEarlierCSharpVersions() var code = @" public class Test { - public void DoSomething(ref readonly int x) { } + public void DoSomething(in int x) { } }"; ParseAndValidate(code, new CSharpParseOptions(LanguageVersion.CSharp7), // (4,29): error CS8107: Feature 'readonly references' is not available in C# 7. Please use language version 7.2 or greater. - // public void DoSomething(ref readonly int x) { } + // public void DoSomething(in int x) { } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "ref").WithArguments("readonly references", "7.2").WithLocation(4, 29) ); } @@ -3427,16 +3427,16 @@ public static void Test1(ref ref int i) {} public static void Test2(out out int i) {} public static void Test3(this this int i) {} public static void Test4(params params int[] i) {} - public static void Test5(ref readonly ref readonly int[] i) {} + public static void Test5(in in int[] i) {} } "; CreateCompilationWithMscorlibAndSystemCore(test).GetDeclarationDiagnostics().Verify( // (8,43): error CS1107: A parameter can only have one 'ref' modifier - // public static void Test5(ref readonly ref readonly int[] i) {} + // public static void Test5(in in int[] i) {} Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(8, 43), // (8,47): error CS1107: A parameter can only have one 'readonly' modifier - // public static void Test6(ref readonly ref readonly int[] i) {} + // public static void Test6(in in int[] i) {} Diagnostic(ErrorCode.ERR_DupParamMod, "readonly").WithArguments("readonly").WithLocation(8, 47), // (5,34): error CS1107: A parameter can only have one 'out' modifier // public static void Test2(out out int i) {} @@ -3460,37 +3460,37 @@ public void BadRefReadOnlyWithRefParameterModifiers() public class TestType { // No type parameters -public static void Method1(ref readonly ref int i) { } -public static void Method2(ref ref readonly int i) { } +public static void Method1(in ref int i) { } +public static void Method2(ref in int i) { } // Single type parameters -public static void Method3(ref readonly ref int i) { } -public static void Method4(ref ref readonly int i) { } +public static void Method3(in ref int i) { } +public static void Method4(ref in int i) { } // Multiple type parameters -public static void Method5(ref readonly ref int i) { } -public static void Method6(ref ref readonly int i) { } +public static void Method5(in ref int i) { } +public static void Method6(ref in int i) { } } "; CreateCompilationWithMscorlibAndSystemCore(test).GetDeclarationDiagnostics().Verify( // (5,41): error CS1107: A parameter can only have one 'ref' modifier - // public static void Method1(ref readonly ref int i) { } + // public static void Method1(in ref int i) { } Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(5, 41), // (6,32): error CS1107: A parameter can only have one 'ref' modifier - // public static void Method2(ref ref readonly int i) { } + // public static void Method2(ref in int i) { } Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(6, 32), // (9,44): error CS1107: A parameter can only have one 'ref' modifier - // public static void Method3(ref readonly ref int i) { } + // public static void Method3(in ref int i) { } Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(9, 44), // (10,35): error CS1107: A parameter can only have one 'ref' modifier - // public static void Method4(ref ref readonly int i) { } + // public static void Method4(ref in int i) { } Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(10, 35), // (13,50): error CS1107: A parameter can only have one 'ref' modifier - // public static void Method5(ref readonly ref int i) { } + // public static void Method5(in ref int i) { } Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(13, 50), // (14,41): error CS1107: A parameter can only have one 'ref' modifier - // public static void Method6(ref ref readonly int i) { } + // public static void Method6(ref in int i) { } Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(14, 41)); } @@ -3502,37 +3502,37 @@ public void BadRefReadOnlyWithThisParameterModifiers() public static class TestType { // No type parameters -public static void Method1(ref readonly this int i) { } -public static void Method2(this ref readonly int i) { } +public static void Method1(in this int i) { } +public static void Method2(this in int i) { } // Single type parameters -public static void Method3(ref readonly this int i) { } -public static void Method4(this ref readonly int i) { } +public static void Method3(in this int i) { } +public static void Method4(this in int i) { } // Multiple type parameters -public static void Method5(ref readonly this int i) { } -public static void Method6(this ref readonly int i) { } +public static void Method5(in this int i) { } +public static void Method6(this in int i) { } } "; CreateCompilationWithMscorlibAndSystemCore(test).GetDeclarationDiagnostics().Verify( // (14,42): error CS8339: The parameter modifier 'ref' cannot be used after the modifier 'this' - // public static void Method6(this ref readonly int i) { } + // public static void Method6(this in int i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "ref").WithArguments("ref", "this").WithLocation(14, 42), // (14,46): error CS8339: The parameter modifier 'readonly' cannot be used after the modifier 'this' - // public static void Method6(this ref readonly int i) { } + // public static void Method6(this in int i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "readonly").WithArguments("readonly", "this").WithLocation(14, 46), // (6,33): error CS8339: The parameter modifier 'ref' cannot be used after the modifier 'this' - // public static void Method2(this ref readonly int i) { } + // public static void Method2(this in int i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "ref").WithArguments("ref", "this").WithLocation(6, 33), // (6,37): error CS8339: The parameter modifier 'readonly' cannot be used after the modifier 'this' - // public static void Method2(this ref readonly int i) { } + // public static void Method2(this in int i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "readonly").WithArguments("readonly", "this").WithLocation(6, 37), // (10,36): error CS8339: The parameter modifier 'ref' cannot be used after the modifier 'this' - // public static void Method4(this ref readonly int i) { } + // public static void Method4(this in int i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "ref").WithArguments("ref", "this").WithLocation(10, 36), // (10,40): error CS8339: The parameter modifier 'readonly' cannot be used after the modifier 'this' - // public static void Method4(this ref readonly int i) { } + // public static void Method4(this in int i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "readonly").WithArguments("readonly", "this").WithLocation(10, 40)); } @@ -3544,46 +3544,46 @@ public void BadRefReadOnlyWithParamsParameterModifiers() public class TestType { // No type parameters -public static void Method1(ref readonly params int[] i) { } -public static void Method2(params ref readonly int[] i) { } +public static void Method1(in params int[] i) { } +public static void Method2(params in int[] i) { } // Single type parameters -public static void Method3(ref readonly params int[] i) { } -public static void Method4(params ref readonly int[] i) { } +public static void Method3(in params int[] i) { } +public static void Method4(params in int[] i) { } // Multiple type parameters -public static void Method5(ref readonly params int[] i) { } -public static void Method6(params ref readonly int[] i) { } +public static void Method5(in params int[] i) { } +public static void Method6(params in int[] i) { } } "; CreateCompilationWithMscorlibAndSystemCore(test).GetDeclarationDiagnostics().Verify( // (6,35): error CS1611: The params parameter cannot be declared as ref - // public static void Method2(params ref readonly int[] i) { } + // public static void Method2(params in int[] i) { } Diagnostic(ErrorCode.ERR_ParamsCantBeWithModifier, "ref").WithArguments("ref").WithLocation(6, 35), // (6,39): error CS1611: The params parameter cannot be declared as readonly - // public static void Method2(params ref readonly int[] i) { } + // public static void Method2(params in int[] i) { } Diagnostic(ErrorCode.ERR_ParamsCantBeWithModifier, "readonly").WithArguments("readonly").WithLocation(6, 39), // (9,44): error CS8328: The parameter modifier 'params' cannot be used with 'ref' - // public static void Method3(ref readonly params int[] i) { } + // public static void Method3(in params int[] i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiers, "params").WithArguments("params", "ref").WithLocation(9, 44), // (10,38): error CS1611: The params parameter cannot be declared as ref - // public static void Method4(params ref readonly int[] i) { } + // public static void Method4(params in int[] i) { } Diagnostic(ErrorCode.ERR_ParamsCantBeWithModifier, "ref").WithArguments("ref").WithLocation(10, 38), // (10,42): error CS1611: The params parameter cannot be declared as readonly - // public static void Method4(params ref readonly int[] i) { } + // public static void Method4(params in int[] i) { } Diagnostic(ErrorCode.ERR_ParamsCantBeWithModifier, "readonly").WithArguments("readonly").WithLocation(10, 42), // (13,50): error CS8328: The parameter modifier 'params' cannot be used with 'ref' - // public static void Method5(ref readonly params int[] i) { } + // public static void Method5(in params int[] i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiers, "params").WithArguments("params", "ref").WithLocation(13, 50), // (14,44): error CS1611: The params parameter cannot be declared as ref - // public static void Method6(params ref readonly int[] i) { } + // public static void Method6(params in int[] i) { } Diagnostic(ErrorCode.ERR_ParamsCantBeWithModifier, "ref").WithArguments("ref").WithLocation(14, 44), // (14,48): error CS1611: The params parameter cannot be declared as readonly - // public static void Method6(params ref readonly int[] i) { } + // public static void Method6(params in int[] i) { } Diagnostic(ErrorCode.ERR_ParamsCantBeWithModifier, "readonly").WithArguments("readonly").WithLocation(14, 48), // (5,41): error CS8328: The parameter modifier 'params' cannot be used with 'ref' - // public static void Method1(ref readonly params int[] i) { } + // public static void Method1(in params int[] i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiers, "params").WithArguments("params", "ref").WithLocation(5, 41)); } @@ -3595,46 +3595,46 @@ public void BadRefReadOnlyWithOutParameterModifiers() public class TestType { // No type parameters -public static void Method1(ref readonly out int i) { } -public static void Method2(out ref readonly int i) { } +public static void Method1(in out int i) { } +public static void Method2(out in int i) { } // Single type parameters -public static void Method3(ref readonly out int i) { } -public static void Method4(out ref readonly int i) { } +public static void Method3(in out int i) { } +public static void Method4(out in int i) { } // Multiple type parameters -public static void Method5(ref readonly out int i) { } -public static void Method6(out ref readonly int i) { } +public static void Method5(in out int i) { } +public static void Method6(out in int i) { } } "; CreateCompilationWithMscorlibAndSystemCore(test).GetDeclarationDiagnostics().Verify( // (5,41): error CS8328: The parameter modifier 'out' cannot be used with 'ref' - // public static void Method1(ref readonly out int i) { } + // public static void Method1(in out int i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiers, "out").WithArguments("out", "ref").WithLocation(5, 41), // (6,32): error CS8328: The parameter modifier 'ref' cannot be used with 'out' - // public static void Method2(out ref readonly int i) { } + // public static void Method2(out in int i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiers, "ref").WithArguments("ref", "out").WithLocation(6, 32), // (6,36): error CS8328: The parameter modifier 'readonly' cannot be used with 'out' - // public static void Method2(out ref readonly int i) { } + // public static void Method2(out in int i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiers, "readonly").WithArguments("readonly", "out").WithLocation(6, 36), // (9,44): error CS8328: The parameter modifier 'out' cannot be used with 'ref' - // public static void Method3(ref readonly out int i) { } + // public static void Method3(in out int i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiers, "out").WithArguments("out", "ref").WithLocation(9, 44), // (10,35): error CS8328: The parameter modifier 'ref' cannot be used with 'out' - // public static void Method4(out ref readonly int i) { } + // public static void Method4(out in int i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiers, "ref").WithArguments("ref", "out").WithLocation(10, 35), // (10,39): error CS8328: The parameter modifier 'readonly' cannot be used with 'out' - // public static void Method4(out ref readonly int i) { } + // public static void Method4(out in int i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiers, "readonly").WithArguments("readonly", "out").WithLocation(10, 39), // (13,50): error CS8328: The parameter modifier 'out' cannot be used with 'ref' - // public static void Method5(ref readonly out int i) { } + // public static void Method5(in out int i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiers, "out").WithArguments("out", "ref").WithLocation(13, 50), // (14,41): error CS8328: The parameter modifier 'ref' cannot be used with 'out' - // public static void Method6(out ref readonly int i) { } + // public static void Method6(out in int i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiers, "ref").WithArguments("ref", "out").WithLocation(14, 41), // (14,45): error CS8328: The parameter modifier 'readonly' cannot be used with 'out' - // public static void Method6(out ref readonly int i) { } + // public static void Method6(out in int i) { } Diagnostic(ErrorCode.ERR_BadParameterModifiers, "readonly").WithArguments("readonly", "out").WithLocation(14, 45)); } @@ -3645,23 +3645,23 @@ public void RefReadonlyParametersAreParsedCorrectly() var test = @" public class Test { - public delegate int Delegate(ref readonly int a); + public delegate int Delegate(in int a); - public void Method(ref readonly int b) + public void Method(in int b) { - void localFunc(ref readonly int c) { } + void localFunc(in int c) { } - Delegate lambda = (ref readonly int d) => d; + Delegate lambda = (in int d) => d; - Delegate anonymousDelegate = delegate (ref readonly int e) { return e; }; + Delegate anonymousDelegate = delegate (in int e) { return e; }; } - public int this [ref readonly int f] + public int this [in int f] { get { return f; } } - public static bool operator ! (ref readonly Test g) + public static bool operator ! (in Test g) { return false; } @@ -5601,7 +5601,7 @@ public void RefExtensionMethodsNotSupportedBefore7_2_RefReadOnlySyntax() var code = @" public static class Extensions { - public static void Print(ref readonly this int p) + public static void Print(in this int p) { System.Console.WriteLine(p); } @@ -5617,10 +5617,10 @@ public static void Main() CreateCompilationWithMscorlibAndSystemCore(code, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_1)).GetParseDiagnostics().Verify( // (4,30): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. - // public static void Print(ref readonly this int p) + // public static void Print(in this int p) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "ref").WithArguments("readonly references", "7.2").WithLocation(4, 30), // (4,30): error CS8302: Feature 'ref extension methods' is not available in C# 7.1. Please use language version 7.2 or greater. - // public static void Print(ref readonly this int p) + // public static void Print(in this int p) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "ref").WithArguments("ref extension methods", "7.2").WithLocation(4, 30) ); diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs index 72ec9b178a76b..265bd599e83cb 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs @@ -97,7 +97,7 @@ static async ref readonly Task M() // (11,41): error CS1519: Invalid token 'operator' in class, struct, or interface member declaration // public static ref readonly Program operator +(Program x, Program y) Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "operator").WithArguments("operator").WithLocation(11, 41), - // (12,5): error CS1519: Invalid token '{' in class, struct, or interface member declaration + // (12,5): error CS1519: Invalid token '{' ref readonly class, struct, or interface member declaration // { Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(12, 5), // (12,5): error CS1519: Invalid token '{' in class, struct, or interface member declaration @@ -221,10 +221,10 @@ class Test // (7,39): error CS1002: ; expected // ref readonly int Invalid() => ref readonly value; Diagnostic(ErrorCode.ERR_SemicolonExpected, "readonly").WithLocation(7, 39), - // (7,53): error CS1519: Invalid token ';' in class, struct, or interface member declaration + // (7,53): error CS1519: Invalid token ';' ref readonly class, struct, or interface member declaration // ref readonly int Invalid() => ref readonly value; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(7, 53), - // (7,53): error CS1519: Invalid token ';' in class, struct, or interface member declaration + // (7,53): error CS1519: Invalid token ';' ref readonly class, struct, or interface member declaration // ref readonly int Invalid() => ref readonly value; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(7, 53)); } @@ -282,35 +282,35 @@ public void RefReadOnlyAtCallSite() CreateStandardCompilation(@" class Test { - void M(ref readonly int p) + void M(in int p) { } void N() { int x = 0; - M(ref readonly x); + M(in x); } }").GetParseDiagnostics().Verify( // (10,15): error CS1525: Invalid expression term 'readonly' - // M(ref readonly x); + // M(in x); Diagnostic(ErrorCode.ERR_InvalidExprTerm, "readonly").WithArguments("readonly").WithLocation(10, 15), // (10,15): error CS1026: ) expected - // M(ref readonly x); + // M(in x); Diagnostic(ErrorCode.ERR_CloseParenExpected, "readonly").WithLocation(10, 15), // (10,15): error CS1002: ; expected - // M(ref readonly x); + // M(in x); Diagnostic(ErrorCode.ERR_SemicolonExpected, "readonly").WithLocation(10, 15), // (10,15): error CS0106: The modifier 'readonly' is not valid for this item - // M(ref readonly x); + // M(in x); Diagnostic(ErrorCode.ERR_BadMemberFlag, "readonly").WithArguments("readonly").WithLocation(10, 15), // (10,25): error CS1001: Identifier expected - // M(ref readonly x); + // M(in x); Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(10, 25), // (10,25): error CS1002: ; expected - // M(ref readonly x); + // M(in x); Diagnostic(ErrorCode.ERR_SemicolonExpected, ")").WithLocation(10, 25), // (10,25): error CS1513: } expected - // M(ref readonly x); + // M(in x); Diagnostic(ErrorCode.ERR_RbraceExpected, ")").WithLocation(10, 25)); } @@ -356,5 +356,29 @@ public class Test // public static ref readonly bool operator!(Test obj) => throw null; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=>").WithArguments("=>").WithLocation(4, 57)); } + + [Fact] + public void InNotAllowedInReturnType() + { + CreateStandardCompilation(@" +class Test +{ + in int M() => throw null; +}").VerifyDiagnostics(); + + Assert.False(true); + } + + [Fact] + public void RefReadOnlyNotAllowedInParameters() + { + CreateStandardCompilation(@" +class Test +{ + void M(ref readonly int p) => throw null; +}").VerifyDiagnostics(); + + Assert.False(true); + } } } diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index 7d045ef3d2d66..3733e1d66b874 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -131,6 +131,7 @@ Microsoft.CodeAnalysis.OperationKind.VariableDeclaration = 1030 -> Microsoft.Cod Microsoft.CodeAnalysis.OperationKind.VariableDeclarationStatement = 3 -> Microsoft.CodeAnalysis.OperationKind Microsoft.CodeAnalysis.OperationKind.YieldBreakStatement = 12 -> Microsoft.CodeAnalysis.OperationKind Microsoft.CodeAnalysis.OperationKind.YieldReturnStatement = 16 -> Microsoft.CodeAnalysis.OperationKind +Microsoft.CodeAnalysis.RefKind.In = 3 -> Microsoft.CodeAnalysis.RefKind Microsoft.CodeAnalysis.RefKind.RefReadOnly = 3 -> Microsoft.CodeAnalysis.RefKind Microsoft.CodeAnalysis.SemanticModel.GetOperation(Microsoft.CodeAnalysis.SyntaxNode node, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.IOperation Microsoft.CodeAnalysis.Semantics.ArgumentKind diff --git a/src/Compilers/Core/Portable/SymbolDisplay/SymbolDisplayParameterOptions.cs b/src/Compilers/Core/Portable/SymbolDisplay/SymbolDisplayParameterOptions.cs index 225394980535a..3bb6d1176ef0c 100644 --- a/src/Compilers/Core/Portable/SymbolDisplay/SymbolDisplayParameterOptions.cs +++ b/src/Compilers/Core/Portable/SymbolDisplay/SymbolDisplayParameterOptions.cs @@ -29,7 +29,7 @@ public enum SymbolDisplayParameterOptions IncludeExtensionThis = 1 << 0, /// - /// Includes the params, ref, ref readonly, out, ByRef, ByVal keywords before parameters. + /// Includes the params, ref, in, out, ByRef, ByVal keywords before parameters. /// IncludeParamsRefOut = 1 << 1, diff --git a/src/Compilers/Core/Portable/Symbols/RefKind.cs b/src/Compilers/Core/Portable/Symbols/RefKind.cs index 0959b20f21f10..6f4e7bebad159 100644 --- a/src/Compilers/Core/Portable/Symbols/RefKind.cs +++ b/src/Compilers/Core/Portable/Symbols/RefKind.cs @@ -6,17 +6,17 @@ namespace Microsoft.CodeAnalysis { /// - /// Denotes the kind of reference parameter. + /// Denotes the kind of reference. /// public enum RefKind : byte { /// - /// Indicates a "value" parameter. + /// Indicates a "value" parameter or return type. /// None = 0, /// - /// Indicates a "ref" parameter. + /// Indicates a "ref" parameter or return type. /// Ref = 1, @@ -26,7 +26,12 @@ public enum RefKind : byte Out = 2, /// - /// Indicates a "ref readonly" parameter. + /// Indicates an "in" parameter. + /// + In = 3, + + /// + /// Indicates a "ref readonly" return type. /// RefReadOnly = 3, } @@ -39,7 +44,7 @@ internal static string ToParameterDisplayString(this RefKind kind) { case RefKind.Out: return "out"; case RefKind.Ref: return "ref"; - case RefKind.RefReadOnly: return "ref readonly"; + case RefKind.In: return "in"; default: throw ExceptionUtilities.UnexpectedValue(kind); } } @@ -54,13 +59,13 @@ internal static string ToArgumentDisplayString(this RefKind kind) } } - internal static string ToPrefix(this RefKind kind) + internal static string ToParameterPrefix(this RefKind kind) { switch (kind) { case RefKind.Out: return "out "; case RefKind.Ref: return "ref "; - case RefKind.RefReadOnly: return "ref readonly "; + case RefKind.In: return "in "; case RefKind.None: return string.Empty; default: throw ExceptionUtilities.UnexpectedValue(kind); } diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/ExtensionMethods/ExtensionMethodTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/ExtensionMethods/ExtensionMethodTests.vb index e27017a982a2a..52744fe55dfaf 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/ExtensionMethods/ExtensionMethodTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/ExtensionMethods/ExtensionMethodTests.vb @@ -2521,7 +2521,7 @@ End Module Dim csharp = CreateCSharpCompilation(" public static class Extensions { - public static void PrintValue(ref readonly this int p) + public static void PrintValue(in this int p) { System.Console.Write(p); } diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/InAttributeModifierTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/InAttributeModifierTests.vb index 001b7b918e871..94274de4b5490 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/InAttributeModifierTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/InAttributeModifierTests.vb @@ -13,7 +13,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Symbols.Metadata Dim reference = CreateCSharpCompilation(" public class TestRef { - public static void M(ref readonly int x) + public static void M(in int x) { System.Console.WriteLine(x); } @@ -39,7 +39,7 @@ End Class Dim reference = CreateCSharpCompilation(" public class TestRef { - public void M(ref readonly int x) + public void M(in int x) { System.Console.WriteLine(x); } @@ -66,7 +66,7 @@ End Class Dim reference = CreateCSharpCompilation(" public class TestRef { - public int this[ref readonly int p] + public int this[in int p] { set { @@ -96,7 +96,7 @@ End Class Dim reference = CreateCSharpCompilation(" public struct TestRef { - public TestRef(ref readonly int value) + public TestRef(in int value) { System.Console.WriteLine(value); } @@ -121,7 +121,7 @@ End Class Dim reference = CreateCSharpCompilation(" public class TestRef { - public virtual void M(ref readonly int x) + public virtual void M(in int x) { System.Console.WriteLine(x); } @@ -154,7 +154,7 @@ BC30657: 'M' has a return type that is not supported or parameter types that are Dim reference = CreateCSharpCompilation(" public abstract class TestRef { - public abstract void M(ref readonly int x); + public abstract void M(in int x); }", parseOptions:=New CSharpParseOptions(CSharp.LanguageVersion.Latest)).EmitToImageReference() Dim source = @@ -184,7 +184,7 @@ BC30657: 'M' has a return type that is not supported or parameter types that are public class TestRef { private int value = 0; - public virtual ref readonly int M() + public virtual in int M() { return ref value; } @@ -216,7 +216,7 @@ BC30657: 'M' has a return type that is not supported or parameter types that are Dim reference = CreateCSharpCompilation(" public abstract class TestRef { - public abstract ref readonly int M(); + public abstract in int M(); }", parseOptions:=New CSharpParseOptions(CSharp.LanguageVersion.Latest)).EmitToImageReference() Dim source = @@ -245,7 +245,7 @@ BC30657: 'M' has a return type that is not supported or parameter types that are public class TestRef { private static int value = 0; - public static ref readonly int M() + public static in int M() { return ref value; } @@ -426,7 +426,7 @@ BC30643: Property 'P' is of an unsupported type. Dim reference = CreateCSharpCompilation(" public class TestRef { - public virtual int this[ref readonly int p] => 0; + public virtual int this[in int p] => 0; }", parseOptions:=New CSharpParseOptions(CSharp.LanguageVersion.Latest)).EmitToImageReference() Dim source = @@ -456,7 +456,7 @@ BC30643: Property 'TestRef.Item(p As )' is of an unsupported type. Dim reference = CreateCSharpCompilation(" public abstract class TestRef { - public abstract int this[ref readonly int p] { set; } + public abstract int this[in int p] { set; } }", parseOptions:=New CSharpParseOptions(CSharp.LanguageVersion.Latest)).EmitToImageReference() Dim source = @@ -571,7 +571,7 @@ BC30643: Property 'TestRef.Item(p As )' is of an unsupported type. Public Sub UsingLambdasOfRefReadOnlyDelegatesIsNotSupported_Invoke_Parameters() Dim reference = CreateCSharpCompilation(" -public delegate void D(ref readonly int p); +public delegate void D(in int p); ", parseOptions:=New CSharpParseOptions(CSharp.LanguageVersion.Latest)).EmitToImageReference() Dim source = @@ -598,7 +598,7 @@ BC30657: 'D' has a return type that is not supported or parameter types that are Public Sub UsingLambdasOfRefReadOnlyDelegatesIsNotSupported_BeginInvoke_Parameters() Dim reference = CreateCSharpCompilation(" -public delegate void D(ref readonly int p); +public delegate void D(in int p); ", parseOptions:=New CSharpParseOptions(CSharp.LanguageVersion.Latest)).EmitToImageReference() Dim source = @@ -625,7 +625,7 @@ BC30657: 'BeginInvoke' has a return type that is not supported or parameter type Public Sub UsingLambdasOfRefReadOnlyDelegatesIsNotSupported_EndInvoke_Parameters() Dim reference = CreateCSharpCompilation(" -public delegate void D(ref readonly int p); +public delegate void D(in int p); ", parseOptions:=New CSharpParseOptions(CSharp.LanguageVersion.Latest)).EmitToImageReference() Dim source = @@ -706,11 +706,11 @@ BC30657: 'EndInvoke' has a return type that is not supported or parameter types Dim reference = CreateCSharpCompilation(" public class TestRef { - public virtual void PrintMul(ref readonly int x) + public virtual void PrintMul(in int x) { System.Console.WriteLine(x * 2); } - public void PrintMul(ref readonly long x) + public void PrintMul(in long x) { System.Console.WriteLine(x * 4); } @@ -771,14 +771,14 @@ End Class Dim reference = CreateCSharpCompilation(" public class TestRef { - public virtual int this[ref readonly int x] + public virtual int this[in int x] { set { System.Console.WriteLine(x * 2); } } - public int this[ref readonly long x] + public int this[in long x] { set { @@ -843,4 +843,4 @@ End Class End Sub End Class -End Namespace \ No newline at end of file +End Namespace diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs index 66693415a06b6..3f1e8e94ab093 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs @@ -6701,45 +6701,45 @@ static void Main(int X) public void LocalFunction_ReadOnlyRef_Parameter_InsertWhole() { var src1 = @"class Test { void M() { } }"; - var src2 = @"class Test { void M() { void local(ref readonly int b) { throw null; } } }"; + var src2 = @"class Test { void M() { void local(in int b) { throw null; } } }"; var edits = GetTopEdits(src1, src2, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)); edits.VerifyEdits( - "Update [void M() { }]@13 -> [void M() { void local(ref readonly int b) { throw null; } }]@13"); + "Update [void M() { }]@13 -> [void M() { void local(in int b) { throw null; } }]@13"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ReadOnlyReferences, "ref readonly int b", FeaturesResources.parameter)); + Diagnostic(RudeEditKind.ReadOnlyReferences, "in int b", FeaturesResources.parameter)); } [Fact] public void LocalFunction_ReadOnlyRef_Parameter_InsertParameter() { var src1 = @"class Test { void M() { void local() { throw null; } } }"; - var src2 = @"class Test { void M() { void local(ref readonly int b) { throw null; } } }"; + var src2 = @"class Test { void M() { void local(in int b) { throw null; } } }"; var edits = GetTopEdits(src1, src2, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)); edits.VerifyEdits( - "Update [void M() { void local() { throw null; } }]@13 -> [void M() { void local(ref readonly int b) { throw null; } }]@13"); + "Update [void M() { void local() { throw null; } }]@13 -> [void M() { void local(in int b) { throw null; } }]@13"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ReadOnlyReferences, "ref readonly int b", FeaturesResources.parameter)); + Diagnostic(RudeEditKind.ReadOnlyReferences, "in int b", FeaturesResources.parameter)); } [Fact] public void LocalFunction_ReadOnlyRef_Parameter_Update() { var src1 = @"class Test { void M() { void local(int b) { throw null; } } }"; - var src2 = @"class Test { void M() { void local(ref readonly int b) { throw null; } } }"; + var src2 = @"class Test { void M() { void local(in int b) { throw null; } } }"; var edits = GetTopEdits(src1, src2, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)); edits.VerifyEdits( - "Update [void M() { void local(int b) { throw null; } }]@13 -> [void M() { void local(ref readonly int b) { throw null; } }]@13"); + "Update [void M() { void local(int b) { throw null; } }]@13 -> [void M() { void local(in int b) { throw null; } }]@13"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ReadOnlyReferences, "ref readonly int b", FeaturesResources.parameter)); + Diagnostic(RudeEditKind.ReadOnlyReferences, "in int b", FeaturesResources.parameter)); } [Fact] diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs index 3d5c47bdd5cd5..9c5d1c0cd46b3 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs @@ -1484,47 +1484,47 @@ public void Delegates_AddAttribute() public void Delegates_ReadOnlyRef_Parameter_InsertWhole() { var src1 = ""; - var src2 = "public delegate int D(ref readonly int b);"; + var src2 = "public delegate int D(in int b);"; var edits = GetTopEdits(src1, src2, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)); edits.VerifyEdits( - "Insert [public delegate int D(ref readonly int b);]@0", - "Insert [(ref readonly int b)]@21", - "Insert [ref readonly int b]@22"); + "Insert [public delegate int D(in int b);]@0", + "Insert [(in int b)]@21", + "Insert [in int b]@22"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ReadOnlyReferences, "ref readonly int b", FeaturesResources.parameter)); + Diagnostic(RudeEditKind.ReadOnlyReferences, "in int b", FeaturesResources.parameter)); } [Fact] public void Delegates_ReadOnlyRef_Parameter_InsertParameter() { var src1 = "public delegate int D();"; - var src2 = "public delegate int D(ref readonly int b);"; + var src2 = "public delegate int D(in int b);"; var edits = GetTopEdits(src1, src2, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)); edits.VerifyEdits( - "Insert [ref readonly int b]@22"); + "Insert [in int b]@22"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.Insert, "ref readonly int b", FeaturesResources.parameter)); + Diagnostic(RudeEditKind.Insert, "in int b", FeaturesResources.parameter)); } [Fact] public void Delegates_ReadOnlyRef_Parameter_Update() { var src1 = "public delegate int D(int b);"; - var src2 = "public delegate int D(ref readonly int b);"; + var src2 = "public delegate int D(in int b);"; var edits = GetTopEdits(src1, src2, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)); edits.VerifyEdits( - "Update [int b]@22 -> [ref readonly int b]@22"); + "Update [int b]@22 -> [in int b]@22"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ModifiersUpdate, "ref readonly int b", FeaturesResources.parameter)); + Diagnostic(RudeEditKind.ModifiersUpdate, "in int b", FeaturesResources.parameter)); } [Fact] @@ -3374,47 +3374,47 @@ public void MethodUpdate_LambdaParameterRefnessInBody() public void Method_ReadOnlyRef_Parameter_InsertWhole() { var src1 = "class Test { }"; - var src2 = "class Test { int M(ref readonly int b) => throw null; }"; + var src2 = "class Test { int M(in int b) => throw null; }"; var edits = GetTopEdits(src1, src2, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)); edits.VerifyEdits( - "Insert [int M(ref readonly int b) => throw null;]@13", - "Insert [(ref readonly int b)]@18", - "Insert [ref readonly int b]@19"); + "Insert [int M(in int b) => throw null;]@13", + "Insert [(in int b)]@18", + "Insert [in int b]@19"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ReadOnlyReferences, "ref readonly int b", FeaturesResources.parameter)); + Diagnostic(RudeEditKind.ReadOnlyReferences, "in int b", FeaturesResources.parameter)); } [Fact] public void Method_ReadOnlyRef_Parameter_InsertParameter() { var src1 = "class Test { int M() => throw null; }"; - var src2 = "class Test { int M(ref readonly int b) => throw null; }"; + var src2 = "class Test { int M(in int b) => throw null; }"; var edits = GetTopEdits(src1, src2, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)); edits.VerifyEdits( - "Insert [ref readonly int b]@19"); + "Insert [in int b]@19"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.Insert, "ref readonly int b", FeaturesResources.parameter)); + Diagnostic(RudeEditKind.Insert, "in int b", FeaturesResources.parameter)); } [Fact] public void Method_ReadOnlyRef_Parameter_Update() { var src1 = "class Test { int M(int b) => throw null; }"; - var src2 = "class Test { int M(ref readonly int b) => throw null; }"; + var src2 = "class Test { int M(in int b) => throw null; }"; var edits = GetTopEdits(src1, src2, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)); edits.VerifyEdits( - "Update [int b]@19 -> [ref readonly int b]@19"); + "Update [int b]@19 -> [in int b]@19"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ModifiersUpdate, "ref readonly int b", FeaturesResources.parameter)); + Diagnostic(RudeEditKind.ModifiersUpdate, "in int b", FeaturesResources.parameter)); } [Fact] @@ -3656,32 +3656,32 @@ class C public void Operator_ReadOnlyRef_Parameter_InsertWhole() { var src1 = "class Test { }"; - var src2 = "class Test { public static bool operator !(ref readonly Test b) => throw null; }"; + var src2 = "class Test { public static bool operator !(in Test b) => throw null; }"; var edits = GetTopEdits(src1, src2, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)); edits.VerifyEdits( - "Insert [public static bool operator !(ref readonly Test b) => throw null;]@13", - "Insert [(ref readonly Test b)]@42", - "Insert [ref readonly Test b]@43"); + "Insert [public static bool operator !(in Test b) => throw null;]@13", + "Insert [(in Test b)]@42", + "Insert [in Test b]@43"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.InsertOperator, "public static bool operator !(ref readonly Test b)", FeaturesResources.operator_)); + Diagnostic(RudeEditKind.InsertOperator, "public static bool operator !(in Test b)", FeaturesResources.operator_)); } [Fact] public void Operator_ReadOnlyRef_Parameter_Update() { var src1 = "class Test { public static bool operator !(Test b) => throw null; }"; - var src2 = "class Test { public static bool operator !(ref readonly Test b) => throw null; }"; + var src2 = "class Test { public static bool operator !(in Test b) => throw null; }"; var edits = GetTopEdits(src1, src2, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)); edits.VerifyEdits( - "Update [Test b]@43 -> [ref readonly Test b]@43"); + "Update [Test b]@43 -> [in Test b]@43"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ModifiersUpdate, "ref readonly Test b", FeaturesResources.parameter)); + Diagnostic(RudeEditKind.ModifiersUpdate, "in Test b", FeaturesResources.parameter)); } #endregion @@ -4909,47 +4909,47 @@ public class C public void Constructor_ReadOnlyRef_Parameter_InsertWhole() { var src1 = "class Test { }"; - var src2 = "class Test { Test(ref readonly int b) => throw null; }"; + var src2 = "class Test { Test(in int b) => throw null; }"; var edits = GetTopEdits(src1, src2, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)); edits.VerifyEdits( - "Insert [Test(ref readonly int b) => throw null;]@13", - "Insert [(ref readonly int b)]@17", - "Insert [ref readonly int b]@18"); + "Insert [Test(in int b) => throw null;]@13", + "Insert [(in int b)]@17", + "Insert [in int b]@18"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ReadOnlyReferences, "ref readonly int b", FeaturesResources.parameter)); + Diagnostic(RudeEditKind.ReadOnlyReferences, "in int b", FeaturesResources.parameter)); } [Fact] public void Constructor_ReadOnlyRef_Parameter_InsertParameter() { var src1 = "class Test { Test() => throw null; }"; - var src2 = "class Test { Test(ref readonly int b) => throw null; }"; + var src2 = "class Test { Test(in int b) => throw null; }"; var edits = GetTopEdits(src1, src2, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)); edits.VerifyEdits( - "Insert [ref readonly int b]@18"); + "Insert [in int b]@18"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.Insert, "ref readonly int b", FeaturesResources.parameter)); + Diagnostic(RudeEditKind.Insert, "in int b", FeaturesResources.parameter)); } [Fact] public void Constructor_ReadOnlyRef_Parameter_Update() { var src1 = "class Test { Test(int b) => throw null; }"; - var src2 = "class Test { Test(ref readonly int b) => throw null; }"; + var src2 = "class Test { Test(in int b) => throw null; }"; var edits = GetTopEdits(src1, src2, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)); edits.VerifyEdits( - "Update [int b]@18 -> [ref readonly int b]@18"); + "Update [int b]@18 -> [in int b]@18"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ModifiersUpdate, "ref readonly int b", FeaturesResources.parameter)); + Diagnostic(RudeEditKind.ModifiersUpdate, "in int b", FeaturesResources.parameter)); } #endregion @@ -7976,32 +7976,32 @@ public void ConstField_Add() public void Indexer_ReadOnlyRef_Parameter_InsertWhole() { var src1 = "class Test { }"; - var src2 = "class Test { int this[ref readonly int i] => throw null; }"; + var src2 = "class Test { int this[in int i] => throw null; }"; var edits = GetTopEdits(src1, src2, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)); edits.VerifyEdits( - "Insert [int this[ref readonly int i] => throw null;]@13", - "Insert [[ref readonly int i]]@21", - "Insert [ref readonly int i]@22"); + "Insert [int this[in int i] => throw null;]@13", + "Insert [[in int i]]@21", + "Insert [in int i]@22"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ReadOnlyReferences, "ref readonly int i", FeaturesResources.parameter)); + Diagnostic(RudeEditKind.ReadOnlyReferences, "in int i", FeaturesResources.parameter)); } [Fact] public void Indexer_ReadOnlyRef_Parameter_Update() { var src1 = "class Test { int this[int i] => throw null; }"; - var src2 = "class Test { int this[ref readonly int i] => throw null; }"; + var src2 = "class Test { int this[in int i] => throw null; }"; var edits = GetTopEdits(src1, src2, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)); edits.VerifyEdits( - "Update [int i]@22 -> [ref readonly int i]@22"); + "Update [int i]@22 -> [in int i]@22"); edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ModifiersUpdate, "ref readonly int i", FeaturesResources.parameter)); + Diagnostic(RudeEditKind.ModifiersUpdate, "in int i", FeaturesResources.parameter)); } [Fact] diff --git a/src/EditorFeatures/CSharpTest/ExtractInterface/ExtractInterfaceTests.cs b/src/EditorFeatures/CSharpTest/ExtractInterface/ExtractInterfaceTests.cs index 79a2457905504..0b3f39b12beda 100644 --- a/src/EditorFeatures/CSharpTest/ExtractInterface/ExtractInterfaceTests.cs +++ b/src/EditorFeatures/CSharpTest/ExtractInterface/ExtractInterfaceTests.cs @@ -1100,7 +1100,7 @@ public async Task TestRefReadOnlyWithMethod_Parameters() using System; class $$TestClass { - public void Method(ref readonly int p1) + public void Method(in int p1) { } }"; @@ -1108,7 +1108,7 @@ public void Method(ref readonly int p1) await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode: @"interface ITestClass { - void Method(ref readonly int p1); + void Method(in int p1); }"); } @@ -1153,13 +1153,13 @@ public async Task TestRefReadOnlyWithIndexer_Parameters() using System; class $$TestClass { - public int this[ref readonly int p1] { set { } } + public int this[in int p1] { set { } } }"; await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expectedInterfaceCode: @"interface ITestClass { - int this[ref readonly int p1] { set; } + int this[in int p1] { set; } }"); } diff --git a/src/EditorFeatures/CSharpTest/ImplementAbstractClass/ImplementAbstractClassTests.cs b/src/EditorFeatures/CSharpTest/ImplementAbstractClass/ImplementAbstractClassTests.cs index ac158e2265d43..75b3fdd26bc9c 100644 --- a/src/EditorFeatures/CSharpTest/ImplementAbstractClass/ImplementAbstractClassTests.cs +++ b/src/EditorFeatures/CSharpTest/ImplementAbstractClass/ImplementAbstractClassTests.cs @@ -1579,18 +1579,18 @@ public async Task TestRefReadOnlyWithMethod_Parameters() await TestInRegularAndScriptAsync( @"abstract class TestParent { - public abstract void Method(ref readonly int p); + public abstract void Method(in int p); } public class [|Test|] : TestParent { }", @"abstract class TestParent { - public abstract void Method(ref readonly int p); + public abstract void Method(in int p); } public class Test : TestParent { - public override void Method(ref readonly int p) + public override void Method(in int p) { throw new System.NotImplementedException(); } @@ -1648,18 +1648,18 @@ public async Task TestRefReadOnlyWithIndexer_Parameters() await TestInRegularAndScriptAsync( @"abstract class TestParent { - public abstract int this[ref readonly int p] { set; } + public abstract int this[in int p] { set; } } public class [|Test|] : TestParent { }", @"abstract class TestParent { - public abstract int this[ref readonly int p] { set; } + public abstract int this[in int p] { set; } } public class Test : TestParent { - public override int this[ref readonly int p] { set => throw new System.NotImplementedException(); } + public override int this[in int p] { set => throw new System.NotImplementedException(); } }"); } diff --git a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs index 1bd1b1e2891b8..f0efb87d577a2 100644 --- a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs +++ b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs @@ -6839,18 +6839,18 @@ public async Task TestRefReadOnlyWithMethod_Parameters() await TestInRegularAndScriptAsync( @"interface ITest { - void Method(ref readonly int p); + void Method(in int p); } public class Test : [|ITest|] { }", @"interface ITest { - void Method(ref readonly int p); + void Method(in int p); } public class Test : ITest { - public void Method(ref readonly int p) + public void Method(in int p) { throw new System.NotImplementedException(); } @@ -6908,18 +6908,18 @@ public async Task TestRefReadOnlyWithIndexer_Parameters() await TestInRegularAndScriptAsync( @"interface ITest { - int this[ref readonly int p] { set; } + int this[in int p] { set; } } public class Test : [|ITest|] { }", @"interface ITest { - int this[ref readonly int p] { set; } + int this[in int p] { set; } } public class Test : ITest { - public int this[ref readonly int p] { set => throw new System.NotImplementedException(); } + public int this[in int p] { set => throw new System.NotImplementedException(); } }"); } diff --git a/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs b/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs index d94519fb7315b..08324d85245f6 100644 --- a/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs +++ b/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs @@ -1149,21 +1149,21 @@ public async Task TestRefReadOnlyWithParameters() { await TestInRegularAndScriptAsync( @" -delegate void D(ref readonly int p); +delegate void D(in int p); class C { void M() { - D [||]lambda = (ref readonly int p) => throw null; + D [||]lambda = (in int p) => throw null; } }", @" -delegate void D(ref readonly int p); +delegate void D(in int p); class C { void M() { - void lambda(ref readonly int p) => throw null; + void lambda(in int p) => throw null; } }"); } diff --git a/src/EditorFeatures/CSharpTest2/Recommendations/InKeywordRecommenderTests.cs b/src/EditorFeatures/CSharpTest2/Recommendations/InKeywordRecommenderTests.cs index 2fe23cf807294..f3aea0bd8ea2d 100644 --- a/src/EditorFeatures/CSharpTest2/Recommendations/InKeywordRecommenderTests.cs +++ b/src/EditorFeatures/CSharpTest2/Recommendations/InKeywordRecommenderTests.cs @@ -301,5 +301,126 @@ void M() { var q = from Int32 $$"); } + + [Test.Utilities.CompilerTrait(Test.Utilities.CompilerFeature.ReadOnlyReferences)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestInAsParameterModifierInMethods() + { + await VerifyKeywordAsync(@" +class Program +{ + public static void Test($$ p) { } +}"); + } + + [Test.Utilities.CompilerTrait(Test.Utilities.CompilerFeature.ReadOnlyReferences)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestInAsParameterModifierInSecondParameter() + { + await VerifyKeywordAsync(@" +class Program +{ + public static void Test(int p1, $$ p2) { } +}"); + } + + [Test.Utilities.CompilerTrait(Test.Utilities.CompilerFeature.ReadOnlyReferences)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestInAsParameterModifierInDelegates() + { + await VerifyKeywordAsync(@" +public delegate int Delegate($$ int p);"); + } + + [Test.Utilities.CompilerTrait(Test.Utilities.CompilerFeature.ReadOnlyReferences)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestInAsParameterModifierInLocalFunctions() + { + await VerifyKeywordAsync(@" +class Program +{ + public static void Test() + { + void localFunc($$ int p) { } + } +}"); + } + + [Test.Utilities.CompilerTrait(Test.Utilities.CompilerFeature.ReadOnlyReferences)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestInAsParameterModifierInLambdaExpressions() + { + await VerifyKeywordAsync(@" +public delegate int Delegate(in int p); + +class Program +{ + public static void Test() + { + Delegate lambda = ($$ int p) => p; + } +}"); + } + + [Test.Utilities.CompilerTrait(Test.Utilities.CompilerFeature.ReadOnlyReferences)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestInAsParameterModifierInAnonymousMethods() + { + await VerifyKeywordAsync(@" +public delegate int Delegate(in int p); + +class Program +{ + public static void Test() + { + Delegate anonymousDelegate = delegate ($$ int p) { return p; }; + } +}"); + } + + [Test.Utilities.CompilerTrait(Test.Utilities.CompilerFeature.ReadOnlyReferences)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestInAsModifierInMethodReturnTypes() + { + await VerifyAbsenceAsync(@" +class Program +{ + public $$ int Test() + { + return ref x; + } +}"); + } + + [Test.Utilities.CompilerTrait(Test.Utilities.CompilerFeature.ReadOnlyReferences)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestInAsModifierInGlobalMemberDeclaration() + { + await VerifyAbsenceAsync(SourceCodeKind.Script, @" +public $$ "); + } + + [Test.Utilities.CompilerTrait(Test.Utilities.CompilerFeature.ReadOnlyReferences)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestInAsModifierInDelegateReturnType() + { + await VerifyAbsenceAsync(@" +public delegate $$ int Delegate(); + +class Program +{ +}"); + } + + [Test.Utilities.CompilerTrait(Test.Utilities.CompilerFeature.ReadOnlyReferences)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task TestInAsModifierInMemberDeclaration() + { + await VerifyAbsenceAsync(@" +class Program +{ + public $$ int Test { get; set; } +}"); + } } } diff --git a/src/EditorFeatures/CSharpTest2/Recommendations/ReadOnlyKeywordRecommenderTests.cs b/src/EditorFeatures/CSharpTest2/Recommendations/ReadOnlyKeywordRecommenderTests.cs index 70d6cb0b27579..53274290ff20c 100644 --- a/src/EditorFeatures/CSharpTest2/Recommendations/ReadOnlyKeywordRecommenderTests.cs +++ b/src/EditorFeatures/CSharpTest2/Recommendations/ReadOnlyKeywordRecommenderTests.cs @@ -421,7 +421,7 @@ void Goo() { [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task TestRefReadonlyAsParameterModifierInMethods() { - await VerifyKeywordAsync(@" + await VerifyAbsenceAsync(@" class Program { public static void Test(ref $$ p) { } @@ -432,7 +432,7 @@ public static void Test(ref $$ p) { } [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task TestRefReadonlyAsParameterModifierInSecondParameter() { - await VerifyKeywordAsync(@" + await VerifyAbsenceAsync(@" class Program { public static void Test(int p1, ref $$ p2) { } @@ -443,7 +443,7 @@ public static void Test(int p1, ref $$ p2) { } [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task TestRefReadonlyAsParameterModifierInDelegates() { - await VerifyKeywordAsync(@" + await VerifyAbsenceAsync(@" public delegate int Delegate(ref $$ int p);"); } @@ -451,7 +451,7 @@ await VerifyKeywordAsync(@" [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task TestRefReadonlyAsParameterModifierInLocalFunctions() { - await VerifyKeywordAsync(@" + await VerifyAbsenceAsync(@" class Program { public static void Test() @@ -465,7 +465,7 @@ void localFunc(ref $$ int p) { } [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task TestRefReadonlyAsParameterModifierInLambdaExpressions() { - await VerifyKeywordAsync(@" + await VerifyAbsenceAsync(@" public delegate int Delegate(ref readonly int p); class Program @@ -481,7 +481,7 @@ public static void Test() [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task TestRefReadonlyAsParameterModifierInAnonymousMethods() { - await VerifyKeywordAsync(@" + await VerifyAbsenceAsync(@" public delegate int Delegate(ref readonly int p); class Program diff --git a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ExpressionCompilerTests.cs b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ExpressionCompilerTests.cs index bebef85b820c6..c29828dfef086 100644 --- a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ExpressionCompilerTests.cs +++ b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ExpressionCompilerTests.cs @@ -6314,7 +6314,7 @@ .locals init (int V_0) //a public void RefReadOnlyLambdasEvaluationWillSynthesizeRequiredAttributes_Parameters() { var reference = CreateStandardCompilation(@" -public delegate void D(ref readonly int p);"); +public delegate void D(in int p);"); CompileAndVerify(reference, symbolValidator: module => { @@ -6339,7 +6339,7 @@ void M(D lambda) var testData = Evaluate( comp, methodName: "Test.M", - expr: "M((ref readonly int p) => {})"); + expr: "M((in int p) => {})"); var methodsGenerated = testData.GetMethodsByName().Keys; Assert.Contains(AttributeDescription.CodeAnalysisEmbeddedAttribute.FullName + "..ctor()", methodsGenerated); @@ -6350,7 +6350,7 @@ void M(D lambda) public void RefReadOnlyLambdasEvaluationWillSynthesizeRequiredAttributes_ReturnTypes() { var reference = CreateStandardCompilation(@" -public delegate ref readonly int D();"); +public delegate in int D();"); CompileAndVerify(reference, symbolValidator: module => { diff --git a/src/VisualStudio/Core/Def/Implementation/ChangeSignature/ChangeSignatureDialogViewModel.cs b/src/VisualStudio/Core/Def/Implementation/ChangeSignature/ChangeSignatureDialogViewModel.cs index 75306ee0bb6b4..bf50f46d6fa33 100644 --- a/src/VisualStudio/Core/Def/Implementation/ChangeSignature/ChangeSignatureDialogViewModel.cs +++ b/src/VisualStudio/Core/Def/Implementation/ChangeSignature/ChangeSignatureDialogViewModel.cs @@ -467,8 +467,8 @@ public string Modifier return "out"; case RefKind.Ref: return "ref"; - case RefKind.RefReadOnly: - return "ref readonly"; + case RefKind.In: + return "in"; } if (_parameter.IsParams) diff --git a/src/VisualStudio/Core/Test/ChangeSignature/ChangeSignatureViewModelTests.vb b/src/VisualStudio/Core/Test/ChangeSignature/ChangeSignatureViewModelTests.vb index a03d5ca0bd634..47ba9ac148c1e 100644 --- a/src/VisualStudio/Core/Test/ChangeSignature/ChangeSignatureViewModelTests.vb +++ b/src/VisualStudio/Core/Test/ChangeSignature/ChangeSignatureViewModelTests.vb @@ -365,15 +365,15 @@ class MyClass Dim markup = Dim state = Await GetViewModelTestStateAsync(markup, LanguageNames.CSharp) - VerifyOpeningState(state.ViewModel, "private void Method(int p1, ref int p2, ref readonly int p3, out int p4)") + VerifyOpeningState(state.ViewModel, "private void Method(int p1, ref int p2, in int p3, out int p4)") Assert.Equal("", state.ViewModel.AllParameters(0).Modifier) Assert.Equal("ref", state.ViewModel.AllParameters(1).Modifier) - Assert.Equal("ref readonly", state.ViewModel.AllParameters(2).Modifier) + Assert.Equal("in", state.ViewModel.AllParameters(2).Modifier) Assert.Equal("out", state.ViewModel.AllParameters(3).Modifier) End Function End Class From 3be2584bb0a5c51a28f63bce66a1d4bfa4eb2d2c Mon Sep 17 00:00:00 2001 From: Omar Tawfik Date: Thu, 28 Sep 2017 14:00:39 -0700 Subject: [PATCH 05/16] Checked uses of RefKind.RefReadOnly --- .../Portable/Binder/Binder.ValueChecks.cs | 8 ++-- .../Portable/Binder/Binder_Invocation.cs | 2 +- .../CSharp/Portable/Binder/Binder_Lambda.cs | 2 +- .../OverloadResolution/OverloadResolution.cs | 2 +- .../OverloadResolutionResult.cs | 14 +++---- .../CSharp/Portable/CodeGen/EmitAddress.cs | 2 +- .../CSharp/Portable/CodeGen/EmitExpression.cs | 2 +- .../AsyncRewriter/AwaitExpressionSpiller.cs | 4 +- .../Lowering/LocalRewriter/LocalRewriter.cs | 2 +- .../LocalRewriter/LocalRewriter_Call.cs | 6 +-- .../Lowering/SyntheticBoundNodeFactory.cs | 2 +- .../SymbolDisplayVisitor.Members.cs | 6 +-- .../Symbols/Metadata/PE/PEMethodSymbol.cs | 2 +- .../Symbols/Metadata/PE/PEParameterSymbol.cs | 2 +- .../Portable/Symbols/NamedTypeSymbol.cs | 2 +- .../Portable/Symbols/ParameterSymbol.cs | 2 +- .../Symbols/Source/ParameterHelpers.cs | 8 ++-- .../Source/SourceOrdinaryMethodSymbol.cs | 2 +- .../Symbols/Source/SourceParameterSymbol.cs | 4 +- .../SourceUserDefinedOperatorSymbolBase.cs | 2 +- .../Symbols/Source/ThisParameterSymbol.cs | 2 +- .../Attributes/AttributeTests_RefReadOnly.cs | 40 +++++++++---------- .../CodeGen/CodeGenReadonlyStructTests.cs | 32 +++++++-------- .../Semantics/RefExtensionMethodsTests.cs | 2 +- .../Symbol/Symbols/Source/DelegateTests.cs | 6 +-- .../Source/ExpressionBodiedPropertyTests.cs | 4 +- .../ChangeSignatureViewModelTests.vb | 2 +- .../CodeGeneration/CSharpSyntaxGenerator.cs | 6 +-- 28 files changed, 84 insertions(+), 86 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs index abe81619dd764..45a090ead2a48 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs @@ -518,7 +518,7 @@ private bool CheckParameterValueKind(SyntaxNode node, BoundParameter parameter, // all parameters can be passed by ref/out or assigned to // except "in" parameters, which are readonly - if (parameterSymbol.RefKind == RefKind.RefReadOnly && RequiresAssignableVariable(valueKind)) + if (parameterSymbol.RefKind == RefKind.In && RequiresAssignableVariable(valueKind)) { ReportReadOnlyError(parameterSymbol, node, valueKind, checkingReceiver, diagnostics); return false; @@ -1291,9 +1291,9 @@ private static RefKind GetEffectiveRefKind( { var paramIndex = argsToParamsOpt.IsDefault ? argIndex : argsToParamsOpt[argIndex]; - if (parameters[paramIndex].RefKind == RefKind.RefReadOnly) + if (parameters[paramIndex].RefKind == RefKind.In) { - effectiveRefKind = RefKind.RefReadOnly; + effectiveRefKind = RefKind.In; refReadOnlyParametersMatchedWithArgs = refReadOnlyParametersMatchedWithArgs ?? ArrayBuilder.GetInstance(parameters.Length, fillWithValue: false); refReadOnlyParametersMatchedWithArgs[paramIndex] = true; } @@ -1321,7 +1321,7 @@ private static ParameterSymbol TryGetUnmatchedRefReadOnlyParameterAndFreeMatched break; } - if (parameter.RefKind == RefKind.RefReadOnly && + if (parameter.RefKind == RefKind.In && refReadOnlyParametersMatchedWithArgs?[i] != true && parameter.Type.IsByRefLikeType == false) { diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs index 453d4051777be..6842b969375cd 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs @@ -980,7 +980,7 @@ private BoundCall BindInvocationExpressionContinued( CheckFeatureAvailability(receiverArgument.Syntax, MessageID.IDS_FeatureRefExtensionMethods, diagnostics); } - else if (receiverParameter.RefKind == RefKind.RefReadOnly) + else if (receiverParameter.RefKind == RefKind.In) { CheckFeatureAvailability(receiverArgument.Syntax, MessageID.IDS_FeatureRefExtensionMethods, diagnostics); } diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs index 210e62ea13aa3..d2047dc16245a 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs @@ -141,7 +141,7 @@ private Tuple, ImmutableArray, ImmutableArra case SyntaxKind.ReadOnlyKeyword: Debug.Assert(refKind == RefKind.Ref || syntax.HasErrors); - refKind = RefKind.RefReadOnly; + refKind = RefKind.In; allValue = false; break; diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs index a0ba5e2462970..d4c00ba1feae4 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs @@ -2575,7 +2575,7 @@ private RefKind GetEffectiveParameterRefKind(ParameterSymbol parameter, RefKind { var paramRefKind = parameter.RefKind; - if (paramRefKind == RefKind.RefReadOnly) + if (paramRefKind == RefKind.In) { // "in" parameters are effectively None for the purpose of overload resolution. paramRefKind = RefKind.None; diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolutionResult.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolutionResult.cs index 3005883e675a2..ad08d7943b7bf 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolutionResult.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolutionResult.cs @@ -950,17 +950,17 @@ private static void ReportBadArgumentError( ParameterSymbol parameter = method.GetParameters()[parm]; bool isLastParameter = method.GetParameterCount() == parm + 1; // This is used to later decide if we need to try to unwrap a params array RefKind refArg = arguments.RefKind(arg); - RefKind refParm = parameter.RefKind; + RefKind refParameter = parameter.RefKind; if (arguments.IsExtensionMethodThisArgument(arg)) { Debug.Assert(refArg == RefKind.None); - if (refParm == RefKind.Ref || refParm == RefKind.RefReadOnly) + if (refParameter == RefKind.Ref || refParameter == RefKind.In) { // For ref and ref-readonly extension methods, we omit the "ref" modifier on receiver arguments. // Setting the correct RefKind for finding the correct diagnostics message. // For other ref kinds, keeping it as it is to find mismatch errors. - refArg = refParm; + refArg = refParameter; } } @@ -974,7 +974,7 @@ private static void ReportBadArgumentError( { // If the problem is that a lambda isn't convertible to the given type, also report why. // The argument and parameter type might match, but may not have same in/out modifiers - if (argument.Kind == BoundKind.UnboundLambda && refArg == refParm) + if (argument.Kind == BoundKind.UnboundLambda && refArg == refParameter) { ((UnboundLambda)argument).GenerateAnonymousFunctionConversionError(diagnostics, parameter.Type); } @@ -992,9 +992,9 @@ private static void ReportBadArgumentError( UnwrapIfParamsArray(parameter, isLastParameter)); } } - else if (refArg != refParm && !(refArg == RefKind.None && refParm == RefKind.RefReadOnly)) + else if (refArg != refParameter && !(refArg == RefKind.None && refParameter == RefKind.In)) { - if (refParm == RefKind.None || refParm == RefKind.RefReadOnly) + if (refParameter == RefKind.None || refParameter == RefKind.In) { // Argument {0} should not be passed with the {1} keyword diagnostics.Add( @@ -1012,7 +1012,7 @@ private static void ReportBadArgumentError( sourceLocation, symbols, arg + 1, - refParm.ToParameterDisplayString()); + refParameter.ToParameterDisplayString()); } } else diff --git a/src/Compilers/CSharp/Portable/CodeGen/EmitAddress.cs b/src/Compilers/CSharp/Portable/CodeGen/EmitAddress.cs index d591bc14ae6b2..65299f6fdc40c 100644 --- a/src/Compilers/CSharp/Portable/CodeGen/EmitAddress.cs +++ b/src/Compilers/CSharp/Portable/CodeGen/EmitAddress.cs @@ -364,7 +364,7 @@ private bool HasHome(BoundExpression expression, bool needWriteable) case BoundKind.Parameter: return !needWriteable || - ((BoundParameter)expression).ParameterSymbol.RefKind != RefKind.RefReadOnly; + ((BoundParameter)expression).ParameterSymbol.RefKind != RefKind.In; case BoundKind.Local: // locals have home unless they are byval stack locals or ref-readonly diff --git a/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs b/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs index c50e993006e65..f88fbce71c0b3 100644 --- a/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs +++ b/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs @@ -599,7 +599,7 @@ private void EmitArgument(BoundExpression argument, RefKind refKind) EmitExpression(argument, true); break; - case RefKind.RefReadOnly: + case RefKind.In: var temp = EmitAddress(argument, AddressKind.ReadOnly); AddExpressionTemp(temp); break; diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AwaitExpressionSpiller.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AwaitExpressionSpiller.cs index a056fa00167c7..fc1c526ef6468 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AwaitExpressionSpiller.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AwaitExpressionSpiller.cs @@ -378,7 +378,7 @@ private BoundExpression Spill( case BoundKind.Call: var call = (BoundCall)expression; - if (refKind != RefKind.None && refKind != RefKind.RefReadOnly) + if (refKind != RefKind.None && refKind != RefKind.In) { Debug.Assert(call.Method.RefKind != RefKind.None); _F.Diagnostics.Add(ErrorCode.ERR_RefReturningCallAndAwait, _F.Syntax.Location, call.Method); @@ -794,7 +794,7 @@ public override BoundNode VisitCall(BoundCall node) receiver = node.ReceiverOpt; var refKind = node.Method.ContainingType.IsReadOnly? - RefKind.RefReadOnly: + RefKind.In: ReceiverSpillRefKind(receiver); receiver = Spill(receiverBuilder, VisitExpression(ref receiverBuilder, receiver), refKind: refKind); diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs index 41dc46552712d..b87d27c5ef29c 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs @@ -597,7 +597,7 @@ private void CheckRefReadOnlySymbols(MethodSymbol symbol) { foreach (var parameter in symbol.Parameters) { - if (parameter.RefKind == RefKind.RefReadOnly) + if (parameter.RefKind == RefKind.In) { foundRefReadOnly = true; break; diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs index e1445b909e0d0..d3269841d0cf2 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs @@ -503,7 +503,7 @@ private static ImmutableArray GetEffectiveArgumentRefKinds(ImmutableArr for (int i = 0; i < parameters.Length; i++) { var paramRefKind = parameters[i].RefKind; - if (paramRefKind == RefKind.RefReadOnly) + if (paramRefKind == RefKind.In) { if (refKindsBuilder == null) { @@ -661,9 +661,9 @@ private void BuildStoresToTemps( BoundExpression argument = rewrittenArguments[a]; int p = (!argsToParamsOpt.IsDefault) ? argsToParamsOpt[a] : a; RefKind refKind = argumentRefKinds.RefKinds(a); - if (refKind == RefKind.None && parameters[p].RefKind == RefKind.RefReadOnly) + if (refKind == RefKind.None && parameters[p].RefKind == RefKind.In) { - refKind = RefKind.RefReadOnly; + refKind = RefKind.In; } Debug.Assert(arguments[p] == null); diff --git a/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs b/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs index a2fac9fb9f984..896e5f0138342 100644 --- a/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs +++ b/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs @@ -1269,7 +1269,7 @@ public BoundLocal StoreToTemp( #endif ) { - if (refKind == RefKind.Out || refKind == RefKind.RefReadOnly) + if (refKind == RefKind.Out || refKind == RefKind.In) { refKind = RefKind.Ref; } diff --git a/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Members.cs b/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Members.cs index 7a2c9e807d15f..59672c5b7c049 100644 --- a/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Members.cs +++ b/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Members.cs @@ -742,10 +742,8 @@ private void AddParameterRefKindIfRequired(RefKind refKind) AddKeyword(SyntaxKind.RefKeyword); AddSpace(); break; - case RefKind.RefReadOnly: - AddKeyword(SyntaxKind.RefKeyword); - AddSpace(); - AddKeyword(SyntaxKind.ReadOnlyKeyword); + case RefKind.In: + AddKeyword(SyntaxKind.InKeyword); AddSpace(); break; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs index 9f69385538bc8..9219de45e7c63 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs @@ -796,7 +796,7 @@ private bool IsValidExtensionMethodSignature() { case RefKind.None: case RefKind.Ref: - case RefKind.RefReadOnly: + case RefKind.In: return !parameter.IsParams; default: return false; diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs index e12e3b508f0c3..20d11f1ed8a63 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs @@ -304,7 +304,7 @@ public PEParameterSymbolWithCustomModifiers( _customModifiers = CSharpCustomModifier.Convert(customModifiers); _refCustomModifiers = CSharpCustomModifier.Convert(refCustomModifiers); - if (this.RefKind != RefKind.RefReadOnly && _refCustomModifiers.Any(modifier => !modifier.IsOptional && modifier.Modifier.IsWellKnownTypeInAttribute())) + if (this.RefKind != RefKind.In && _refCustomModifiers.Any(modifier => !modifier.IsOptional && modifier.Modifier.IsWellKnownTypeInAttribute())) { // The modreq is only accepted on RefReadOnly symbols isBad = true; diff --git a/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs index 8ae0fcf316c36..2b9def734b4a5 100644 --- a/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs @@ -378,7 +378,7 @@ internal void DoGetExtensionMethods(ArrayBuilder methods, string n var thisParam = method.Parameters.First(); if ((thisParam.RefKind == RefKind.Ref && !thisParam.Type.IsValueType) || - (thisParam.RefKind == RefKind.RefReadOnly && thisParam.Type.TypeKind != TypeKind.Struct)) + (thisParam.RefKind == RefKind.In && thisParam.Type.TypeKind != TypeKind.Struct)) { // For ref and ref-readonly extension methods, receivers need to be of the correct types to be considered in lookup continue; diff --git a/src/Compilers/CSharp/Portable/Symbols/ParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/ParameterSymbol.cs index 8706583116e0a..27755ccd509af 100644 --- a/src/Compilers/CSharp/Portable/Symbols/ParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/ParameterSymbol.cs @@ -145,7 +145,7 @@ public bool IsOptional RefKind refKind; return !IsParams && IsMetadataOptional && ((refKind = RefKind) == RefKind.None || - (refKind == RefKind.RefReadOnly) || + (refKind == RefKind.In) || (refKind == RefKind.Ref && ContainingSymbol.ContainingType.IsComImport)); } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs b/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs index 98e58c51d0695..b3c9fb1bcd08d 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs @@ -125,7 +125,7 @@ internal static void EnsureIsReadOnlyAttributeExists(ImmutableArray { var parameter = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod("M").GetParameters().Single(); - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Internal, parameter.GetAttributes(), module.ContainingAssembly.Name); }); @@ -108,7 +108,7 @@ class Test Assert.True(method.ReturnsByRefReadonly); var parameter = method.GetParameters().Single(); - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, parameter.GetAttributes(), referenceA.Compilation.AssemblyName); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, method.GetReturnTypeAttributes(), referenceA.Compilation.AssemblyName); @@ -138,7 +138,7 @@ struct Test foreach (var parameter in method.Parameters) { - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, parameter.GetAttributes(), module.ContainingAssembly.Name); } }); @@ -190,7 +190,7 @@ struct Test Assert.Equal(2, method.ParameterCount); foreach (var parameter in method.Parameters) { - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, parameter.GetAttributes(), referenceA.Compilation.AssemblyName); } @@ -217,7 +217,7 @@ public Test(in int x) { } { var parameter = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod(".ctor").Parameters.Single(); - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, parameter.GetAttributes(), module.ContainingAssembly.Name); }); } @@ -261,7 +261,7 @@ public Test(in int x) { } { var parameter = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod(".ctor").Parameters.Single(); - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, parameter.GetAttributes(), referenceA.Compilation.AssemblyName); AssertNoIsReadOnlyAttributeExists(module.ContainingAssembly); @@ -391,7 +391,7 @@ class Test Assert.True(indexer.ReturnsByRefReadonly); var parameter = indexer.GetParameters().Single(); - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, parameter.GetAttributes(), module.ContainingAssembly.Name); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, indexer.GetAttributes(), module.ContainingAssembly.Name); @@ -411,7 +411,7 @@ class Test CompileAndVerify(text, symbolValidator: module => { var parameter = module.ContainingAssembly.GetTypeByMetadataName("Test").GetProperty("this[]").GetParameters().Single(); - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Internal, parameter.GetAttributes(), module.ContainingAssembly.Name); }); @@ -463,7 +463,7 @@ class Test Assert.True(indexer.ReturnsByRefReadonly); var parameter = indexer.GetParameters().Single(); - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, parameter.GetAttributes(), referenceA.Compilation.AssemblyName); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, indexer.GetAttributes(), referenceA.Compilation.AssemblyName); @@ -490,7 +490,7 @@ public class IsReadOnlyAttribute : System.Attribute { } Assert.True(method.ReturnsByRefReadonly); var parameter = method.GetParameters().Single(); - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, parameter.GetAttributes(), module.ContainingAssembly.Name); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, method.GetReturnTypeAttributes(), module.ContainingAssembly.Name); @@ -507,7 +507,7 @@ public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Delegate_Parameter CompileAndVerify(text, symbolValidator: module => { var parameter = module.ContainingAssembly.GetTypeByMetadataName("D").DelegateInvokeMethod.GetParameters().Single(); - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Internal, parameter.GetAttributes(), module.ContainingAssembly.Name); }); @@ -552,7 +552,7 @@ public class IsReadOnlyAttribute : System.Attribute { } Assert.True(method.ReturnsByRefReadonly); var parameter = method.GetParameters().Single(); - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, parameter.GetAttributes(), referenceA.Compilation.AssemblyName); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, method.GetReturnTypeAttributes(), referenceA.Compilation.AssemblyName); @@ -589,7 +589,7 @@ ref readonly int Inner(in int x) Assert.True(method.ReturnsByRefReadonly); var parameter = method.GetParameters().Single(); - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, parameter.GetAttributes(), module.ContainingAssembly.Name); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, method.GetReturnTypeAttributes(), module.ContainingAssembly.Name); @@ -613,7 +613,7 @@ void Inner(in int x) { } CompileAndVerify(text, options: options, symbolValidator: module => { var parameter = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod("g__Inner|0_0").GetParameters().Single(); - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Internal, parameter.GetAttributes(), module.ContainingAssembly.Name); }); @@ -678,7 +678,7 @@ ref readonly int Inner(in int x) Assert.True(method.ReturnsByRefReadonly); var parameter = method.GetParameters().Single(); - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, parameter.GetAttributes(), referenceA.Compilation.AssemblyName); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, method.GetReturnTypeAttributes(), referenceA.Compilation.AssemblyName); @@ -717,7 +717,7 @@ public void M2(D value) { } Assert.True(method.ReturnsByRefReadonly); var parameter = method.GetParameters().Single(); - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, parameter.GetAttributes(), module.ContainingAssembly.Name); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, method.GetReturnTypeAttributes(), module.ContainingAssembly.Name); @@ -745,7 +745,7 @@ public void M2(D value) { } CompileAndVerify(text, options: options, symbolValidator: module => { var parameter = module.GlobalNamespace.GetMember("Test.<>c.b__0_0").GetParameters().Single(); - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Internal, parameter.GetAttributes(), module.ContainingAssembly.Name); }); @@ -813,7 +813,7 @@ public void M2(D value) { } Assert.True(method.ReturnsByRefReadonly); var parameter = method.GetParameters().Single(); - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, parameter.GetAttributes(), referenceA.Compilation.AssemblyName); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, method.GetReturnTypeAttributes(), referenceA.Compilation.AssemblyName); @@ -1151,7 +1151,7 @@ public void M(in int x) { } AssertNoIsReadOnlyAttributeExists(module.ContainingAssembly); var parameter = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod("M").GetParameters().Single(); - Assert.Equal(RefKind.RefReadOnly, parameter.RefKind); + Assert.Equal(RefKind.In, parameter.RefKind); AssertReferencedIsReadOnlyAttribute(Accessibility.Public, parameter.GetAttributes(), reference.Display); }); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenReadonlyStructTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenReadonlyStructTests.cs index e98a12aeccc62..9c967e2dcbc75 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenReadonlyStructTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenReadonlyStructTests.cs @@ -814,29 +814,29 @@ public override string ToString() NamedTypeSymbol namedType = comp.GetTypeByMetadataName("Program+S1"); Assert.True(namedType.IsReadOnly); Assert.Equal(RefKind.Out, namedType.Constructors[0].ThisParameter.RefKind); - Assert.Equal(RefKind.RefReadOnly, namedType.GetMethod("M1").ThisParameter.RefKind); - Assert.Equal(RefKind.RefReadOnly, namedType.GetMethod("ToString").ThisParameter.RefKind); + Assert.Equal(RefKind.In, namedType.GetMethod("M1").ThisParameter.RefKind); + Assert.Equal(RefKind.In, namedType.GetMethod("ToString").ThisParameter.RefKind); // S1 namedType = comp.GetTypeByMetadataName("Program+S1`1"); Assert.True(namedType.IsReadOnly); Assert.Equal(RefKind.Out, namedType.Constructors[0].ThisParameter.RefKind); - Assert.Equal(RefKind.RefReadOnly, namedType.GetMethod("M1").ThisParameter.RefKind); - Assert.Equal(RefKind.RefReadOnly, namedType.GetMethod("ToString").ThisParameter.RefKind); + Assert.Equal(RefKind.In, namedType.GetMethod("M1").ThisParameter.RefKind); + Assert.Equal(RefKind.In, namedType.GetMethod("ToString").ThisParameter.RefKind); // T TypeSymbol type = namedType.TypeParameters[0]; Assert.True(namedType.IsReadOnly); Assert.Equal(RefKind.Out, namedType.Constructors[0].ThisParameter.RefKind); - Assert.Equal(RefKind.RefReadOnly, namedType.GetMethod("M1").ThisParameter.RefKind); - Assert.Equal(RefKind.RefReadOnly, namedType.GetMethod("ToString").ThisParameter.RefKind); + Assert.Equal(RefKind.In, namedType.GetMethod("M1").ThisParameter.RefKind); + Assert.Equal(RefKind.In, namedType.GetMethod("ToString").ThisParameter.RefKind); // S1 namedType = namedType.Construct(comp.ObjectType); Assert.True(namedType.IsReadOnly); Assert.Equal(RefKind.Out, namedType.Constructors[0].ThisParameter.RefKind); - Assert.Equal(RefKind.RefReadOnly, namedType.GetMethod("M1").ThisParameter.RefKind); - Assert.Equal(RefKind.RefReadOnly, namedType.GetMethod("ToString").ThisParameter.RefKind); + Assert.Equal(RefKind.In, namedType.GetMethod("M1").ThisParameter.RefKind); + Assert.Equal(RefKind.In, namedType.GetMethod("ToString").ThisParameter.RefKind); // S2 namedType = comp.GetTypeByMetadataName("Program+S2"); @@ -970,29 +970,29 @@ public override string ToString() NamedTypeSymbol namedType = comp.GetTypeByMetadataName("Program+S1"); Assert.True(namedType.IsReadOnly); Assert.Equal(RefKind.Out, namedType.Constructors[0].ThisParameter.RefKind); - Assert.Equal(RefKind.RefReadOnly, namedType.GetMethod("M1").ThisParameter.RefKind); - Assert.Equal(RefKind.RefReadOnly, namedType.GetMethod("ToString").ThisParameter.RefKind); + Assert.Equal(RefKind.In, namedType.GetMethod("M1").ThisParameter.RefKind); + Assert.Equal(RefKind.In, namedType.GetMethod("ToString").ThisParameter.RefKind); // S1 namedType = comp.GetTypeByMetadataName("Program+S1`1"); Assert.True(namedType.IsReadOnly); Assert.Equal(RefKind.Out, namedType.Constructors[0].ThisParameter.RefKind); - Assert.Equal(RefKind.RefReadOnly, namedType.GetMethod("M1").ThisParameter.RefKind); - Assert.Equal(RefKind.RefReadOnly, namedType.GetMethod("ToString").ThisParameter.RefKind); + Assert.Equal(RefKind.In, namedType.GetMethod("M1").ThisParameter.RefKind); + Assert.Equal(RefKind.In, namedType.GetMethod("ToString").ThisParameter.RefKind); // T TypeSymbol type = namedType.TypeParameters[0]; Assert.True(namedType.IsReadOnly); Assert.Equal(RefKind.Out, namedType.Constructors[0].ThisParameter.RefKind); - Assert.Equal(RefKind.RefReadOnly, namedType.GetMethod("M1").ThisParameter.RefKind); - Assert.Equal(RefKind.RefReadOnly, namedType.GetMethod("ToString").ThisParameter.RefKind); + Assert.Equal(RefKind.In, namedType.GetMethod("M1").ThisParameter.RefKind); + Assert.Equal(RefKind.In, namedType.GetMethod("ToString").ThisParameter.RefKind); // S1 namedType = namedType.Construct(comp.ObjectType); Assert.True(namedType.IsReadOnly); Assert.Equal(RefKind.Out, namedType.Constructors[0].ThisParameter.RefKind); - Assert.Equal(RefKind.RefReadOnly, namedType.GetMethod("M1").ThisParameter.RefKind); - Assert.Equal(RefKind.RefReadOnly, namedType.GetMethod("ToString").ThisParameter.RefKind); + Assert.Equal(RefKind.In, namedType.GetMethod("M1").ThisParameter.RefKind); + Assert.Equal(RefKind.In, namedType.GetMethod("ToString").ThisParameter.RefKind); // S2 namedType = comp.GetTypeByMetadataName("Program+S2"); diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefExtensionMethodsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefExtensionMethodsTests.cs index 45bbd2226711b..c02278f0faef6 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefExtensionMethodsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefExtensionMethodsTests.cs @@ -1962,7 +1962,7 @@ public static void Method(in this int p) { } var model = comp.GetSemanticModel(tree); var symbol = (ParameterSymbol)model.GetDeclaredSymbolForNode(parameter.AsNode()); - Assert.Equal(RefKind.RefReadOnly, symbol.RefKind); + Assert.Equal(RefKind.In, symbol.RefKind); } [Fact] diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/DelegateTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/DelegateTests.cs index 24b3efb59ad53..7650294d374df 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/DelegateTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/DelegateTests.cs @@ -750,7 +750,7 @@ public void RefReadonlyReturningDelegate() Assert.Equal(RefKind.RefReadOnly, d.DelegateInvokeMethod.RefKind); Assert.Equal(RefKind.RefReadOnly, ((MethodSymbol)d.GetMembers("EndInvoke").Single()).RefKind); - Assert.Equal(RefKind.RefReadOnly, d.DelegateInvokeMethod.Parameters[0].RefKind); + Assert.Equal(RefKind.In, d.DelegateInvokeMethod.Parameters[0].RefKind); } [Fact] @@ -779,14 +779,14 @@ public static void Main() Assert.False(lambda.ReturnsByRef); Assert.True(lambda.ReturnsByRefReadonly); - Assert.Equal(lambda.Parameters[0].RefKind, RefKind.RefReadOnly); + Assert.Equal(lambda.Parameters[0].RefKind, RefKind.In); lambdaSyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType().Single(); lambda = (LambdaSymbol)model.GetSymbolInfo(lambdaSyntax).Symbol; Assert.False(lambda.ReturnsByRef); Assert.True(lambda.ReturnsByRefReadonly); - Assert.Equal(lambda.Parameters[0].RefKind, RefKind.RefReadOnly); + Assert.Equal(lambda.Parameters[0].RefKind, RefKind.In); } } } diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/ExpressionBodiedPropertyTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/ExpressionBodiedPropertyTests.cs index 54d5e344f1918..c296a04c1f9ea 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/ExpressionBodiedPropertyTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/ExpressionBodiedPropertyTests.cs @@ -554,7 +554,7 @@ class C Assert.False(p.GetMethod.IsImplicitlyDeclared); Assert.True(p.IsExpressionBodied); Assert.Equal(RefKind.RefReadOnly, p.GetMethod.RefKind); - Assert.Equal(RefKind.RefReadOnly, p.GetMethod.Parameters[0].RefKind); + Assert.Equal(RefKind.In, p.GetMethod.Parameters[0].RefKind); Assert.False(p.ReturnsByRef); Assert.False(p.GetMethod.ReturnsByRef); Assert.True(p.ReturnsByRefReadonly); @@ -582,7 +582,7 @@ class C Assert.False(p.GetMethod.IsImplicitlyDeclared); Assert.True(p.IsExpressionBodied); Assert.Equal(RefKind.RefReadOnly, p.GetMethod.RefKind); - Assert.Equal(RefKind.RefReadOnly, p.GetMethod.Parameters[0].RefKind); + Assert.Equal(RefKind.In, p.GetMethod.Parameters[0].RefKind); Assert.False(p.ReturnsByRef); Assert.False(p.GetMethod.ReturnsByRef); Assert.True(p.ReturnsByRefReadonly); diff --git a/src/VisualStudio/Core/Test/ChangeSignature/ChangeSignatureViewModelTests.vb b/src/VisualStudio/Core/Test/ChangeSignature/ChangeSignatureViewModelTests.vb index 47ba9ac148c1e..d5ccd7b6f6564 100644 --- a/src/VisualStudio/Core/Test/ChangeSignature/ChangeSignatureViewModelTests.vb +++ b/src/VisualStudio/Core/Test/ChangeSignature/ChangeSignatureViewModelTests.vb @@ -359,7 +359,7 @@ class MyClass Public Async Function TestRefKindsDisplayedCorrectly() As Tasks.Task - Dim includedInTest = {RefKind.None, RefKind.Ref, RefKind.Out, RefKind.RefReadOnly} + Dim includedInTest = {RefKind.None, RefKind.Ref, RefKind.Out, RefKind.In, RefKind.RefReadOnly} Assert.Equal(includedInTest, EnumUtilities.GetValues(Of RefKind)()) Dim markup = Date: Thu, 28 Sep 2017 14:01:44 -0700 Subject: [PATCH 06/16] Create tests to cover test plans #19216 and #20127 (#22284) * Create tests to cover test plans #19216 and #20127 * clean up --- .../Portable/Binder/Binder.ValueChecks.cs | 54 +-- .../OverloadResolution/OverloadResolution.cs | 2 +- .../Portable/Syntax/SyntaxNodeExtensions.cs | 4 +- .../CodeGenRefReadOnlyParametersTests.cs | 19 + .../CodeGen/CodeGenRefReadonlyReturnTests.cs | 215 +++++++++++ .../Test/Semantic/Semantics/NameOfTests.cs | 17 + .../Semantics/RefLocalsAndReturnsTests.cs | 72 ++++ .../Semantic/Semantics/SemanticErrorTests.cs | 70 ++-- .../StackAllocSpanExpressionsTests.cs | 144 +++++++ .../Test/Semantic/Semantics/UnsafeTests.cs | 16 + .../Test/Semantic/Semantics/VarianceTests.cs | 26 ++ .../Syntax/Parsing/RefReadonlyReturnsTests.cs | 153 -------- .../Test/Syntax/Parsing/RefReadonlyTests.cs | 360 ++++++++++++++++++ 13 files changed, 939 insertions(+), 213 deletions(-) delete mode 100644 src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyReturnsTests.cs create mode 100644 src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs diff --git a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs index 174cd7d4b74ea..de7070338d218 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs @@ -517,7 +517,7 @@ private bool CheckParameterValueKind(SyntaxNode node, BoundParameter parameter, ParameterSymbol parameterSymbol = parameter.ParameterSymbol; // all parameters can be passed by ref/out or assigned to - // except "in" parameters, which are readonly + // except "ref readonly" parameters, which are readonly if (parameterSymbol.RefKind == RefKind.RefReadOnly && RequiresAssignableVariable(valueKind)) { ReportReadOnlyError(parameterSymbol, node, valueKind, checkingReceiver, diagnostics); @@ -959,7 +959,7 @@ bool isRefEscape //by default it is safe to escape uint escapeScope = Binder.ExternalScope; - ArrayBuilder inParametersMatchedWithArgs = null; + ArrayBuilder refReadOnlyParametersMatchedWithArgs = null; if (!argsOpt.IsDefault) { @@ -983,7 +983,7 @@ bool isRefEscape goto moreArguments; } - RefKind effectiveRefKind = GetEffectiveRefKind(argIndex, argRefKindsOpt, parameters, argsToParamsOpt, ref inParametersMatchedWithArgs); + RefKind effectiveRefKind = GetEffectiveRefKind(argIndex, argRefKindsOpt, parameters, argsToParamsOpt, ref refReadOnlyParametersMatchedWithArgs); // ref escape scope is the narrowest of // - ref escape of all byref arguments @@ -1001,7 +1001,7 @@ bool isRefEscape if (escapeScope >= scopeOfTheContainingExpression) { // no longer needed - inParametersMatchedWithArgs?.Free(); + refReadOnlyParametersMatchedWithArgs?.Free(); // can't get any worse return escapeScope; @@ -1009,12 +1009,12 @@ bool isRefEscape } } - // handle omitted optional "in" parameters if there are any - ParameterSymbol unmatchedInParameter = TryGetUnmatchedInParameterAndFreeMatchedArgs(parameters, ref inParametersMatchedWithArgs); + // handle omitted optional "ref readonly" parameters if there are any + ParameterSymbol unmatchedRefReadOnlyParameter = TryGetUnmatchedRefReadOnlyParameterAndFreeMatchedArgs(parameters, ref refReadOnlyParametersMatchedWithArgs); - // unmatched "in" parameter is the same as a literal, its ref escape is scopeOfTheContainingExpression (can't get any worse) + // unmatched "ref readonly" parameter is the same as a literal, its ref escape is scopeOfTheContainingExpression (can't get any worse) // its val escape is ExternalScope (does not affect overal result) - if (unmatchedInParameter != null && isRefEscape) + if (unmatchedRefReadOnlyParameter != null && isRefEscape) { return scopeOfTheContainingExpression; } @@ -1063,7 +1063,7 @@ bool isRefEscape receiverOpt = null; } - ArrayBuilder inParametersMatchedWithArgs = null; + ArrayBuilder refReadOnlyParametersMatchedWithArgs = null; if (!argsOpt.IsDefault) { @@ -1088,7 +1088,7 @@ bool isRefEscape goto moreArguments; } - RefKind effectiveRefKind = GetEffectiveRefKind(argIndex, argRefKindsOpt, parameters, argsToParamsOpt, ref inParametersMatchedWithArgs); + RefKind effectiveRefKind = GetEffectiveRefKind(argIndex, argRefKindsOpt, parameters, argsToParamsOpt, ref refReadOnlyParametersMatchedWithArgs); // ref escape scope is the narrowest of // - ref escape of all byref arguments @@ -1103,7 +1103,7 @@ bool isRefEscape if (!valid) { // no longer needed - inParametersMatchedWithArgs?.Free(); + refReadOnlyParametersMatchedWithArgs?.Free(); ErrorCode errorCode = GetStandardCallEscapeError(checkingReceiver); @@ -1124,14 +1124,14 @@ bool isRefEscape } } - // handle omitted optional "in" parameters if there are any - ParameterSymbol unmatchedInParameter = TryGetUnmatchedInParameterAndFreeMatchedArgs(parameters, ref inParametersMatchedWithArgs); + // handle omitted optional "ref readonly" parameters if there are any + ParameterSymbol unmatchedRefReadOnlyParameter = TryGetUnmatchedRefReadOnlyParameterAndFreeMatchedArgs(parameters, ref refReadOnlyParametersMatchedWithArgs); - // unmatched "in" parameter is the same as a literal, its ref escape is scopeOfTheContainingExpression (can't get any worse) + // unmatched "ref readonly" parameter is the same as a literal, its ref escape is scopeOfTheContainingExpression (can't get any worse) // its val escape is ExternalScope (does not affect overal result) - if (unmatchedInParameter != null && isRefEscape) + if (unmatchedRefReadOnlyParameter != null && isRefEscape) { - Error(diagnostics, GetStandardCallEscapeError(checkingReceiver), syntax, symbol, unmatchedInParameter.Name); + Error(diagnostics, GetStandardCallEscapeError(checkingReceiver), syntax, symbol, unmatchedRefReadOnlyParameter.Name); return false; } @@ -1276,15 +1276,15 @@ private static bool CheckInvocationArgMixing( /// /// Gets "effective" ref kind of an argument. /// Generally we know if a formal argument is passed as ref/out by looking at the call site. - /// However, to distinguish "in" and regular "val" parameters we need to take a look at corresponding parameter, if such exists. - /// NOTE: there are cases like params/vararg, when a corresponding parameter may not exist, then it cannot be an "in". + /// However, to distinguish "ref readonly" and regular "val" parameters we need to take a look at corresponding parameter, if such exists. + /// NOTE: there are cases like params/vararg, when a corresponding parameter may not exist, then it cannot be a "ref readonly". /// private static RefKind GetEffectiveRefKind( int argIndex, ImmutableArray argRefKindsOpt, ImmutableArray parameters, ImmutableArray argsToParamsOpt, - ref ArrayBuilder inParametersMatchedWithArgs) + ref ArrayBuilder refReadOnlyParametersMatchedWithArgs) { var effectiveRefKind = argRefKindsOpt.IsDefault ? RefKind.None : argRefKindsOpt[argIndex]; if (effectiveRefKind == RefKind.None && argIndex < parameters.Length) @@ -1294,8 +1294,8 @@ private static RefKind GetEffectiveRefKind( if (parameters[paramIndex].RefKind == RefKind.RefReadOnly) { effectiveRefKind = RefKind.RefReadOnly; - inParametersMatchedWithArgs = inParametersMatchedWithArgs ?? ArrayBuilder.GetInstance(parameters.Length, fillWithValue: false); - inParametersMatchedWithArgs[paramIndex] = true; + refReadOnlyParametersMatchedWithArgs = refReadOnlyParametersMatchedWithArgs ?? ArrayBuilder.GetInstance(parameters.Length, fillWithValue: false); + refReadOnlyParametersMatchedWithArgs[paramIndex] = true; } } @@ -1303,11 +1303,11 @@ private static RefKind GetEffectiveRefKind( } /// - /// Gets an "in" parameter for which there is no argument supplied, if such exists. - /// That indicates an optional "in" parameter. We treat it as an RValue passed by reference via a temporary. + /// Gets a "ref readonly" parameter for which there is no argument supplied, if such exists. + /// That indicates an optional "ref readonly" parameter. We treat it as an RValue passed by reference via a temporary. /// The effective scope of such variable is the immediately containing scope. /// - private static ParameterSymbol TryGetUnmatchedInParameterAndFreeMatchedArgs(ImmutableArray parameters, ref ArrayBuilder inParametersMatchedWithArgs) + private static ParameterSymbol TryGetUnmatchedRefReadOnlyParameterAndFreeMatchedArgs(ImmutableArray parameters, ref ArrayBuilder refReadOnlyParametersMatchedWithArgs) { try { @@ -1322,7 +1322,7 @@ private static ParameterSymbol TryGetUnmatchedInParameterAndFreeMatchedArgs(Immu } if (parameter.RefKind == RefKind.RefReadOnly && - inParametersMatchedWithArgs?[i] != true && + refReadOnlyParametersMatchedWithArgs?[i] != true && parameter.Type.IsByRefLikeType == false) { return parameter; @@ -1334,9 +1334,9 @@ private static ParameterSymbol TryGetUnmatchedInParameterAndFreeMatchedArgs(Immu } finally { - inParametersMatchedWithArgs?.Free(); + refReadOnlyParametersMatchedWithArgs?.Free(); // make sure noone uses it after. - inParametersMatchedWithArgs = null; + refReadOnlyParametersMatchedWithArgs = null; } } diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs index a0ba5e2462970..6742c711fdd7c 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs @@ -2577,7 +2577,7 @@ private RefKind GetEffectiveParameterRefKind(ParameterSymbol parameter, RefKind if (paramRefKind == RefKind.RefReadOnly) { - // "in" parameters are effectively None for the purpose of overload resolution. + // "ref readonly" parameters are effectively None for the purpose of overload resolution. paramRefKind = RefKind.None; } diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeExtensions.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeExtensions.cs index 5b163542dbb61..e5d65c9153164 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeExtensions.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxNodeExtensions.cs @@ -130,12 +130,12 @@ internal static bool IsLegalSpanStackAllocPosition(this SyntaxNode node) { Debug.Assert(node != null); - while (node.Parent.IsKind(SyntaxKind.CastExpression)) + if (node.Parent.IsKind(SyntaxKind.CastExpression)) { node = node.Parent; } - if (node.Parent.IsKind(SyntaxKind.ConditionalExpression)) + while (node.Parent.IsKind(SyntaxKind.ConditionalExpression)) { node = node.Parent; } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs index 2ed43f5c115e9..c1033b9540c12 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs @@ -1563,5 +1563,24 @@ .locals init (T V_0) }"); } + [Fact] + public void RefReadOnlyOptionalParameters() + { + CompileAndVerify(@" +using System; +class Program +{ + static void Print(ref readonly int p = 5) + { + Console.Write(p); + } + static void Main() + { + Print(); + Console.Write(""-""); + Print(9); + } +}", expectedOutput: "5-9"); + } } } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs index a0eb06901ae81..52a22b962ad36 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs @@ -1158,5 +1158,220 @@ .maxstack 1 IL_0001: throw }"); } + + [Fact] + public void RefExtensionMethod_PassThrough_LocalNoCopying() + { + CompileAndVerify(@" +public static class Ext +{ + public static ref int M(ref this int p) => ref p; +} +class Test +{ + void M() + { + int x = 5; + x.M(); + } +}", additionalRefs: new[] { SystemCoreRef }, verify: false).VerifyIL("Test.M", @" +{ + // Code size 11 (0xb) + .maxstack 1 + .locals init (int V_0) //x + IL_0000: ldc.i4.5 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call ""ref int Ext.M(ref int)"" + IL_0009: pop + IL_000a: ret +}"); + } + + [Fact] + public void RefExtensionMethod_PassThrough_FieldNoCopying() + { + CompileAndVerify(@" +public static class Ext +{ + public static ref int M(ref this int p) => ref p; +} +class Test +{ + private int x = 5; + void M() + { + x.M(); + } +}", additionalRefs: new[] { SystemCoreRef }, verify: false).VerifyIL("Test.M", @" +{ + // Code size 13 (0xd) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ldflda ""int Test.x"" + IL_0006: call ""ref int Ext.M(ref int)"" + IL_000b: pop + IL_000c: ret +}"); + } + + [Fact] + public void RefExtensionMethod_PassThrough_ChainNoCopying() + { + CompileAndVerify(@" +public static class Ext +{ + public static ref int M(ref this int p) => ref p; +} +class Test +{ + private int x = 5; + void M() + { + x.M().M().M(); + } +}", additionalRefs: new[] { SystemCoreRef }, verify: false).VerifyIL("Test.M", @" +{ + // Code size 23 (0x17) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ldflda ""int Test.x"" + IL_0006: call ""ref int Ext.M(ref int)"" + IL_000b: call ""ref int Ext.M(ref int)"" + IL_0010: call ""ref int Ext.M(ref int)"" + IL_0015: pop + IL_0016: ret +}"); + } + + [Fact] + public void RefReadOnlyExtensionMethod_PassThrough_TempCopying() + { + CompileAndVerify(@" +public static class Ext +{ + public static ref readonly int M(ref readonly this int p) => ref p; +} +class Test +{ + void M() + { + 5.M(); + } +}", additionalRefs: new[] { SystemCoreRef }, verify: false).VerifyIL("Test.M", @" +{ + // Code size 11 (0xb) + .maxstack 1 + .locals init (int V_0) + IL_0000: ldc.i4.5 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call ""ref readonly int Ext.M(ref readonly int)"" + IL_0009: pop + IL_000a: ret +}"); + } + + [Fact] + public void RefReadOnlyExtensionMethod_PassThrough_LocalNoCopying() + { + CompileAndVerify(@" +public static class Ext +{ + public static ref readonly int M(ref readonly this int p) => ref p; +} +class Test +{ + void M() + { + int x = 5; + x.M(); + } +}", additionalRefs: new[] { SystemCoreRef }, verify: false).VerifyIL("Test.M", @" +{ + // Code size 11 (0xb) + .maxstack 1 + .locals init (int V_0) //x + IL_0000: ldc.i4.5 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call ""ref readonly int Ext.M(ref readonly int)"" + IL_0009: pop + IL_000a: ret +}"); + } + + [Fact] + public void RefReadOnlyExtensionMethod_PassThrough_FieldNoCopying() + { + CompileAndVerify(@" +public static class Ext +{ + public static ref readonly int M(ref readonly this int p) => ref p; +} +class Test +{ + private int x = 5; + void M() + { + x.M(); + } +}", additionalRefs: new[] { SystemCoreRef }, verify: false).VerifyIL("Test.M", @" +{ + // Code size 13 (0xd) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ldflda ""int Test.x"" + IL_0006: call ""ref readonly int Ext.M(ref readonly int)"" + IL_000b: pop + IL_000c: ret +}"); + } + + [Fact] + public void RefReadOnlyExtensionMethod_PassThrough_ChainNoCopying() + { + CompileAndVerify(@" +public static class Ext +{ + public static ref readonly int M(ref readonly this int p) => ref p; +} +class Test +{ + private int x = 5; + void M() + { + x.M().M().M(); + } +}", additionalRefs: new[] { SystemCoreRef }, verify: false).VerifyIL("Test.M", @" +{ + // Code size 23 (0x17) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ldflda ""int Test.x"" + IL_0006: call ""ref readonly int Ext.M(ref readonly int)"" + IL_000b: call ""ref readonly int Ext.M(ref readonly int)"" + IL_0010: call ""ref readonly int Ext.M(ref readonly int)"" + IL_0015: pop + IL_0016: ret +}"); + } + + [Fact] + public void RefReadOnlyReturnOptionalValue() + { + CompileAndVerify(@" +class Program +{ + static ref readonly string M(ref readonly string s = ""optional"") => ref s; + + static void Main() + { + System.Console.Write(M()); + System.Console.Write(""-""); + System.Console.Write(M(""provided"")); + } +}", verify: false, expectedOutput: "optional-provided"); + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs index 203360f3361c4..7a64be353844d 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs @@ -1326,5 +1326,22 @@ public static void Main(string[] args) var compilation = CreateCompilationWithMscorlib45(source, null, new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithAllowUnsafe(true)); CompileAndVerify(compilation, expectedOutput: "normalField fixedField").VerifyDiagnostics(); } + + [Fact] + public void PassingNameOfToRefReadOnlyShouldCopy() + { + CompileAndVerify(@" +class Program +{ + public static void Main() + { + M(nameof(Main)); + } + private static void M(ref readonly string value) + { + System.Console.WriteLine(value); + } +}", expectedOutput: "Main"); + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs index fb3573e2dd8fd..bb2273b1b1af9 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs @@ -2696,5 +2696,77 @@ async Task TestMethod() Diagnostic(ErrorCode.ERR_RefReturningCallAndAwait, "await Task.FromResult(1)").WithArguments("TestClass.this[int, int].get").WithLocation(36, 22) ); } + + [Fact] + public void RefReadOnlyInAsyncMethodDisallowed() + { + CreateCompilationWithMscorlib45(@" +using System.Threading.Tasks; +class Test +{ + async Task Method(ref readonly int p) + { + await Task.FromResult(0); + } +}").VerifyDiagnostics( + // (5,40): error CS1988: Async methods cannot have ref or out parameters + // async Task Method(ref readonly int p) + Diagnostic(ErrorCode.ERR_BadAsyncArgType, "p").WithLocation(5, 40)); + } + + [Fact] + public void RefReadOnlyInIteratorMethodsDisallowed() + { + CreateCompilationWithMscorlib45(@" +using System.Collections.Generic; +class Test +{ + IEnumerable Method(ref readonly int p) + { + yield return 0; + yield return 1; + yield return 2; + } +}").VerifyDiagnostics( + // (5,46): error CS1623: Iterators cannot have ref or out parameters + // IEnumerable Method(ref readonly int p) + Diagnostic(ErrorCode.ERR_BadIteratorArgType, "p").WithLocation(5, 46)); + } + + [Fact] + public void RefReadOnlyInEnumeratorMethodsDisallowed() + { + CreateStandardCompilation(@" +using System.Collections.Generic; +class Test +{ + public IEnumerator GetEnumerator(ref readonly int p) + { + yield return 0; + } +}").VerifyDiagnostics( + // (5,60): error CS1623: Iterators cannot have ref or out parameters + // public IEnumerator GetEnumerator(ref readonly int p) + Diagnostic(ErrorCode.ERR_BadIteratorArgType, "p").WithLocation(5, 60)); + } + + [Fact] + public void CannotCallRefReadOnlyMethodsUsingDiscardParameter() + { + CreateStandardCompilation(@" +class Test +{ + void M(ref readonly int p) + { + } + void N() + { + M(_); + } +}").VerifyDiagnostics( + // (9,11): error CS0103: The name '_' does not exist in the current context + // M(_); + Diagnostic(ErrorCode.ERR_NameNotInContext, "_").WithArguments("_").WithLocation(9, 11)); + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs index e9c95622e828e..72562a7948b79 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs @@ -8536,41 +8536,51 @@ unsafe public static void Main() } [Fact] - public void CS0255ERR_StackallocInCatchFinally() + public void CS0255ERR_StackallocInFinally() { var text = @" -using System; - -public class TestTryFinally +unsafe class Test { - public static unsafe void Test() - { - int i = 123; - string s = ""Some string""; - object o = s; - - try - { - // Conversion is not valid; o contains a string not an int - i = (int) o; - } - - finally - { - Console.Write(""i = {0}"", i); - int* fib = stackalloc int[100]; // CS0255 - } - } + void M() + { + try + { + // Something + } + finally + { + int* fib = stackalloc int[100]; + } + } +}"; + CreateStandardCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (12,24): error CS0255: stackalloc may not be used in a catch or finally block + // int* fib = stackalloc int[100]; + Diagnostic(ErrorCode.ERR_StackallocInCatchFinally, "stackalloc int[100]").WithLocation(12, 24)); + } - public static void Main() - { - } -} -"; + [Fact] + public void CS0255ERR_StackallocInCatch() + { + var text = @" +unsafe class Test +{ + void M() + { + try + { + // Something + } + catch + { + int* fib = stackalloc int[100]; + } + } +}"; CreateStandardCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( - // (21,21): error CS0255: stackalloc may not be used in a catch or finally block - // int* fib = stackalloc int[100]; // CS0255 - Diagnostic(ErrorCode.ERR_StackallocInCatchFinally, "stackalloc int[100]")); + // (12,24): error CS0255: stackalloc may not be used in a catch or finally block + // int* fib = stackalloc int[100]; + Diagnostic(ErrorCode.ERR_StackallocInCatchFinally, "stackalloc int[100]").WithLocation(12, 24)); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocSpanExpressionsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocSpanExpressionsTests.cs index 5f55c9f2bec66..15e546e292181 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocSpanExpressionsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocSpanExpressionsTests.cs @@ -303,6 +303,29 @@ void M() Diagnostic(ErrorCode.ERR_InvalidQM, "true ? stackalloc int [10] : a").WithArguments("stackalloc int[10]", "System.Span").WithLocation(8, 17)); } + [Fact] + public void ConditionalExpressionOnSpan_Nested() + { + CreateCompilationWithMscorlibAndSpan(@" +class Test +{ + bool N() => true; + + void M() + { + var x = N() + ? N() + ? stackalloc int [1] + : stackalloc int [2] + : N() + ? stackalloc int[3] + : N() + ? stackalloc int[4] + : stackalloc int[5]; + } +}", TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + [Fact] public void BooleanOperatorOnSpan_NoTargetTyping() { @@ -342,6 +365,22 @@ void M() Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "stackalloc int[10]").WithArguments("ref structs", "7.2").WithLocation(7, 23)); } + [Fact] + public void StackAllocSyntaxProducesUnsafeErrorInSafeCode() + { + CreateStandardCompilation(@" +class Test +{ + void M() + { + var x = stackalloc int[10]; + } +}", options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (6,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // var x = stackalloc int[10]; + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "stackalloc int[10]").WithLocation(6, 17)); + } + [Fact] public void StackAllocInUsing1() { @@ -508,5 +547,110 @@ static void Main() Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(7, 16) ); } + + [Fact] + public void StackAllocWithDynamic() + { + CreateStandardCompilation(@" +class Program +{ + static void Main() + { + var d = stackalloc dynamic[10]; + } +}").VerifyDiagnostics( + // (6,33): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('dynamic') + // var d = stackalloc dynamic[10]; + Diagnostic(ErrorCode.ERR_ManagedAddr, "dynamic").WithArguments("dynamic").WithLocation(6, 28)); + } + + [Fact] + public void StackAllocWithDynamicSpan() + { + CreateCompilationWithMscorlibAndSpan(@" +using System; +class Program +{ + static void Main() + { + Span d = stackalloc dynamic[10]; + } +}").VerifyDiagnostics( + // (7,38): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('dynamic') + // Span d = stackalloc dynamic[10]; + Diagnostic(ErrorCode.ERR_ManagedAddr, "dynamic").WithArguments("dynamic").WithLocation(7, 38)); + } + + [Fact] + public void StackAllocAsArgument() + { + CreateStandardCompilation(@" +class Program +{ + static void N(object p) { } + + static void Main() + { + N(stackalloc int[10]); + } +}").VerifyDiagnostics( + // (8,11): error CS1525: Invalid expression term 'stackalloc' + // N(stackalloc int[10]); + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(8, 11)); + } + + [Fact] + public void StackAllocInParenthesis() + { + CreateStandardCompilation(@" +class Program +{ + static void Main() + { + var x = (stackalloc int[10]); + } +}").VerifyDiagnostics( + // (6,18): error CS1525: Invalid expression term 'stackalloc' + // var x = (stackalloc int[10]); + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(6, 18)); + } + + [Fact] + public void StackAllocInNullConditionalOperator() + { + CreateStandardCompilation(@" +class Program +{ + static void Main() + { + var x = stackalloc int[1] ?? stackalloc int[2]; + } +}").VerifyDiagnostics( + // (6,17): error CS1525: Invalid expression term 'stackalloc' + // var x = stackalloc int[1] ?? stackalloc int[2]; + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(6, 17), + // (6,38): error CS1525: Invalid expression term 'stackalloc' + // var x = stackalloc int[1] ?? stackalloc int[2]; + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(6, 38)); + } + + [Fact] + public void StackAllocInCastAndConditionalOperator() + { + CreateCompilationWithMscorlibAndSpan(@" +using System; +class Test +{ + public void Method() + { + Test value = true ? new Test() : (Test)stackalloc int[10]; + } + + public static explicit operator Test(Span value) + { + return new Test(); + } +}", TestOptions.ReleaseDll).VerifyDiagnostics(); + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs index 559c9c11a431a..7c0dadb31601b 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs @@ -8561,6 +8561,22 @@ static unsafe void Main() CompileAndVerify(text, options: TestOptions.UnsafeReleaseExe, expectedOutput: @"4812"); } + [Fact] + public void CannotTakeAddressOfRefReadOnlyParameter() + { + CreateStandardCompilation(@" +public class Test +{ + unsafe void M(ref readonly int p) + { + int* pointer = &p; + } +}", options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (6,25): error CS0211: Cannot take the address of the given expression + // int* pointer = &p; + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "p").WithLocation(6, 25)); + } + #endregion } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/VarianceTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/VarianceTests.cs index 16db7be15c2a0..5793ce918b456 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/VarianceTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/VarianceTests.cs @@ -627,5 +627,31 @@ interface I : // interface I : Diagnostic(ErrorCode.ERR_UnexpectedVariance, "T").WithArguments("I", "T", "covariant", "contravariantly").WithLocation(14, 17)); } + + [Fact] + public void CovarianceBoundariesForRefReadOnly_Parameters() + { + CreateStandardCompilation(@" +interface ITest +{ + void M(ref readonly T p); +}").VerifyDiagnostics( + // (4,25): error CS1961: Invalid variance: The type parameter 'T' must be invariantly valid on 'ITest.M(ref readonly T)'. 'T' is contravariant. + // void M(ref readonly T p); + Diagnostic(ErrorCode.ERR_UnexpectedVariance, "T").WithArguments("ITest.M(ref readonly T)", "T", "contravariant", "invariantly").WithLocation(4, 25)); + } + + [Fact] + public void CovarianceBoundariesForRefReadOnly_ReturnType() + { + CreateStandardCompilation(@" +interface ITest +{ + ref readonly T M(); +}").VerifyDiagnostics( + // (4,5): error CS1961: Invalid variance: The type parameter 'T' must be invariantly valid on 'ITest.M()'. 'T' is contravariant. + // ref readonly T M(); + Diagnostic(ErrorCode.ERR_UnexpectedVariance, "ref readonly T").WithArguments("ITest.M()", "T", "contravariant", "invariantly").WithLocation(4, 5)); + } } } diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyReturnsTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyReturnsTests.cs deleted file mode 100644 index b33ce2f9a2b39..0000000000000 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyReturnsTests.cs +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Xunit; -using System.Linq; -using Microsoft.CodeAnalysis.CSharp.Test.Utilities; -using Microsoft.CodeAnalysis.Test.Utilities; -using Roslyn.Test.Utilities; -using Xunit.Abstractions; - -namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Parsing -{ - [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public class RefReadonlyReturnsTests : ParsingTests - { - public RefReadonlyReturnsTests(ITestOutputHelper output) : base(output) { } - - protected override SyntaxTree ParseTree(string text, CSharpParseOptions options) - { - return SyntaxFactory.ParseSyntaxTree(text, options: options); - } - - [Fact] - public void RefReadonlyReturn_CSharp7() - { - var text = @" -unsafe class Program -{ - delegate ref readonly int D1(); - - static ref readonly T M() - { - return ref (new T[1])[0]; - } - - public virtual ref readonly int* P1 => throw null; - - public ref readonly int[][] this[int i] => throw null; -} -"; - - var comp = CreateCompilationWithMscorlib45(text, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_1), options: TestOptions.UnsafeDebugDll); - comp.VerifyDiagnostics( - // (4,18): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. - // delegate ref readonly int D1(); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "readonly").WithArguments("readonly references", "7.2").WithLocation(4, 18), - // (6,16): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. - // static ref readonly T M() - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "readonly").WithArguments("readonly references", "7.2").WithLocation(6, 16), - // (11,24): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. - // public virtual ref readonly int* P1 => throw null; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "readonly").WithArguments("readonly references", "7.2").WithLocation(11, 24), - // (13,16): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. - // public ref readonly int[][] this[int i] => throw null; - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "readonly").WithArguments("readonly references", "7.2").WithLocation(13, 16) - ); - } - - [Fact] - public void RefReadonlyReturn_Unexpected() - { - var text = @" - -class Program -{ - static void Main() - { - } - - ref readonly int Field; - - public static ref readonly Program operator +(Program x, Program y) - { - throw null; - } - - // this parses fine - static async ref readonly Task M() - { - throw null; - } - - public ref readonly virtual int* P1 => throw null; - -} -"; - - ParseAndValidate(text, TestOptions.Regular, - // (9,27): error CS1003: Syntax error, '(' expected - // ref readonly int Field; - Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments("(", ";").WithLocation(9, 27), - // (9,27): error CS1026: ) expected - // ref readonly int Field; - Diagnostic(ErrorCode.ERR_CloseParenExpected, ";").WithLocation(9, 27), - // (11,41): error CS1519: Invalid token 'operator' in class, struct, or interface member declaration - // public static ref readonly Program operator +(Program x, Program y) - Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "operator").WithArguments("operator").WithLocation(11, 41), - // (11,41): error CS1519: Invalid token 'operator' in class, struct, or interface member declaration - // public static ref readonly Program operator +(Program x, Program y) - Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "operator").WithArguments("operator").WithLocation(11, 41), - // (12,5): error CS1519: Invalid token '{' in class, struct, or interface member declaration - // { - Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(12, 5), - // (12,5): error CS1519: Invalid token '{' in class, struct, or interface member declaration - // { - Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(12, 5), - // (22,25): error CS1031: Type expected - // public ref readonly virtual int* P1 => throw null; - Diagnostic(ErrorCode.ERR_TypeExpected, "virtual").WithLocation(22, 25), - // (24,1): error CS1022: Type or namespace definition, or end-of-file expected - // } - Diagnostic(ErrorCode.ERR_EOFExpected, "}").WithLocation(24, 1)); - } - - [Fact] - public void RefReadonlyReturn_UnexpectedBindTime() - { - var text = @" - -class Program -{ - static void Main() - { - ref readonly int local = ref (new int[1])[0]; - - (ref readonly int, ref readonly int Alice)? t = null; - - System.Collections.Generic.List x = null; - - Use(local); - Use(t); - Use(x); - } - - static void Use(T dummy) - { - } -} -"; - var comp = CreateCompilationWithMscorlib45(text, new[] { ValueTupleRef, SystemRuntimeFacadeRef }); - comp.VerifyDiagnostics( - // (9,10): error CS1073: Unexpected token 'ref' - // (ref readonly int, ref readonly int Alice)? t = null; - Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(9, 10), - // (9,28): error CS1073: Unexpected token 'ref' - // (ref readonly int, ref readonly int Alice)? t = null; - Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(9, 28), - // (11,41): error CS1073: Unexpected token 'ref' - // System.Collections.Generic.List x = null; - Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(11, 41) - ); - } - } -} diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs new file mode 100644 index 0000000000000..72ec9b178a76b --- /dev/null +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs @@ -0,0 +1,360 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Xunit; +using System.Linq; +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; +using Xunit.Abstractions; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Parsing +{ + [CompilerTrait(CompilerFeature.ReadOnlyReferences)] + public class RefReadonlyTests : ParsingTests + { + public RefReadonlyTests(ITestOutputHelper output) : base(output) { } + + protected override SyntaxTree ParseTree(string text, CSharpParseOptions options) + { + return SyntaxFactory.ParseSyntaxTree(text, options: options); + } + + [Fact] + public void RefReadonlyReturn_CSharp7() + { + var text = @" +unsafe class Program +{ + delegate ref readonly int D1(); + + static ref readonly T M() + { + return ref (new T[1])[0]; + } + + public virtual ref readonly int* P1 => throw null; + + public ref readonly int[][] this[int i] => throw null; +} +"; + + var comp = CreateCompilationWithMscorlib45(text, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_1), options: TestOptions.UnsafeDebugDll); + comp.VerifyDiagnostics( + // (4,18): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. + // delegate ref readonly int D1(); + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "readonly").WithArguments("readonly references", "7.2").WithLocation(4, 18), + // (6,16): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. + // static ref readonly T M() + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "readonly").WithArguments("readonly references", "7.2").WithLocation(6, 16), + // (11,24): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. + // public virtual ref readonly int* P1 => throw null; + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "readonly").WithArguments("readonly references", "7.2").WithLocation(11, 24), + // (13,16): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. + // public ref readonly int[][] this[int i] => throw null; + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "readonly").WithArguments("readonly references", "7.2").WithLocation(13, 16) + ); + } + + [Fact] + public void RefReadonlyReturn_Unexpected() + { + var text = @" + +class Program +{ + static void Main() + { + } + + ref readonly int Field; + + public static ref readonly Program operator +(Program x, Program y) + { + throw null; + } + + // this parses fine + static async ref readonly Task M() + { + throw null; + } + + public ref readonly virtual int* P1 => throw null; + +} +"; + + ParseAndValidate(text, TestOptions.Regular, + // (9,27): error CS1003: Syntax error, '(' expected + // ref readonly int Field; + Diagnostic(ErrorCode.ERR_SyntaxError, ";").WithArguments("(", ";").WithLocation(9, 27), + // (9,27): error CS1026: ) expected + // ref readonly int Field; + Diagnostic(ErrorCode.ERR_CloseParenExpected, ";").WithLocation(9, 27), + // (11,41): error CS1519: Invalid token 'operator' in class, struct, or interface member declaration + // public static ref readonly Program operator +(Program x, Program y) + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "operator").WithArguments("operator").WithLocation(11, 41), + // (11,41): error CS1519: Invalid token 'operator' in class, struct, or interface member declaration + // public static ref readonly Program operator +(Program x, Program y) + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "operator").WithArguments("operator").WithLocation(11, 41), + // (12,5): error CS1519: Invalid token '{' in class, struct, or interface member declaration + // { + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(12, 5), + // (12,5): error CS1519: Invalid token '{' in class, struct, or interface member declaration + // { + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "{").WithArguments("{").WithLocation(12, 5), + // (22,25): error CS1031: Type expected + // public ref readonly virtual int* P1 => throw null; + Diagnostic(ErrorCode.ERR_TypeExpected, "virtual").WithLocation(22, 25), + // (24,1): error CS1022: Type or namespace definition, or end-of-file expected + // } + Diagnostic(ErrorCode.ERR_EOFExpected, "}").WithLocation(24, 1)); + } + + [Fact] + public void RefReadonlyReturn_UnexpectedBindTime() + { + var text = @" + +class Program +{ + static void Main() + { + ref readonly int local = ref (new int[1])[0]; + + (ref readonly int, ref readonly int Alice)? t = null; + + System.Collections.Generic.List x = null; + + Use(local); + Use(t); + Use(x); + } + + static void Use(T dummy) + { + } +} +"; + var comp = CreateCompilationWithMscorlib45(text, new[] { ValueTupleRef, SystemRuntimeFacadeRef }); + comp.VerifyDiagnostics( + // (9,10): error CS1073: Unexpected token 'ref' + // (ref readonly int, ref readonly int Alice)? t = null; + Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(9, 10), + // (9,28): error CS1073: Unexpected token 'ref' + // (ref readonly int, ref readonly int Alice)? t = null; + Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(9, 28), + // (11,41): error CS1073: Unexpected token 'ref' + // System.Collections.Generic.List x = null; + Diagnostic(ErrorCode.ERR_UnexpectedToken, "ref").WithArguments("ref").WithLocation(11, 41)); + } + + [Fact] + public void RefReadOnlyLocalsAreDisallowed() + { + CreateStandardCompilation(@" +class Test +{ + void M() + { + int value = 0; + ref int valid = ref value; + ref readonly int invalid = ref readonly value; + } +}").GetParseDiagnostics().Verify( + // (8,40): error CS1525: Invalid expression term 'readonly' + // ref readonly int invalid = ref readonly value; + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "readonly").WithArguments("readonly").WithLocation(8, 40), + // (8,40): error CS1002: ; expected + // ref readonly int invalid = ref readonly value; + Diagnostic(ErrorCode.ERR_SemicolonExpected, "readonly").WithLocation(8, 40), + // (8,40): error CS0106: The modifier 'readonly' is not valid for this item + // ref readonly int invalid = ref readonly value; + Diagnostic(ErrorCode.ERR_BadMemberFlag, "readonly").WithArguments("readonly").WithLocation(8, 40), + // (8,54): error CS1001: Identifier expected + // ref readonly int invalid = ref readonly value; + Diagnostic(ErrorCode.ERR_IdentifierExpected, ";").WithLocation(8, 54)); + } + + [Fact] + public void LocalsWithRefReadOnlyExpressionsAreDisallowed() + { + CreateStandardCompilation(@" +class Test +{ + void M() + { + int value = 0; + ref int valid = ref value; + ref int invalid = ref readonly value; + } +}").GetParseDiagnostics().Verify( + // (8,31): error CS1525: Invalid expression term 'readonly' + // ref int invalid = ref readonly value; + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "readonly").WithArguments("readonly").WithLocation(8, 31), + // (8,31): error CS1002: ; expected + // ref int invalid = ref readonly value; + Diagnostic(ErrorCode.ERR_SemicolonExpected, "readonly").WithLocation(8, 31), + // (8,31): error CS0106: The modifier 'readonly' is not valid for this item + // ref int invalid = ref readonly value; + Diagnostic(ErrorCode.ERR_BadMemberFlag, "readonly").WithArguments("readonly").WithLocation(8, 31), + // (8,45): error CS1001: Identifier expected + // ref int invalid = ref readonly value; + Diagnostic(ErrorCode.ERR_IdentifierExpected, ";").WithLocation(8, 45)); + } + + [Fact] + public void ReturnRefReadOnlyAreDisallowed() + { + CreateStandardCompilation(@" +class Test +{ + int value = 0; + + ref readonly int Valid() => ref value; + ref readonly int Invalid() => ref readonly value; + +}").GetParseDiagnostics().Verify( + // (7,39): error CS1525: Invalid expression term 'readonly' + // ref readonly int Invalid() => ref readonly value; + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "readonly").WithArguments("readonly").WithLocation(7, 39), + // (7,39): error CS1002: ; expected + // ref readonly int Invalid() => ref readonly value; + Diagnostic(ErrorCode.ERR_SemicolonExpected, "readonly").WithLocation(7, 39), + // (7,53): error CS1519: Invalid token ';' in class, struct, or interface member declaration + // ref readonly int Invalid() => ref readonly value; + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(7, 53), + // (7,53): error CS1519: Invalid token ';' in class, struct, or interface member declaration + // ref readonly int Invalid() => ref readonly value; + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, ";").WithArguments(";").WithLocation(7, 53)); + } + + [Fact] + public void RefReadOnlyForEachAreDisallowed() + { + CreateStandardCompilation(@" +class Test +{ + void M() + { + var ar = new int[] { 1, 2, 3 }; + + foreach(ref readonly v in ar) + { + } + } +}").GetParseDiagnostics().Verify( + // (8,17): error CS1525: Invalid expression term 'ref' + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "ref").WithArguments("ref").WithLocation(8, 17), + // (8,17): error CS1515: 'in' expected + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_InExpected, "ref").WithLocation(8, 17), + // (8,17): error CS0230: Type and identifier are both required in a foreach statement + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_BadForeachDecl, "ref").WithLocation(8, 17), + // (8,17): error CS1525: Invalid expression term 'ref' + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "ref").WithArguments("ref").WithLocation(8, 17), + // (8,17): error CS1026: ) expected + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_CloseParenExpected, "ref").WithLocation(8, 17), + // (8,32): error CS1001: Identifier expected + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_IdentifierExpected, "in").WithLocation(8, 32), + // (8,32): error CS1003: Syntax error, ',' expected + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_SyntaxError, "in").WithArguments(",", "in").WithLocation(8, 32), + // (8,35): error CS1002: ; expected + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_SemicolonExpected, "ar").WithLocation(8, 35), + // (8,37): error CS1002: ; expected + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_SemicolonExpected, ")").WithLocation(8, 37), + // (8,37): error CS1513: } expected + // foreach(ref readonly v in ar) + Diagnostic(ErrorCode.ERR_RbraceExpected, ")").WithLocation(8, 37)); + } + + [Fact] + public void RefReadOnlyAtCallSite() + { + CreateStandardCompilation(@" +class Test +{ + void M(ref readonly int p) + { + } + void N() + { + int x = 0; + M(ref readonly x); + } +}").GetParseDiagnostics().Verify( + // (10,15): error CS1525: Invalid expression term 'readonly' + // M(ref readonly x); + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "readonly").WithArguments("readonly").WithLocation(10, 15), + // (10,15): error CS1026: ) expected + // M(ref readonly x); + Diagnostic(ErrorCode.ERR_CloseParenExpected, "readonly").WithLocation(10, 15), + // (10,15): error CS1002: ; expected + // M(ref readonly x); + Diagnostic(ErrorCode.ERR_SemicolonExpected, "readonly").WithLocation(10, 15), + // (10,15): error CS0106: The modifier 'readonly' is not valid for this item + // M(ref readonly x); + Diagnostic(ErrorCode.ERR_BadMemberFlag, "readonly").WithArguments("readonly").WithLocation(10, 15), + // (10,25): error CS1001: Identifier expected + // M(ref readonly x); + Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(10, 25), + // (10,25): error CS1002: ; expected + // M(ref readonly x); + Diagnostic(ErrorCode.ERR_SemicolonExpected, ")").WithLocation(10, 25), + // (10,25): error CS1513: } expected + // M(ref readonly x); + Diagnostic(ErrorCode.ERR_RbraceExpected, ")").WithLocation(10, 25)); + } + + [Fact] + public void InverseReadOnlyRefShouldBeIllegal() + { + CreateStandardCompilation(@" +class Test +{ + void M(readonly ref int p) + { + } +}").GetParseDiagnostics().Verify( + // (4,12): error CS1026: ) expected + // void M(readonly ref int p) + Diagnostic(ErrorCode.ERR_CloseParenExpected, "readonly").WithLocation(4, 12), + // (4,12): error CS1002: ; expected + // void M(readonly ref int p) + Diagnostic(ErrorCode.ERR_SemicolonExpected, "readonly").WithLocation(4, 12), + // (4,30): error CS1003: Syntax error, '(' expected + // void M(readonly ref int p) + Diagnostic(ErrorCode.ERR_SyntaxError, ")").WithArguments("(", ")").WithLocation(4, 30)); + } + + [Fact] + public void RefReadOnlyReturnIllegalInOperators() + { + CreateStandardCompilation(@" +public class Test +{ + public static ref readonly bool operator!(Test obj) => throw null; +}").GetParseDiagnostics().Verify( + // (4,37): error CS1519: Invalid token 'operator' in class, struct, or interface member declaration + // public static ref readonly bool operator!(Test obj) => throw null; + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "operator").WithArguments("operator").WithLocation(4, 37), + // (4,37): error CS1519: Invalid token 'operator' in class, struct, or interface member declaration + // public static ref readonly bool operator!(Test obj) => throw null; + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "operator").WithArguments("operator").WithLocation(4, 37), + // (4,55): error CS8124: Tuple must contain at least two elements. + // public static ref readonly bool operator!(Test obj) => throw null; + Diagnostic(ErrorCode.ERR_TupleTooFewElements, ")").WithLocation(4, 55), + // (4,57): error CS1519: Invalid token '=>' in class, struct, or interface member declaration + // public static ref readonly bool operator!(Test obj) => throw null; + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=>").WithArguments("=>").WithLocation(4, 57)); + } + } +} From 999e20ef5189b54d59339d37c77fdf0e429233bb Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Thu, 28 Sep 2017 19:09:51 -0700 Subject: [PATCH 07/16] Fix serialization of attribute data to account for named params argument (#22231) --- .../Portable/Binder/Binder_Attributes.cs | 88 ++++-- .../Test/Emit/Attributes/AttributeTests.cs | 281 +++++++++++++++++- .../Test/Emit/Attributes/AttributeTests.vb | 48 +++ 3 files changed, 394 insertions(+), 23 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Attributes.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Attributes.cs index 129206660b4b0..bb08a3f3c947d 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Attributes.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Attributes.cs @@ -578,8 +578,12 @@ private ImmutableArray GetRewrittenAttributeConstructorArguments( if (parameter.IsParams && parameter.Type.IsSZArray() && i + 1 == parameterCount) { - reorderedArgument = GetParamArrayArgument(parameter, constructorArgsArray, argumentsCount, argsConsumedCount, this.Conversions); - sourceIndices = sourceIndices ?? CreateSourceIndicesArray(i, parameterCount); + reorderedArgument = GetParamArrayArgument(parameter, constructorArgsArray, constructorArgumentNamesOpt, argumentsCount, + argsConsumedCount, this.Conversions, out bool foundNamed); + if (!foundNamed) + { + sourceIndices = sourceIndices ?? CreateSourceIndicesArray(i, parameterCount); + } } else if (argsConsumedCount < argumentsCount) { @@ -820,41 +824,48 @@ private TypedConstant GetDefaultValueArgument(ParameterSymbol parameter, Attribu } } - private static TypedConstant GetParamArrayArgument(ParameterSymbol parameter, ImmutableArray constructorArgsArray, int argumentsCount, int argsConsumedCount, Conversions conversions) + private static TypedConstant GetParamArrayArgument(ParameterSymbol parameter, ImmutableArray constructorArgsArray, + ImmutableArray constructorArgumentNamesOpt, int argumentsCount, int argsConsumedCount, Conversions conversions, out bool foundNamed) { Debug.Assert(argsConsumedCount <= argumentsCount); + // If there's a named argument, we'll use that + if (!constructorArgumentNamesOpt.IsDefault) + { + int argIndex = constructorArgumentNamesOpt.IndexOf(parameter.Name); + if (argIndex >= 0) + { + foundNamed = true; + if (TryGetNormalParamValue(parameter, constructorArgsArray, argIndex, conversions, out var namedValue)) + { + return namedValue; + } + + // A named argument for a params parameter is necessarily the only one for that parameter + return new TypedConstant(parameter.Type, ImmutableArray.Create(constructorArgsArray[argIndex])); + } + } + int paramArrayArgCount = argumentsCount - argsConsumedCount; + foundNamed = false; + + // If there are zero arguments left if (paramArrayArgCount == 0) { return new TypedConstant(parameter.Type, ImmutableArray.Empty); } - // If there's exactly one argument and it's an array of an appropriate type, then just return it. - if (paramArrayArgCount == 1 && constructorArgsArray[argsConsumedCount].Kind == TypedConstantKind.Array) + // If there's exactly one argument left, we'll try to use it in normal form + if (paramArrayArgCount == 1 && + TryGetNormalParamValue(parameter, constructorArgsArray, argsConsumedCount, conversions, out var lastValue)) { - TypeSymbol argumentType = (TypeSymbol)constructorArgsArray[argsConsumedCount].Type; - - // Easy out (i.e. don't both classifying conversion). - if (argumentType == parameter.Type) - { - return constructorArgsArray[argsConsumedCount]; - } - - HashSet useSiteDiagnostics = null; // ignoring, since already bound argument and parameter - Conversion conversion = conversions.ClassifyBuiltInConversion(argumentType, parameter.Type, ref useSiteDiagnostics); - - // NOTE: Won't always succeed, even though we've performed overload resolution. - // For example, passing int[] to params object[] actually treats the int[] as an element of the object[]. - if (conversion.IsValid && conversion.Kind == ConversionKind.ImplicitReference) - { - return constructorArgsArray[argsConsumedCount]; - } + return lastValue; } Debug.Assert(!constructorArgsArray.IsDefault); Debug.Assert(argsConsumedCount <= constructorArgsArray.Length); + // Take the trailing arguments as an array for expanded form var values = new TypedConstant[paramArrayArgCount]; for (int i = 0; i < paramArrayArgCount; i++) @@ -865,6 +876,39 @@ private static TypedConstant GetParamArrayArgument(ParameterSymbol parameter, Im return new TypedConstant(parameter.Type, values.AsImmutableOrNull()); } + private static bool TryGetNormalParamValue(ParameterSymbol parameter, ImmutableArray constructorArgsArray, + int argIndex, Conversions conversions, out TypedConstant result) + { + TypedConstant argument = constructorArgsArray[argIndex]; + if (argument.Kind != TypedConstantKind.Array) + { + result = default; + return false; + } + + TypeSymbol argumentType = (TypeSymbol)argument.Type; + // Easy out (i.e. don't bother classifying conversion). + if (argumentType == parameter.Type) + { + result = argument; + return true; + } + + HashSet useSiteDiagnostics = null; // ignoring, since already bound argument and parameter + Conversion conversion = conversions.ClassifyBuiltInConversion(argumentType, parameter.Type, ref useSiteDiagnostics); + + // NOTE: Won't always succeed, even though we've performed overload resolution. + // For example, passing int[] to params object[] actually treats the int[] as an element of the object[]. + if (conversion.IsValid && conversion.Kind == ConversionKind.ImplicitReference) + { + result = argument; + return true; + } + + result = default; + return false; + } + #endregion #region AttributeExpressionVisitor diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests.cs index 5739787c0fd1d..6454e007c84c0 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests.cs @@ -6,7 +6,6 @@ using System.IO; using System.Linq; using System.Reflection; -using System.Threading; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -62,6 +61,286 @@ public static void Main() {} CompileAndVerify(source, sourceSymbolValidator: attributeValidator, symbolValidator: null); } + [Fact] + [WorkItem(20741, "https://github.com/dotnet/roslyn/issues/20741")] + public void TestNamedArgumentOnStringParamsArgument() + { + var comp = CreateCompilationWithMscorlib46(@" +using System; + +class MarkAttribute : Attribute +{ + public MarkAttribute(bool a, params object[] b) + { + } +} + +[Mark(b: new string[] { ""Hello"", ""World"" }, a: true)] +[Mark(b: ""Hello"", true)] +static class Program +{ +}", parseOptions: TestOptions.Regular7_2); + comp.VerifyDiagnostics( + // (11,2): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type + // [Mark(b: new string[] { "Hello", "World" }, a: true)] + Diagnostic(ErrorCode.ERR_BadAttributeArgument, @"Mark(b: new string[] { ""Hello"", ""World"" }, a: true)").WithLocation(11, 2), + // (12,7): error CS8323: Named argument 'b' is used out-of-position but is followed by an unnamed argument + // [Mark(b: "Hello", true)] + Diagnostic(ErrorCode.ERR_BadNonTrailingNamedArgument, "b").WithArguments("b").WithLocation(12, 7) + ); + } + + [Fact] + [WorkItem(20741, "https://github.com/dotnet/roslyn/issues/20741")] + public void TestNamedArgumentOnOrderedObjectParamsArgument() + { + var comp = CreateCompilationWithMscorlib46(@" +using System; +using System.Reflection; + +sealed class MarkAttribute : Attribute +{ + public MarkAttribute(bool a, params object[] b) + { + B = b; + } + public object[] B { get; } +} + +[Mark(a: true, b: new object[] { ""Hello"", ""World"" })] +static class Program +{ + public static void Main() + { + var attr = typeof(Program).GetCustomAttribute(); + Console.Write($""B.Length={attr.B.Length}, B[0]={attr.B[0]}, B[1]={attr.B[1]}""); + } +}", options: TestOptions.DebugExe); + comp.VerifyDiagnostics(); + + CompileAndVerify(comp, expectedOutput: @"B.Length=2, B[0]=Hello, B[1]=World"); + + var program = (NamedTypeSymbol)comp.GetMember("Program"); + var attributeData = (SourceAttributeData)program.GetAttributes()[0]; + Assert.Equal(new[] { 0, -1 }, attributeData.ConstructorArgumentsSourceIndices); + } + + [Fact] + [WorkItem(20741, "https://github.com/dotnet/roslyn/issues/20741")] + public void TestNamedArgumentOnObjectParamsArgument() + { + var comp = CreateCompilationWithMscorlib46(@" +using System; +using System.Reflection; + +sealed class MarkAttribute : Attribute +{ + public MarkAttribute(bool a, params object[] b) + { + B = b; + } + public object[] B { get; } +} + +[Mark(b: new object[] { ""Hello"", ""World"" }, a: true)] +static class Program +{ + public static void Main() + { + var attr = typeof(Program).GetCustomAttribute(); + Console.Write($""B.Length={attr.B.Length}, B[0]={attr.B[0]}, B[1]={attr.B[1]}""); + } +}", options: TestOptions.DebugExe); + comp.VerifyDiagnostics(); + + CompileAndVerify(comp, expectedOutput: @"B.Length=2, B[0]=Hello, B[1]=World"); + + var program = (NamedTypeSymbol)comp.GetMember("Program"); + var attributeData = (SourceAttributeData)program.GetAttributes()[0]; + Assert.Equal(new[] { 1, -1 }, attributeData.ConstructorArgumentsSourceIndices); + } + + [Fact] + [WorkItem(20741, "https://github.com/dotnet/roslyn/issues/20741")] + public void TestNamedArgumentOnObjectParamsArgument2() + { + var comp = CreateCompilationWithMscorlib46(@" +using System; +using System.Reflection; + +sealed class MarkAttribute : Attribute +{ + public MarkAttribute(bool a, params object[] b) + { + A = a; + B = b; + } + public bool A { get; } + public object[] B { get; } +} + +[Mark(b: ""Hello"", a: true)] +static class Program +{ + public static void Main() + { + var attr = typeof(Program).GetCustomAttribute(); + Console.Write($""A={attr.A}, B.Length={attr.B.Length}, B[0]={attr.B[0]}""); + } +}", options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_2); + comp.VerifyDiagnostics(); + + CompileAndVerify(comp, expectedOutput: @"A=True, B.Length=1, B[0]=Hello"); + + var program = (NamedTypeSymbol)comp.GetMember("Program"); + var attributeData = (SourceAttributeData)program.GetAttributes()[0]; + Assert.Equal(new[] { 1, -1 }, attributeData.ConstructorArgumentsSourceIndices); + } + + [Fact] + [WorkItem(20741, "https://github.com/dotnet/roslyn/issues/20741")] + public void TestNamedArgumentOnObjectParamsArgument3() + { + var comp = CreateCompilationWithMscorlib46(@" +using System; +using System.Reflection; + +sealed class MarkAttribute : Attribute +{ + public MarkAttribute(bool a, params object[] b) + { + B = b; + } + public object[] B { get; } +} + +[Mark(true, new object[] { ""Hello"" }, new object[] { ""World"" })] +static class Program +{ + public static void Main() + { + var attr = typeof(Program).GetCustomAttribute(); + var worldArray = (object[])attr.B[1]; + Console.Write(worldArray[0]); + } +}", options: TestOptions.DebugExe); + comp.VerifyDiagnostics(); + + CompileAndVerify(comp, expectedOutput: @"World"); + + var program = (NamedTypeSymbol)comp.GetMember("Program"); + var attributeData = (SourceAttributeData)program.GetAttributes()[0]; + Assert.Equal(new[] { 0, -1 }, attributeData.ConstructorArgumentsSourceIndices); + } + + [Fact] + [WorkItem(20741, "https://github.com/dotnet/roslyn/issues/20741")] + public void TestNamedArgumentOnObjectParamsArgument4() + { + var comp = CreateCompilationWithMscorlib46(@" +using System; +using System.Reflection; + +sealed class MarkAttribute : Attribute +{ + public MarkAttribute(bool a, params object[] b) + { + B = b; + } + public object[] B { get; } +} + +[Mark(a: true, new object[] { ""Hello"" }, new object[] { ""World"" })] +static class Program +{ + public static void Main() + { + var attr = typeof(Program).GetCustomAttribute(); + var worldArray = (object[])attr.B[1]; + Console.Write(worldArray[0]); + } +}", options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_2); + comp.VerifyDiagnostics(); + + CompileAndVerify(comp, expectedOutput: @"World"); + + var program = (NamedTypeSymbol)comp.GetMember("Program"); + var attributeData = (SourceAttributeData)program.GetAttributes()[0]; + Assert.Equal(new[] { 0, -1 }, attributeData.ConstructorArgumentsSourceIndices); + } + + [Fact] + [WorkItem(20741, "https://github.com/dotnet/roslyn/issues/20741")] + public void TestNamedArgumentOnObjectParamsArgument5() + { + var comp = CreateCompilationWithMscorlib46(@" +using System; +using System.Reflection; + +sealed class MarkAttribute : Attribute +{ + public MarkAttribute(bool a, params object[] b) + { + B = b; + } + public object[] B { get; } +} + +[Mark(b: null, a: true)] +static class Program +{ + public static void Main() + { + var attr = typeof(Program).GetCustomAttribute(); + Console.Write(attr.B == null); + } +}", options: TestOptions.DebugExe); + comp.VerifyDiagnostics(); + + CompileAndVerify(comp, expectedOutput: @"True"); + + var program = (NamedTypeSymbol)comp.GetMember("Program"); + var attributeData = (SourceAttributeData)program.GetAttributes()[0]; + Assert.Equal(new[] { 1, -1 }, attributeData.ConstructorArgumentsSourceIndices); + } + + [Fact] + [WorkItem(20741, "https://github.com/dotnet/roslyn/issues/20741")] + public void TestNamedArgumentOnNonParamsArgument() + { + var comp = CreateCompilationWithMscorlib46(@" +using System; +using System.Reflection; + +sealed class MarkAttribute : Attribute +{ + public MarkAttribute(int a, int b) + { + A = a; + B = b; + } + public int A { get; } + public int B { get; } +} + +[Mark(b: 42, a: 1)] +static class Program +{ + public static void Main() + { + var attr = typeof(Program).GetCustomAttribute(); + Console.Write($""A={attr.A}, B={attr.B}""); + } +}", options: TestOptions.DebugExe); + comp.VerifyDiagnostics(); + + CompileAndVerify(comp, expectedOutput: "A=1, B=42"); + + var program = (NamedTypeSymbol)comp.GetMember("Program"); + var attributeData = (SourceAttributeData)program.GetAttributes()[0]; + Assert.Equal(new[] { 1, 0 }, attributeData.ConstructorArgumentsSourceIndices); + } + [WorkItem(984896, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/984896")] [Fact] public void TestAssemblyAttributesErr() diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests.vb index 2ec5b80e3e43f..d2d3f1d91e84c 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests.vb @@ -63,6 +63,54 @@ End Class CompilationUtils.AssertNoDiagnostics(comp) End Sub + + + Public Sub TestNamedArgumentOnStringParamsArgument() + Dim source = + + + +Module Program + + Private Sub Test(ByVal otherArg As Boolean, ParamArray args As Object()) + End Sub + + Sub Main() + Console.WriteLine("Method call") + Test(args:=New String() {"Hello", "World"}, otherArg:=True) + End Sub +End Module +]]> + + + + Dim comp = CreateCompilationWithMscorlibAndVBRuntime(source) + comp.AssertTheseDiagnostics( + ~~~~ +BC30661: Field or property 'args' is not found. + + ~~~~ +BC30661: Field or property 'otherArg' is not found. + + ~~~~~~~~ +BC30587: Named argument cannot match a ParamArray parameter. + Test(args:=New String() {"Hello", "World"}, otherArg:=True) + ~~~~ + ]]>) + End Sub + ''' ''' This function is the same as PEParameterSymbolParamArray ''' except that we check attributes first (to check for race From e52edd84fd654f291517f017610ed6ddbc69df90 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Thu, 28 Sep 2017 21:42:43 -0700 Subject: [PATCH 08/16] Fix typo in INotifyCompletion API in doc (#22417) --- docs/features/task-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/task-types.md b/docs/features/task-types.md index d31903f5d960f..419d9b1d2d109 100644 --- a/docs/features/task-types.md +++ b/docs/features/task-types.md @@ -21,7 +21,7 @@ class Awaiter : INotifyCompletion { public bool IsCompleted { get; } public T GetResult(); - public void OnCompletion(Action completion); + public void OnCompleted(Action completion); } ``` ## Builder Type From bceced0d19b85383c6ceb43353031b33a4c618b8 Mon Sep 17 00:00:00 2001 From: vsadov Date: Thu, 28 Sep 2017 09:54:38 -0700 Subject: [PATCH 09/16] Allow taking unmanaged/pinned addresses of readonly variables. Fixes:#22306 --- .../Portable/Binder/Binder.ValueChecks.cs | 18 ++--- .../CSharp/Portable/CodeGen/EmitExpression.cs | 4 +- .../CodeGenRefReadOnlyParametersTests.cs | 17 ++--- .../CodeGen/CodeGenRefReadonlyReturnTests.cs | 69 +++++++++-------- .../CSharp/Test/Emit/CodeGen/UnsafeTests.cs | 74 ++++++++++++++++++- .../Diagnostics/OperationAnalyzerTests.cs | 24 +++--- .../IOperationTests_IFixedStatement.cs | 8 +- .../Semantic/Semantics/SemanticErrorTests.cs | 9 +-- .../Test/Semantic/Semantics/UnsafeTests.cs | 27 +++---- 9 files changed, 155 insertions(+), 95 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs index de7070338d218..57b4aa9b07360 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs @@ -99,27 +99,27 @@ internal enum BindValueKind : byte ReadonlyRef = RefersToLocation | RValue, /// - /// Expression is passed as a ref or out parameter or assigned to a byref variable. + /// Expression can be the operand of an address-of operation (&). + /// Same as ReadonlyRef. The difference is just for error reporting. /// - RefOrOut = RefersToLocation | RValue | Assignable, + AddressOf = ReadonlyRef + 1, /// - /// Expression can be the operand of an address-of operation (&). - /// Same as RefOrOut. The difference is just for error reporting. + /// Expression is the receiver of a fixed buffer field access + /// Same as ReadonlyRef. The difference is just for error reporting. /// - AddressOf = RefOrOut + 1, + FixedReceiver = ReadonlyRef + 2, /// - /// Expression is the receiver of a fixed buffer field access - /// Same as RefOrOut. The difference is just for error reporting. + /// Expression is passed as a ref or out parameter or assigned to a byref variable. /// - FixedReceiver = RefOrOut + 2, + RefOrOut = RefersToLocation | RValue | Assignable, /// /// Expression is returned by an ordinary r/w reference. /// Same as RefOrOut. The difference is just for error reporting. /// - RefReturn = RefOrOut + 3, + RefReturn = RefOrOut + 1, } private static bool RequiresRValueOnly(BindValueKind kind) diff --git a/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs b/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs index c50e993006e65..f8b29a667f29f 100644 --- a/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs +++ b/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs @@ -2336,7 +2336,9 @@ private void EmitAssignmentValue(BoundAssignmentOperator assignmentOperator) { int exprTempsBefore = _expressionTemps?.Count ?? 0; - LocalDefinition temp = EmitAddress(assignmentOperator.Right, AddressKind.Writeable); + // NOTE: passing "ReadOnly" here. Assuming we do not have compile errors, + // We should not get an address of a copy, even if the RHS is readonly + LocalDefinition temp = EmitAddress(assignmentOperator.Right, AddressKind.ReadOnly); // Generally taking a ref for the purpose of ref assignment should not be done on homeless values // however, there are very rare cases when we need to get a ref off a temp in synthetic code. diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs index c1033b9540c12..3396b60117e5f 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs @@ -464,8 +464,9 @@ static void M(ref readonly int arg1, ref readonly (int Alice, int Bob) arg2) Diagnostic(ErrorCode.ERR_RefReadonlyNotField2, "arg2.Alice").WithArguments("variable", "ref readonly (int Alice, int Bob)")); } + [WorkItem(22306, "https://github.com/dotnet/roslyn/issues/22306")] [Fact] - public void ReadonlyParamCannotTakePtr() + public void ReadonlyParamCanTakePtr() { var text = @" class Program @@ -488,18 +489,12 @@ unsafe static void M(ref readonly int arg1, ref readonly (int Alice, int Bob) ar var comp = CreateCompilationWithMscorlib45(text, new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.UnsafeReleaseDll); comp.VerifyDiagnostics( - // (6,20): error CS0211: Cannot take the address of the given expression + // (6,18): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer // int* a = & arg1; - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "arg1").WithLocation(6, 20), - // (7,20): error CS0211: Cannot take the address of the given expression + Diagnostic(ErrorCode.ERR_FixedNeeded, "& arg1").WithLocation(6, 18), + // (7,18): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer // int* b = & arg2.Alice; - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "arg2.Alice").WithLocation(7, 20), - // (9,26): error CS0211: Cannot take the address of the given expression - // fixed(int* c = & arg1) - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "arg1").WithLocation(9, 26), - // (13,26): error CS0211: Cannot take the address of the given expression - // fixed(int* d = & arg2.Alice) - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "arg2.Alice").WithLocation(13, 26) + Diagnostic(ErrorCode.ERR_FixedNeeded, "& arg2.Alice").WithLocation(7, 18) ); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs index 52a22b962ad36..62800b35218f8 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs @@ -13,7 +13,7 @@ public class CodeGenRefReadOnlyReturnTests : CompilingTestBase [Fact] public void RefReadonlyLocalToField() { - var comp = CompileAndVerify(@" + var source = @" struct S { public int X; @@ -52,7 +52,9 @@ ref readonly S M() return ref rs1; } -}"); +}"; + + var comp = CompileAndVerify(source, parseOptions: TestOptions.Regular.WithPEVerifyCompatFeature()); comp.VerifyIL("C.M", @" { // Code size 65 (0x41) @@ -82,6 +84,31 @@ .locals init (S V_0, IL_003b: call ""void S2.AddOne()"" IL_0040: ret }"); + + comp = CompileAndVerify(source, verify: false); + comp.VerifyIL("C.M", @" +{ + // Code size 59 (0x3b) + .maxstack 2 + .locals init (S V_0) + IL_0000: ldsflda ""S C.s1"" + IL_0005: dup + IL_0006: ldobj ""S"" + IL_000b: stloc.0 + IL_000c: ldloca.s V_0 + IL_000e: call ""void S.AddOne()"" + IL_0013: ldsflda ""S C.s2"" + IL_0018: ldobj ""S"" + IL_001d: stloc.0 + IL_001e: ldloca.s V_0 + IL_0020: call ""void S.AddOne()"" + IL_0025: ldsflda ""S2 C.s3"" + IL_002a: call ""void S2.AddOne()"" + IL_002f: ldarg.0 + IL_0030: ldflda ""S2 C.s4"" + IL_0035: call ""void S2.AddOne()"" + IL_003a: ret +}"); } [Fact] @@ -343,15 +370,11 @@ static ref readonly int Helper() }"); verifier.VerifyIL("C.M()", @" { - // Code size 11 (0xb) + // Code size 7 (0x7) .maxstack 1 - .locals init (int V_0) IL_0000: call ""ref readonly int C.Helper()"" - IL_0005: ldind.i4 - IL_0006: stloc.0 - IL_0007: ldloca.s V_0 - IL_0009: pop - IL_000a: ret + IL_0005: pop + IL_0006: ret }"); } @@ -618,30 +641,18 @@ unsafe static void Test() var comp = CreateCompilationWithMscorlib45(text, new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.UnsafeReleaseDll); comp.VerifyDiagnostics( - // (6,20): error CS0211: Cannot take the address of the given expression + // (6,18): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer // int* a = & M(); - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "M()").WithLocation(6, 20), - // (7,20): error CS0211: Cannot take the address of the given expression + Diagnostic(ErrorCode.ERR_FixedNeeded, "& M()").WithLocation(6, 18), + // (7,18): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer // int* b = & M1().Alice; - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "M1().Alice").WithLocation(7, 20), - // (9,21): error CS0211: Cannot take the address of the given expression + Diagnostic(ErrorCode.ERR_FixedNeeded, "& M1().Alice").WithLocation(7, 18), + // (9,19): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer // int* a1 = & P; - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "P").WithLocation(9, 21), - // (10,21): error CS0211: Cannot take the address of the given expression + Diagnostic(ErrorCode.ERR_FixedNeeded, "& P").WithLocation(9, 19), + // (10,19): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer // int* b2 = & P1.Alice; - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "P1.Alice").WithLocation(10, 21), - // (12,26): error CS0211: Cannot take the address of the given expression - // fixed(int* c = & M()) - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "M()").WithLocation(12, 26), - // (16,26): error CS0211: Cannot take the address of the given expression - // fixed(int* d = & M1().Alice) - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "M1().Alice").WithLocation(16, 26), - // (20,26): error CS0211: Cannot take the address of the given expression - // fixed(int* c = & P) - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "P").WithLocation(20, 26), - // (24,26): error CS0211: Cannot take the address of the given expression - // fixed(int* d = & P1.Alice) - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "P1.Alice").WithLocation(24, 26) + Diagnostic(ErrorCode.ERR_FixedNeeded, "& P1.Alice").WithLocation(10, 19) ); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/UnsafeTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/UnsafeTests.cs index 1a79a51e5d327..1731abdd6f76c 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/UnsafeTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/UnsafeTests.cs @@ -1226,6 +1226,7 @@ .locals init (pinned int& V_0) "); } + [WorkItem(22306, "https://github.com/dotnet/roslyn/issues/22306")] [Fact] public void FixedStatementMultipleFields() { @@ -1235,7 +1236,7 @@ public void FixedStatementMultipleFields() unsafe class C { int x; - int y; + readonly int y; static void Main() { @@ -1292,6 +1293,77 @@ .locals init (int* V_0, //p "); } + [WorkItem(22306, "https://github.com/dotnet/roslyn/issues/22306")] + [Fact] + public void FixedStatementMultipleMethods() + { + var text = @" +using System; + +unsafe class C +{ + int x; + readonly int y; + + ref int X()=>ref x; + ref readonly int this[int i]=>ref y; + + static void Main() + { + C c = new C(); + fixed (int* p = &c.X(), q = &c[3]) + { + *p = 1; + *q = 2; + } + Console.Write(c.x); + Console.Write(c.y); + } +} +"; + var compVerifier = CompileAndVerify(text, options: TestOptions.UnsafeReleaseExe, expectedOutput: @"12"); + + compVerifier.VerifyIL("C.Main", @" +{ + // Code size 58 (0x3a) + .maxstack 4 + .locals init (int* V_0, //p + pinned int& V_1, + pinned int& V_2) + IL_0000: newobj ""C..ctor()"" + IL_0005: dup + IL_0006: callvirt ""ref int C.X()"" + IL_000b: stloc.1 + IL_000c: ldloc.1 + IL_000d: conv.u + IL_000e: stloc.0 + IL_000f: dup + IL_0010: ldc.i4.3 + IL_0011: callvirt ""ref readonly int C.this[int].get"" + IL_0016: stloc.2 + IL_0017: ldloc.2 + IL_0018: conv.u + IL_0019: ldloc.0 + IL_001a: ldc.i4.1 + IL_001b: stind.i4 + IL_001c: ldc.i4.2 + IL_001d: stind.i4 + IL_001e: ldc.i4.0 + IL_001f: conv.u + IL_0020: stloc.1 + IL_0021: ldc.i4.0 + IL_0022: conv.u + IL_0023: stloc.2 + IL_0024: dup + IL_0025: ldfld ""int C.x"" + IL_002a: call ""void System.Console.Write(int)"" + IL_002f: ldfld ""int C.y"" + IL_0034: call ""void System.Console.Write(int)"" + IL_0039: ret +} +"); + } + [WorkItem(546866, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546866")] [Fact] public void FixedStatementProperty() diff --git a/src/Compilers/CSharp/Test/Semantic/Diagnostics/OperationAnalyzerTests.cs b/src/Compilers/CSharp/Test/Semantic/Diagnostics/OperationAnalyzerTests.cs index 14286a3ec15ff..d0e7f2cd2e827 100644 --- a/src/Compilers/CSharp/Test/Semantic/Diagnostics/OperationAnalyzerTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Diagnostics/OperationAnalyzerTests.cs @@ -1383,21 +1383,17 @@ public unsafe void M1() private int _i = 0; }"; CreateCompilationWithMscorlib45(source, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularWithIOperationFeature) - .VerifyDiagnostics(Diagnostic(ErrorCode.ERR_InvalidAddrOp, "a + b").WithLocation(7, 18), - Diagnostic(ErrorCode.ERR_AddrOnReadOnlyLocal, "i").WithLocation(28, 23), - Diagnostic(ErrorCode.ERR_AddrOnReadOnlyLocal, "i").WithLocation(33, 24)) + .VerifyDiagnostics(Diagnostic(ErrorCode.ERR_InvalidAddrOp, "a + b").WithLocation(7, 18)) .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new AddressOfTestAnalyzer() }, null, null, false, - Diagnostic(AddressOfTestAnalyzer.AddressOfDescriptor.Id, "&(a + b)").WithLocation(7, 16), - Diagnostic(AddressOfTestAnalyzer.InvalidAddressOfReferenceDescriptor.Id, "a + b").WithLocation(7, 18), - Diagnostic(AddressOfTestAnalyzer.AddressOfDescriptor.Id, "&a").WithLocation(9, 16), - Diagnostic(AddressOfTestAnalyzer.AddressOfDescriptor.Id, "&x").WithLocation(15, 17), - Diagnostic(AddressOfTestAnalyzer.AddressOfDescriptor.Id, "&(*p)").WithLocation(16, 12), - Diagnostic(AddressOfTestAnalyzer.AddressOfDescriptor.Id, "&p[0]").WithLocation(17, 12), - Diagnostic(AddressOfTestAnalyzer.AddressOfDescriptor.Id, "&i").WithLocation(28, 22), - Diagnostic(AddressOfTestAnalyzer.InvalidAddressOfReferenceDescriptor.Id, "i").WithLocation(28, 23), - Diagnostic(AddressOfTestAnalyzer.AddressOfDescriptor.Id, "&_i").WithLocation(31, 25), - Diagnostic(AddressOfTestAnalyzer.AddressOfDescriptor.Id, "&i").WithLocation(33, 23), - Diagnostic(AddressOfTestAnalyzer.InvalidAddressOfReferenceDescriptor.Id, "i").WithLocation(33, 24)); + Diagnostic("AddressOfOperation", "&(a + b)").WithLocation(7, 16), + Diagnostic("InvalidAddressOfReference", "a + b").WithLocation(7, 18), + Diagnostic("AddressOfOperation", "&a").WithLocation(9, 16), + Diagnostic("AddressOfOperation", "&i").WithLocation(28, 22), + Diagnostic("AddressOfOperation", "&_i").WithLocation(31, 25), + Diagnostic("AddressOfOperation", "&i").WithLocation(33, 23), + Diagnostic("AddressOfOperation", "&x").WithLocation(15, 17), + Diagnostic("AddressOfOperation", "&(*p)").WithLocation(16, 12), + Diagnostic("AddressOfOperation", "&p[0]").WithLocation(17, 12)); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IFixedStatement.cs b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IFixedStatement.cs index ce246f3d5db01..2918b71a237a1 100644 --- a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IFixedStatement.cs +++ b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IFixedStatement.cs @@ -287,14 +287,12 @@ void M1() Right: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int32, IsInvalid) (Syntax: '&p1') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: IAddressOfExpression (OperationKind.AddressOfExpression, Type: System.Int32**, IsInvalid) (Syntax: '&p1') - Reference: IInvalidExpression (OperationKind.InvalidExpression, Type: System.Int32*, IsInvalid) (Syntax: 'p1') - Children(1): - ILocalReferenceExpression: p1 (OperationKind.LocalReferenceExpression, Type: System.Int32*, IsInvalid) (Syntax: 'p1') + Reference: ILocalReferenceExpression: p1 (OperationKind.LocalReferenceExpression, Type: System.Int32*, IsInvalid) (Syntax: 'p1') "; var expectedDiagnostics = new DiagnosticDescription[] { - // CS0459: Cannot take the address of a read-only local variable + // file.cs(15,22): error CS0266: Cannot implicitly convert type 'int**' to 'int'. An explicit conversion exists (are you missing a cast?) // i3 = &p1; - Diagnostic(ErrorCode.ERR_AddrOnReadOnlyLocal, "p1").WithLocation(15, 23) + Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "&p1").WithArguments("int**", "int").WithLocation(15, 22) }; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics, diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs index 72562a7948b79..b6d8e0b1495e9 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs @@ -10260,6 +10260,7 @@ public static void Main() Diagnostic(ErrorCode.ERR_AmbigUDConv, "h1a").WithArguments("H1.implicit operator G1(H1)", "H0.implicit operator G0(H0)", "H1", "G0")); } + [WorkItem(22306, "https://github.com/dotnet/roslyn/issues/22306")] [Fact] public void CS0459ERR_AddrOnReadOnlyLocal() { @@ -10283,13 +10284,7 @@ public unsafe void M1() private int _i = 0; } "; - CreateStandardCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( - // (9,23): error CS0459: Cannot take the address of a read-only local variable - // int *j = &i; // CS0459 - Diagnostic(ErrorCode.ERR_AddrOnReadOnlyLocal, "i"), - // (14,24): error CS0459: Cannot take the address of a read-only local variable - // int **j = &i; // CS0459 - Diagnostic(ErrorCode.ERR_AddrOnReadOnlyLocal, "i")); + CreateStandardCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs index 7c0dadb31601b..fc3d5fea7d8d7 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs @@ -3123,6 +3123,7 @@ int M(int param) Diagnostic(ErrorCode.ERR_InvalidAddrOp, "x").WithArguments("x")); } + [WorkItem(22306, "https://github.com/dotnet/roslyn/issues/22306")] [Fact] public void AddressOfExpressionKinds_ReadOnlyLocal() { @@ -3142,17 +3143,17 @@ void M() foreach (int y in new int[1]) { - p = &y; //CS0459 + p = &y; } using (S s = new S()) { - S* sp = &s; //CS0459 + S* sp = &s; } fixed (int* a = &array[0]) { - int** pp = &a; //CS0459 + int** pp = &a; } } } @@ -3165,19 +3166,11 @@ public void Dispose() { } CreateCompilationWithMscorlibAndSystemCore(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( // (13,14): error CS0211: Cannot take the address of the given expression // p = &x; //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "x"), - // (17,18): error CS0459: Cannot take the address of a read-only local variable - // p = &y; //CS0459 - Diagnostic(ErrorCode.ERR_AddrOnReadOnlyLocal, "y"), - // (22,22): error CS0459: Cannot take the address of a read-only local variable - // S* sp = &s; //CS0459 - Diagnostic(ErrorCode.ERR_AddrOnReadOnlyLocal, "s"), - // (27,25): error CS0459: Cannot take the address of a read-only local variable - // int** pp = &a; //CS0459 - Diagnostic(ErrorCode.ERR_AddrOnReadOnlyLocal, "a"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "x").WithLocation(13, 14), // (6,11): warning CS0649: Field 'C.array' is never assigned to, and will always have its default value null // int[] array; - Diagnostic(ErrorCode.WRN_UnassignedInternalField, "array").WithArguments("C.array", "null")); + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "array").WithArguments("C.array", "null").WithLocation(6, 11) + ); } [Fact] @@ -3839,6 +3832,7 @@ public static void Main() Diagnostic(ErrorCode.ERR_AnonymousTypePropertyAssignedBadValue, "p1 = &x").WithArguments("int*")); } + [WorkItem(22306, "https://github.com/dotnet/roslyn/issues/22306")] [WorkItem(544537, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544537")] [Fact] public void AddressOfStaticReadonlyFieldInsideFixed() @@ -3855,10 +3849,7 @@ unsafe public static void Main() } "; - CreateCompilationWithMscorlibAndSystemCore(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( - // (8,27): error CS0211: Cannot take the address of the given expression - // fixed (int* v1 = &R1) { } - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "R1")); + CreateCompilationWithMscorlibAndSystemCore(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); } #endregion AddressOf diagnostics From 2a2f1a678a89a039a7069dda01ef14b978576f9e Mon Sep 17 00:00:00 2001 From: vsadov Date: Thu, 28 Sep 2017 21:50:25 -0700 Subject: [PATCH 10/16] CR feedback --- .../Portable/Binder/Binder.ValueChecks.cs | 12 +-- .../Portable/CSharpResources.Designer.cs | 19 +--- .../CSharp/Portable/CSharpResources.resx | 3 - .../CSharp/Portable/Errors/ErrorCode.cs | 2 +- .../Diagnostics/OperationAnalyzerTests.cs | 4 +- .../Semantic/Semantics/SemanticErrorTests.cs | 6 +- .../Test/Semantic/Semantics/UnsafeTests.cs | 89 ++++++++++--------- 7 files changed, 59 insertions(+), 76 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs index 57b4aa9b07360..69c7b00c2f6dd 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs @@ -395,7 +395,9 @@ internal bool CheckValueKind(SyntaxNode node, BoundExpression expr, BindValueKin // Note: RValueOnly is checked at the beginning of this method. Since we are here we need more than readable. //"this" is readonly in members of readonly structs, unless we are in a constructor. if (!thisref.Type.IsValueType || - (thisref.Type.IsReadOnly && (this.ContainingMemberOrLambda as MethodSymbol)?.MethodKind != MethodKind.Constructor)) + (RequiresAssignableVariable(valueKind) && + thisref.Type.IsReadOnly && + (this.ContainingMemberOrLambda as MethodSymbol)?.MethodKind != MethodKind.Constructor)) { // CONSIDER: the Dev10 name has angle brackets (i.e. "") Error(diagnostics, GetThisLvalueError(valueKind), node, ThisParameterSymbol.SymbolName); @@ -1369,12 +1371,6 @@ private static void ReportReadonlyLocalError(SyntaxNode node, LocalSymbol local, return; } - if (kind == BindValueKind.AddressOf) - { - Error(diagnostics, ErrorCode.ERR_AddrOnReadOnlyLocal, node); - return; - } - ErrorCode[] ReadOnlyLocalErrors = { ErrorCode.ERR_RefReadonlyLocalCause, @@ -1401,7 +1397,7 @@ static private ErrorCode GetThisLvalueError(BindValueKind kind) return ErrorCode.ERR_RefReadonlyLocal; case BindValueKind.AddressOf: - return ErrorCode.ERR_AddrOnReadOnlyLocal; + return ErrorCode.ERR_InvalidAddrOp; case BindValueKind.IncrementDecrement: return ErrorCode.ERR_IncrementLvalueExpected; diff --git a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs index 6bebc21a5f7a8..5b7171e526c1f 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs +++ b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs @@ -241,15 +241,6 @@ internal static string ERR_AddRemoveMustHaveBody { } } - /// - /// Looks up a localized string similar to Cannot take the address of a read-only local variable. - /// - internal static string ERR_AddrOnReadOnlyLocal { - get { - return ResourceManager.GetString("ERR_AddrOnReadOnlyLocal", resourceCulture); - } - } - /// /// Looks up a localized string similar to Agnostic assembly cannot have a processor specific module '{0}'.. /// @@ -8493,18 +8484,16 @@ internal static string ERR_RefReturnNonreturnableLocal2 { return ResourceManager.GetString("ERR_RefReturnNonreturnableLocal2", resourceCulture); } } - + /// /// Looks up a localized string similar to Cannot return a parameter by reference '{0}' because it is not a ref or out parameter. /// - internal static string ERR_RefReturnParameter - { - get - { + internal static string ERR_RefReturnParameter { + get { return ResourceManager.GetString("ERR_RefReturnParameter", resourceCulture); } } - + /// /// Looks up a localized string similar to Cannot return by reference a member of parameter '{0}' because it is not a ref or out parameter. /// diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index f8d4ef0aacf00..9b80f2af3a725 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -1356,9 +1356,6 @@ The result of the expression is always 'null' - - Cannot take the address of a read-only local variable - Cannot return 'this' by reference. diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index 6e990c9c292e1..c7bc5620d03c6 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -311,7 +311,7 @@ internal enum ErrorCode ERR_ConWithValCon = 456, ERR_AmbigUDConv = 457, WRN_AlwaysNull = 458, - ERR_AddrOnReadOnlyLocal = 459, + // ERR_AddrOnReadOnlyLocal = 459, // no longer an error ERR_OverrideWithConstraints = 460, ERR_AmbigOverride = 462, ERR_DecConstError = 463, diff --git a/src/Compilers/CSharp/Test/Semantic/Diagnostics/OperationAnalyzerTests.cs b/src/Compilers/CSharp/Test/Semantic/Diagnostics/OperationAnalyzerTests.cs index d0e7f2cd2e827..7e55adb44b84f 100644 --- a/src/Compilers/CSharp/Test/Semantic/Diagnostics/OperationAnalyzerTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Diagnostics/OperationAnalyzerTests.cs @@ -1371,12 +1371,12 @@ public unsafe void M1() int[] ints = new int[] { 1, 2, 3 }; foreach (int i in ints) { - int *j = &i; // CS0459 + int *j = &i; } fixed (int *i = &_i) { - int **j = &i; // CS0459 + int **j = &i; } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs index b6d8e0b1495e9..f772af97a8213 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs @@ -10262,7 +10262,7 @@ public static void Main() [WorkItem(22306, "https://github.com/dotnet/roslyn/issues/22306")] [Fact] - public void CS0459ERR_AddrOnReadOnlyLocal() + public void AddrOnReadOnlyLocal() { var text = @" class A @@ -10272,12 +10272,12 @@ public unsafe void M1() int[] ints = new int[] { 1, 2, 3 }; foreach (int i in ints) { - int *j = &i; // CS0459 + int *j = &i; } fixed (int *i = &_i) { - int **j = &i; // CS0459 + int **j = &i; } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs index fc3d5fea7d8d7..354936f6450da 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs @@ -3235,7 +3235,7 @@ int M(int param) var w = &(F += null); //CS0211 var x = &(array is object); //CS0211 var y = &(array ?? array); //CS0208, CS0211 (managed) - var aa = &this; //CS0208, CS0459 (readonly) + var aa = &this; //CS0208 var bb = &typeof(int); //CS0208, CS0211 (managed) var cc = &Color.Red; //CS0211 @@ -3261,120 +3261,121 @@ enum Color } "; CreateStandardCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (76,18): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer + // var aa = &this; //CS0212 (need fixed) + Diagnostic(ErrorCode.ERR_FixedNeeded, "&this").WithLocation(76, 18), // (23,14): error CS0211: Cannot take the address of the given expression // p = &1; //CS0211 (can't addr) - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "1"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "1").WithLocation(23, 14), // (24,13): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer // p = &array[0]; //CS0212 (need fixed) - Diagnostic(ErrorCode.ERR_FixedNeeded, "&array[0]"), + Diagnostic(ErrorCode.ERR_FixedNeeded, "&array[0]").WithLocation(24, 13), // (25,15): error CS0211: Cannot take the address of the given expression // p = &(local = 1); //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "local = 1"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "local = 1").WithLocation(25, 15), // (26,14): error CS0103: The name 'goo' does not exist in the current context // p = &goo; //CS0103 (no goo) - Diagnostic(ErrorCode.ERR_NameNotInContext, "goo").WithArguments("goo"), + Diagnostic(ErrorCode.ERR_NameNotInContext, "goo").WithArguments("goo").WithLocation(26, 14), // (27,13): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer // p = &base.f; //CS0212 - Diagnostic(ErrorCode.ERR_FixedNeeded, "&base.f"), + Diagnostic(ErrorCode.ERR_FixedNeeded, "&base.f").WithLocation(27, 13), // (28,15): error CS0211: Cannot take the address of the given expression // p = &(local + local); //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "local + local"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "local + local").WithLocation(28, 15), // (29,14): error CS0211: Cannot take the address of the given expression // p = &M(local); //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "M(local)"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "M(local)").WithLocation(29, 14), // (30,14): error CS0211: Cannot take the address of the given expression // p = &func(); //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "func()"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "func()").WithLocation(30, 14), // (31,15): error CS0211: Cannot take the address of the given expression // p = &(local += local); //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "local += local"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "local += local").WithLocation(31, 15), // (32,15): error CS0211: Cannot take the address of the given expression // p = &(local == 0 ? local : param); //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "local == 0 ? local : param"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "local == 0 ? local : param").WithLocation(32, 15), // (33,15): error CS0211: Cannot take the address of the given expression // p = &((int)param); //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "(int)param"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "(int)param").WithLocation(33, 15), // (34,14): error CS0211: Cannot take the address of the given expression // p = &default(int); //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "default(int)"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "default(int)").WithLocation(34, 14), // (35,14): error CS0211: Cannot take the address of the given expression // p = &delegate { return 1; }; //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "delegate { return 1; }"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "delegate { return 1; }").WithLocation(35, 14), // (36,13): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer // p = &instanceField; //CS0212 - Diagnostic(ErrorCode.ERR_FixedNeeded, "&instanceField"), + Diagnostic(ErrorCode.ERR_FixedNeeded, "&instanceField").WithLocation(36, 13), // (37,13): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer // p = &staticField; //CS0212 - Diagnostic(ErrorCode.ERR_FixedNeeded, "&staticField"), + Diagnostic(ErrorCode.ERR_FixedNeeded, "&staticField").WithLocation(37, 13), // (38,15): error CS0211: Cannot take the address of the given expression // p = &(local++); //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "local++"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "local++").WithLocation(38, 15), // (39,14): error CS0211: Cannot take the address of the given expression // p = &this[0]; //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "this[0]").WithArguments("C.this[int]"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "this[0]").WithArguments("C.this[int]").WithLocation(39, 14), // (40,15): error CS0211: Cannot take the address of the given expression // p = &(() => 1); //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "() => 1"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "() => 1").WithLocation(40, 15), // (41,14): error CS0211: Cannot take the address of the given expression // p = &M; //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "M").WithArguments("M", "method group"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "M").WithArguments("M", "method group").WithLocation(41, 14), // (42,15): error CS0211: Cannot take the address of the given expression // p = &(new System.Int32()); //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "new System.Int32()"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "new System.Int32()").WithLocation(42, 15), // (43,14): error CS0211: Cannot take the address of the given expression // p = &P; //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "P").WithArguments("C.P"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "P").WithArguments("C.P").WithLocation(43, 14), // (44,14): error CS0211: Cannot take the address of the given expression // p = &sizeof(int); //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "sizeof(int)"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "sizeof(int)").WithLocation(44, 14), // (45,13): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer // p = &this.instanceField; //CS0212 - Diagnostic(ErrorCode.ERR_FixedNeeded, "&this.instanceField"), + Diagnostic(ErrorCode.ERR_FixedNeeded, "&this.instanceField").WithLocation(45, 13), // (46,15): error CS0211: Cannot take the address of the given expression // p = &(+local); //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "+local"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "+local").WithLocation(46, 15), // (49,16): error CS0211: Cannot take the address of the given expression // pp = &(&local); //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "&local"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "&local").WithLocation(49, 16), // (51,19): error CS0211: Cannot take the address of the given expression // var q = &(new { }); //CS0208, CS0211 (managed) - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "new { }"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "new { }").WithLocation(51, 19), // (52,19): error CS0211: Cannot take the address of the given expression // var r = &(new int[1]); //CS0208, CS0211 (managed) - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "new int[1]"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "new int[1]").WithLocation(52, 19), // (53,19): error CS0211: Cannot take the address of the given expression // var s = &(array as object); //CS0208, CS0211 (managed) - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "array as object"), - // (54,17): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('System.Action') + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "array as object").WithLocation(53, 19), + // (54,17): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('Action') // var t = &E; //CS0208 - Diagnostic(ErrorCode.ERR_ManagedAddr, "&E").WithArguments("System.Action"), + Diagnostic(ErrorCode.ERR_ManagedAddr, "&E").WithArguments("System.Action").WithLocation(54, 17), // (55,18): error CS0079: The event 'C.F' can only appear on the left hand side of += or -= // var u = &F; //CS0079 (can't use event like that) - Diagnostic(ErrorCode.ERR_BadEventUsageNoField, "F").WithArguments("C.F"), + Diagnostic(ErrorCode.ERR_BadEventUsageNoField, "F").WithArguments("C.F").WithLocation(55, 18), // (56,19): error CS0211: Cannot take the address of the given expression // var v = &(E += null); //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "E += null"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "E += null").WithLocation(56, 19), // (57,19): error CS0211: Cannot take the address of the given expression // var w = &(F += null); //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "F += null"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "F += null").WithLocation(57, 19), // (58,19): error CS0211: Cannot take the address of the given expression // var x = &(array is object); //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "array is object"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "array is object").WithLocation(58, 19), // (59,19): error CS0211: Cannot take the address of the given expression // var y = &(array ?? array); //CS0208, CS0211 (managed) - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "array ?? array"), - // (60,19): error CS0459: Cannot take the address of a read-only local variable - // var aa = &this; //CS0208, CS0459 (readonly) - Diagnostic(ErrorCode.ERR_AddrOnReadOnlyLocal, "this").WithArguments("this"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "array ?? array").WithLocation(59, 19), + // (60,19): error CS0211: Cannot take the address of the given expression + // var aa = &this; //CS0208 + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "this").WithArguments("this").WithLocation(60, 19), // (61,19): error CS0211: Cannot take the address of the given expression // var bb = &typeof(int); //CS0208, CS0211 (managed) - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "typeof(int)"), + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "typeof(int)").WithLocation(61, 19), // (62,19): error CS0211: Cannot take the address of the given expression // var cc = &Color.Red; //CS0211 - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "Color.Red"), - // (76,18): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer - // var aa = &this; //CS0212 (need fixed) - Diagnostic(ErrorCode.ERR_FixedNeeded, "&this")); + Diagnostic(ErrorCode.ERR_InvalidAddrOp, "Color.Red").WithLocation(62, 19) + ); } #endregion AddressOf operand kinds From 86c629901e904bdaa7131d300c61c52682ee6979 Mon Sep 17 00:00:00 2001 From: vsadov Date: Thu, 28 Sep 2017 22:17:49 -0700 Subject: [PATCH 11/16] one more test --- .../CSharp/Test/Emit/CodeGen/UnsafeTests.cs | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/UnsafeTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/UnsafeTests.cs index 1731abdd6f76c..b6fd4076ad831 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/UnsafeTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/UnsafeTests.cs @@ -1226,6 +1226,72 @@ .locals init (pinned int& V_0) "); } + [Fact] + public void FixedStatementThis() + { + var text = @" +public class Program +{ + public static void Main() + { + S1 s = default; + s.Test(); + } + + unsafe readonly struct S1 + { + readonly int x; + + public void Test() + { + fixed(void* p = &this) + { + *(int*)p = 123; + } + + ref readonly S1 r = ref this; + + fixed (S1* p = &r) + { + System.Console.WriteLine(p->x); + } + } + } +} +"; + var compVerifier = CompileAndVerify(text, options: TestOptions.UnsafeReleaseExe, expectedOutput: @"123"); + + compVerifier.VerifyIL("Program.S1.Test()", @" +{ + // Code size 30 (0x1e) + .maxstack 2 + .locals init (void* V_0, //p + pinned Program.S1& V_1) + IL_0000: ldarg.0 + IL_0001: stloc.1 + IL_0002: ldloc.1 + IL_0003: conv.u + IL_0004: stloc.0 + IL_0005: ldloc.0 + IL_0006: ldc.i4.s 123 + IL_0008: stind.i4 + IL_0009: ldc.i4.0 + IL_000a: conv.u + IL_000b: stloc.1 + IL_000c: ldarg.0 + IL_000d: stloc.1 + IL_000e: ldloc.1 + IL_000f: conv.u + IL_0010: ldfld ""int Program.S1.x"" + IL_0015: call ""void System.Console.WriteLine(int)"" + IL_001a: ldc.i4.0 + IL_001b: conv.u + IL_001c: stloc.1 + IL_001d: ret +} +"); + } + [WorkItem(22306, "https://github.com/dotnet/roslyn/issues/22306")] [Fact] public void FixedStatementMultipleFields() From 14141fabd5508dd7fa2e0ca6350f86b224e51939 Mon Sep 17 00:00:00 2001 From: vsadov Date: Thu, 28 Sep 2017 22:59:06 -0700 Subject: [PATCH 12/16] fix test after rebase --- src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs index 354936f6450da..2672bb8354440 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs @@ -8564,9 +8564,10 @@ unsafe void M(ref readonly int p) int* pointer = &p; } }", options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( - // (6,25): error CS0211: Cannot take the address of the given expression + // (6,24): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer // int* pointer = &p; - Diagnostic(ErrorCode.ERR_InvalidAddrOp, "p").WithLocation(6, 25)); + Diagnostic(ErrorCode.ERR_FixedNeeded, "&p").WithLocation(6, 24) + ); } #endregion From cfaa1755da03526cd3a0ecfb5ea148973a1a0d61 Mon Sep 17 00:00:00 2001 From: Omar Tawfik Date: Fri, 29 Sep 2017 02:56:16 -0700 Subject: [PATCH 13/16] Fixed tests --- .../CSharp/Portable/Binder/Binder_Lambda.cs | 5 +- .../CSharp/Portable/Parser/LanguageParser.cs | 28 ++-- .../Symbols/Source/ParameterHelpers.cs | 44 ++--- .../Attributes/AttributeTests_Embedded.cs | 22 +-- .../Attributes/AttributeTests_RefReadOnly.cs | 32 ++-- .../CodeGenRefReadOnlyParametersTests.cs | 4 +- .../CodeGen/CodeGenRefReadonlyReturnTests.cs | 10 +- .../Emit/Emit/InAttributeModifierTests.cs | 4 +- .../Semantics/OverloadResolutionTests.cs | 2 +- .../Semantics/RefExtensionMethodsTests.cs | 85 +--------- .../Semantics/RefLocalsAndReturnsTests.cs | 12 +- .../Test/Semantic/Semantics/VarianceTests.cs | 4 +- .../SymbolDisplay/SymbolDisplayTests.cs | 6 +- .../Syntax/Parsing/ParserErrorMessageTests.cs | 153 +++++++----------- .../Test/Syntax/Parsing/RefReadonlyTests.cs | 71 +++++++- .../Metadata/PE/InAttributeModifierTests.vb | 6 +- .../EditAndContinue/StatementEditingTests.cs | 6 +- .../ThisKeywordRecommenderTests.cs | 17 +- .../ExpressionCompilerTests.cs | 2 +- .../InKeywordRecommender.cs | 4 + .../ReadOnlyKeywordRecommender.cs | 10 +- .../CSharpEditAndContinueAnalyzer.cs | 29 ++-- .../ContextQuery/SyntaxTreeExtensions.cs | 2 +- 23 files changed, 243 insertions(+), 315 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs index d2047dc16245a..7e4475b0beaf5 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs @@ -125,8 +125,6 @@ private Tuple, ImmutableArray, ImmutableArra type = BindType(typeSyntax, diagnostics); foreach (var modifier in p.Modifiers) { - var modKind = modifier.Kind(); - switch (modifier.Kind()) { case SyntaxKind.RefKeyword: @@ -139,8 +137,7 @@ private Tuple, ImmutableArray, ImmutableArra allValue = false; break; - case SyntaxKind.ReadOnlyKeyword: - Debug.Assert(refKind == RefKind.Ref || syntax.HasErrors); + case SyntaxKind.InKeyword: refKind = RefKind.In; allValue = false; break; diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index 9b2d7cc035d3f..842fe9063497f 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -3703,19 +3703,15 @@ private bool IsPossibleParameter() switch (this.CurrentToken.Kind) { case SyntaxKind.OpenBracketToken: // attribute - case SyntaxKind.RefKeyword: - case SyntaxKind.OutKeyword: - case SyntaxKind.ParamsKeyword: case SyntaxKind.ArgListKeyword: case SyntaxKind.OpenParenToken: // tuple - case SyntaxKind.ThisKeyword: return true; case SyntaxKind.IdentifierToken: return this.IsTrueIdentifier(); default: - return IsPredefinedType(this.CurrentToken.Kind); + return IsParameterModifier(this.CurrentToken.Kind) || IsPredefinedType(this.CurrentToken.Kind); } } @@ -3827,8 +3823,8 @@ private static bool IsParameterModifier(SyntaxKind kind) case SyntaxKind.ThisKeyword: case SyntaxKind.RefKeyword: case SyntaxKind.OutKeyword: + case SyntaxKind.InKeyword: case SyntaxKind.ParamsKeyword: - case SyntaxKind.ReadOnlyKeyword: return true; } @@ -3849,26 +3845,23 @@ private void ParseParameterModifiers(SyntaxListBuilder modifiers) case SyntaxKind.RefKeyword: { - var nextKind = this.CurrentToken.Kind; - - // "ref this" - if (nextKind == SyntaxKind.ThisKeyword) + if (this.CurrentToken.Kind == SyntaxKind.ThisKeyword) { modifier = CheckFeatureAvailability(modifier, MessageID.IDS_FeatureRefExtensionMethods); } + break; } case SyntaxKind.InKeyword: { modifier = CheckFeatureAvailability(modifier, MessageID.IDS_FeatureReadOnlyReferences); - var nextKind = this.CurrentToken.Kind; - // "in this" - if (nextKind == SyntaxKind.ThisKeyword) + if (this.CurrentToken.Kind == SyntaxKind.ThisKeyword) { modifier = CheckFeatureAvailability(modifier, MessageID.IDS_FeatureRefExtensionMethods); } + break; } } @@ -5892,15 +5885,21 @@ private ScanTypeFlags ScanNonArrayType(ParseTypeMode mode, out SyntaxToken lastT { ScanTypeFlags result; - // in a ref local or ref return, we treat "ref" and "ref readonly" as part of the type if (this.CurrentToken.Kind == SyntaxKind.RefKeyword) { + // in a ref local or ref return, we treat "ref" and "ref readonly" as part of the type this.EatToken(); + if (this.CurrentToken.Kind == SyntaxKind.ReadOnlyKeyword) { this.EatToken(); } } + else if (this.CurrentToken.Kind == SyntaxKind.InKeyword) + { + // Start of a lambda parameter + this.EatToken(); + } if (this.CurrentToken.Kind == SyntaxKind.IdentifierToken) { @@ -10814,6 +10813,7 @@ private bool IsPossibleLambdaParameter() // recovery purposes and then give an error during semantic analysis. case SyntaxKind.RefKeyword: case SyntaxKind.OutKeyword: + case SyntaxKind.InKeyword: case SyntaxKind.OpenParenToken: // tuple return true; diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs b/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs index b3c9fb1bcd08d..82f633730dd44 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs @@ -1,14 +1,11 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; -using System.Linq; -using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.PooledObjects; -using Microsoft.CodeAnalysis.Text; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Symbols { @@ -141,7 +138,7 @@ private static void CheckParameterModifiers( var seenRef = false; var seenOut = false; var seenParams = false; - var seenRefReadOnly = false; + var seenIn = false; foreach (var modifier in parameter.Modifiers) { @@ -167,7 +164,7 @@ private static void CheckParameterModifiers( break; case SyntaxKind.RefKeyword: - if (seenRef || seenRefReadOnly) + if (seenRef) { diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.RefKeyword)); } @@ -183,6 +180,10 @@ private static void CheckParameterModifiers( { diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.RefKeyword), SyntaxFacts.GetText(SyntaxKind.OutKeyword)); } + else if (seenIn) + { + diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.OutKeyword), SyntaxFacts.GetText(SyntaxKind.InKeyword)); + } else { seenRef = true; @@ -202,10 +203,14 @@ private static void CheckParameterModifiers( { diagnostics.Add(ErrorCode.ERR_ParamsCantBeWithModifier, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.OutKeyword)); } - else if (seenRef || seenRefReadOnly) + else if (seenRef) { diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.OutKeyword), SyntaxFacts.GetText(SyntaxKind.RefKeyword)); } + else if (seenIn) + { + diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.OutKeyword), SyntaxFacts.GetText(SyntaxKind.InKeyword)); + } else { seenOut = true; @@ -221,10 +226,14 @@ private static void CheckParameterModifiers( { diagnostics.Add(ErrorCode.ERR_BadParamModThis, modifier.GetLocation()); } - else if (seenRef || seenRefReadOnly) + else if (seenRef) { diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ParamsKeyword), SyntaxFacts.GetText(SyntaxKind.RefKeyword)); } + else if (seenIn) + { + diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.OutKeyword), SyntaxFacts.GetText(SyntaxKind.InKeyword)); + } else if (seenOut) { diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ParamsKeyword), SyntaxFacts.GetText(SyntaxKind.OutKeyword)); @@ -235,36 +244,35 @@ private static void CheckParameterModifiers( } break; - case SyntaxKind.ReadOnlyKeyword: - if(seenRefReadOnly) + case SyntaxKind.InKeyword: + if(seenIn) { - diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ReadOnlyKeyword)); + diagnostics.Add(ErrorCode.ERR_DupParamMod, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.InKeyword)); } else if (seenOut) { - diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ReadOnlyKeyword), SyntaxFacts.GetText(SyntaxKind.OutKeyword)); + diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.InKeyword), SyntaxFacts.GetText(SyntaxKind.OutKeyword)); } else if (seenThis) { - diagnostics.Add(ErrorCode.ERR_BadParameterModifiersOrder, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ReadOnlyKeyword), SyntaxFacts.GetText(SyntaxKind.ThisKeyword)); + diagnostics.Add(ErrorCode.ERR_BadParameterModifiersOrder, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.InKeyword), SyntaxFacts.GetText(SyntaxKind.ThisKeyword)); } else if(seenRef) { - seenRef = false; - seenRefReadOnly = true; + diagnostics.Add(ErrorCode.ERR_BadParameterModifiers, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.InKeyword), SyntaxFacts.GetText(SyntaxKind.RefKeyword)); } else if (seenParams) { - diagnostics.Add(ErrorCode.ERR_ParamsCantBeWithModifier, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ReadOnlyKeyword)); + diagnostics.Add(ErrorCode.ERR_ParamsCantBeWithModifier, modifier.GetLocation(), SyntaxFacts.GetText(SyntaxKind.InKeyword)); } else { - diagnostics.Add(ErrorCode.ERR_UnexpectedToken, modifier.GetLocation(), modifier.Text); + seenIn = true; } break; default: - throw new InvalidOperationException($"Unexpected SyntaxKind {modifier.Kind()}"); + throw ExceptionUtilities.UnexpectedValue(modifier.Kind()); } } } diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Embedded.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Embedded.cs index 2e589169275dd..585ad9ddf75a0 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Embedded.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Embedded.cs @@ -332,27 +332,27 @@ public class Test }"; CreateCompilation(code).VerifyEmitDiagnostics(CodeAnalysis.Emit.EmitOptions.Default.WithRuntimeMetadataVersion("v4.0.30319"), - // (4,18): error CS0518: Predefined type 'System.Object' is not defined or imported - // public class Attribute {} - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "Attribute").WithArguments("System.Object"), - // (7,14): error CS0518: Predefined type 'System.Object' is not defined or imported - // public class Test - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "Test").WithArguments("System.Object"), // (5,18): error CS0518: Predefined type 'System.Object' is not defined or imported // public class Void {} Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "Void").WithArguments("System.Object").WithLocation(5, 18), - // (9,34): error CS0518: Predefined type 'System.Object' is not defined or imported + // (7,14): error CS0518: Predefined type 'System.Object' is not defined or imported + // public class Test + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "Test").WithArguments("System.Object").WithLocation(7, 14), + // (4,18): error CS0518: Predefined type 'System.Object' is not defined or imported + // public class Attribute {} + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "Attribute").WithArguments("System.Object").WithLocation(4, 18), + // (9,24): error CS0518: Predefined type 'System.Object' is not defined or imported // public object M(in object x) { return x; } // should trigger synthesizing IsReadOnly - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "object").WithArguments("System.Object").WithLocation(9, 34), + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "object").WithArguments("System.Object").WithLocation(9, 24), // (9,12): error CS0518: Predefined type 'System.Object' is not defined or imported // public object M(in object x) { return x; } // should trigger synthesizing IsReadOnly Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "object").WithArguments("System.Object").WithLocation(9, 12), - // (5,18): error CS1729: 'object' does not contain a constructor that takes 0 arguments - // public class Void {} - Diagnostic(ErrorCode.ERR_BadCtorArgCount, "Void").WithArguments("object", "0").WithLocation(5, 18), // (4,18): error CS1729: 'object' does not contain a constructor that takes 0 arguments // public class Attribute {} Diagnostic(ErrorCode.ERR_BadCtorArgCount, "Attribute").WithArguments("object", "0").WithLocation(4, 18), + // (5,18): error CS1729: 'object' does not contain a constructor that takes 0 arguments + // public class Void {} + Diagnostic(ErrorCode.ERR_BadCtorArgCount, "Void").WithArguments("object", "0").WithLocation(5, 18), // (7,14): error CS1729: 'object' does not contain a constructor that takes 0 arguments // public class Test Diagnostic(ErrorCode.ERR_BadCtorArgCount, "Test").WithArguments("object", "0").WithLocation(7, 14)); diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_RefReadOnly.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_RefReadOnly.cs index 543aea9f73c57..7e26ebfcd43cc 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_RefReadOnly.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_RefReadOnly.cs @@ -480,7 +480,7 @@ namespace System.Runtime.CompilerServices { public class IsReadOnlyAttribute : System.Attribute { } } -public delegate in int D(in int x); +public delegate ref readonly int D(in int x); "; CompileAndVerify(text, symbolValidator: module => @@ -517,7 +517,7 @@ public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Delegate_Parameter public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Delegate_ReturnType() { var text = @" -public delegate in int D(); +public delegate ref readonly int D(); "; CompileAndVerify(text, symbolValidator: module => @@ -1932,7 +1932,7 @@ public interface IsReadOnlyAttribute 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, "ref readonly int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(6, 33)); + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int x").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(6, 33)); } [Fact] @@ -2116,15 +2116,15 @@ public void RefReadOnlyDefinitionsInsideUserDefinedIsReadOnlyAttribute_Delegate( var code = @" namespace System.Runtime.CompilerServices { - public delegate in int IsReadOnlyAttribute(in int x); + public delegate ref readonly int IsReadOnlyAttribute(in int x); }"; CreateStandardCompilation(code).VerifyEmitDiagnostics( // (4,21): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' - // public delegate in int IsReadOnlyAttribute(in int x); - Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(4, 21), + // 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 in int IsReadOnlyAttribute(in int x); + // 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)); } @@ -2168,8 +2168,8 @@ public class Test CreateStandardCompilation(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, "in int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 12), + // public ref readonly int Method(ref readonly 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)); @@ -2204,7 +2204,7 @@ ref readonly int local(in int p) CreateStandardCompilation(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, "in int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(15, 9), + 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)); @@ -2214,7 +2214,7 @@ ref readonly int local(in int p) public void MissingRequiredConstructorWillReportErrorsOnApproriateSyntax_Lambda() { var reference = CreateStandardCompilation(@" -public delegate in int D(in int x); +public delegate ref readonly int D(in int x); ").EmitToImageReference(); var text = @" @@ -2239,7 +2239,7 @@ public void M2(D value) { } CreateStandardCompilation(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, 33), + 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)); @@ -2265,7 +2265,7 @@ public class Test CreateStandardCompilation(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, "in int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(12, 12)); + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "ref readonly int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(12, 12)); } [Fact] @@ -2288,7 +2288,7 @@ public class Test CreateStandardCompilation(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, "in int").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(12, 12), + 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)); @@ -2314,9 +2314,9 @@ public class Test // (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,56): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IsReadOnlyAttribute..ctor' + // (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, 56)); + Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "in Test y").WithArguments("System.Runtime.CompilerServices.IsReadOnlyAttribute", ".ctor").WithLocation(11, 46)); } private void AssertReferencedIsReadOnlyAttribute(Accessibility accessibility, ImmutableArray attributes, string assemblyName) diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs index 300b653511769..7031510a8d94c 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs @@ -287,7 +287,7 @@ public static void Main() System.Console.WriteLine(p.M(42)); } - public Program(ref readonly string x) + public Program(in string x) { SI = x; } @@ -300,7 +300,7 @@ public virtual ref readonly int M(in int x) class P1 : Program { - public P1(ref readonly string x) : base(x){} + public P1(in string x) : base(x){} public override ref readonly int M(in int x) { diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs index d37193a75be9b..a1eaf44b57b80 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadonlyReturnTests.cs @@ -40,14 +40,14 @@ class C ref readonly S M() { - in S rs1 = ref s1; + ref readonly S rs1 = ref s1; rs1.AddOne(); - in S rs2 = ref s2; + ref readonly S rs2 = ref s2; rs2.AddOne(); - in S2 rs3 = ref s3; + ref readonly S2 rs3 = ref s3; rs3.AddOne(); - in S2 rs4 = ref s4; + ref readonly S2 rs4 = ref s4; rs4.AddOne(); return ref rs1; @@ -1023,7 +1023,7 @@ ref readonly S1 Test() Diagnostic(ErrorCode.ERR_RefReturnStructThis, "this").WithArguments("this").WithLocation(8, 20), // (11,44): error CS8170: Struct members cannot return 'this' or other instance members by reference // in int this[in int i] => ref x; - Diagnostic(ErrorCode.ERR_RefReturnStructThis, "x").WithArguments("this").WithLocation(11, 54) + Diagnostic(ErrorCode.ERR_RefReturnStructThis, "x").WithArguments("this").WithLocation(11, 44) ); } diff --git a/src/Compilers/CSharp/Test/Emit/Emit/InAttributeModifierTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/InAttributeModifierTests.cs index 1a04602fa77b2..6532e3fc3d445 100644 --- a/src/Compilers/CSharp/Test/Emit/Emit/InAttributeModifierTests.cs +++ b/src/Compilers/CSharp/Test/Emit/Emit/InAttributeModifierTests.cs @@ -3715,7 +3715,7 @@ namespace System.Runtime.InteropServices { public class InAttribute {} } -public delegate void D(ref readonly int p);"); +public delegate void D(in int p);"); CompileAndVerify(reference, symbolValidator: module => { @@ -3734,7 +3734,7 @@ public class Test { public static void Main() { - Run((ref readonly int p) => System.Console.WriteLine(p)); + Run((in int p) => System.Console.WriteLine(p)); } public static void Run(D lambda) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs index 41591ca93c95b..9e0f985a44ddc 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs @@ -9420,7 +9420,7 @@ public static void Method(in int p) public static void Main() { int x = 5; - Method(in x); + Method(ref readonly x); } }"; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefExtensionMethodsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefExtensionMethodsTests.cs index c02278f0faef6..36dc918a4b12c 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefExtensionMethodsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefExtensionMethodsTests.cs @@ -2040,7 +2040,7 @@ public static void Main() } [Fact] - public void UsingRefExtensionMethodsBeforeVersion7_2ProducesDiagnostics_RefReadOnlySyntax_SameCompilation() + public void UsingRefExtensionMethodsBeforeVersion7_2ProducesDiagnostics_InSyntax_SameCompilation() { var code = @" public static class Ext @@ -2062,87 +2062,10 @@ public static void Main() CreateCompilationWithMscorlibAndSystemCore(code, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_1)).VerifyDiagnostics( // (4,30): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. // public static void Print(in this int p) - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "ref").WithArguments("readonly references", "7.2").WithLocation(4, 30), + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "in").WithArguments("readonly references", "7.2").WithLocation(4, 30), // (4,30): error CS8302: Feature 'ref extension methods' is not available in C# 7.1. Please use language version 7.2 or greater. // public static void Print(in this int p) - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "ref").WithArguments("ref extension methods", "7.2").WithLocation(4, 30), - // (14,9): error CS8302: Feature 'ref extension methods' is not available in C# 7.1. Please use language version 7.2 or greater. - // p.Print(); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "p").WithArguments("ref extension methods", "7.2").WithLocation(14, 9) - ); - - CompileAndVerify(code, additionalRefs: new[] { SystemCoreRef }, expectedOutput: "5"); - } - - [Fact] - public void UsingRefExtensionMethodsBeforeVersion7_2ProducesDiagnostics_RefReadOnlySyntax_DifferentCompilation() - { - var reference = CreateCompilationWithMscorlibAndSystemCore(@" -public static class Ext -{ - public static void Print(in this int p) - { - System.Console.WriteLine(p); - } -}"); - - var code = @" -public static class Program -{ - public static void Main() - { - int p = 5; - p.Print(); - } -}"; - - CreateCompilationWithMscorlibAndSystemCore( - text: code, - parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_1), - references: new[] { reference.ToMetadataReference() }).VerifyDiagnostics( - // (7,9): error CS8302: Feature 'ref extension methods' is not available in C# 7.1. Please use language version 7.2 or greater. - // p.Print(); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "p").WithArguments("ref extension methods", "7.2").WithLocation(7, 9)); - - CreateCompilationWithMscorlibAndSystemCore( - text: code, - parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_1), - references: new[] { reference.EmitToImageReference() }).VerifyDiagnostics( - // (7,9): error CS8302: Feature 'ref extension methods' is not available in C# 7.1. Please use language version 7.2 or greater. - // p.Print(); - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "p").WithArguments("ref extension methods", "7.2").WithLocation(7, 9)); - - CompileAndVerify(code, additionalRefs: new[] { SystemCoreRef, reference.ToMetadataReference() }, expectedOutput: "5"); - CompileAndVerify(code, additionalRefs: new[] { SystemCoreRef, reference.EmitToImageReference() }, expectedOutput: "5"); - } - - [Fact] - public void UsingRefExtensionMethodsBeforeVersion7_2ProducesDiagnostics_InSyntax_SameCompilation() - { - var code = @" -public static class Ext -{ - public static void Print(in this int p) - { - System.Console.WriteLine(p); - } -} -public static class Program -{ - public static void Main() - { - int p = 5; - p.Print(); - } -}"; - - CreateCompilationWithMscorlibAndSystemCore(code, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_1)).VerifyDiagnostics( - // (4,30): error CS8302: Feature 'ref extension methods' is not available in C# 7.1. Please use language version 7.2 or greater. - // public static void Print(in this int p) - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "ref").WithArguments("ref extension methods", "7.2").WithLocation(4, 30), - // (4,30): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. - // public static void Print(in this int p) - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "ref").WithArguments("readonly references", "7.2").WithLocation(4, 30), + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "in").WithArguments("ref extension methods", "7.2").WithLocation(4, 30), // (14,9): error CS8302: Feature 'ref extension methods' is not available in C# 7.1. Please use language version 7.2 or greater. // p.Print(); Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "p").WithArguments("ref extension methods", "7.2").WithLocation(14, 9) @@ -2192,7 +2115,7 @@ public static void Main() CompileAndVerify(code, additionalRefs: new[] { SystemCoreRef, reference.ToMetadataReference() }, expectedOutput: "5"); CompileAndVerify(code, additionalRefs: new[] { SystemCoreRef, reference.EmitToImageReference() }, expectedOutput: "5"); } - + private const string ExtraRefReadOnlyIL = @" .class private auto ansi sealed beforefieldinit Microsoft.CodeAnalysis.EmbeddedAttribute extends [mscorlib]System.Attribute { diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs index 3acc98bc0ef08..60a575b2a7140 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs @@ -2709,9 +2709,9 @@ async Task Method(in int p) await Task.FromResult(0); } }").VerifyDiagnostics( - // (5,40): error CS1988: Async methods cannot have ref or out parameters + // (5,30): error CS1988: Async methods cannot have ref or out parameters // async Task Method(in int p) - Diagnostic(ErrorCode.ERR_BadAsyncArgType, "p").WithLocation(5, 40)); + Diagnostic(ErrorCode.ERR_BadAsyncArgType, "p").WithLocation(5, 30)); } [Fact] @@ -2728,9 +2728,9 @@ IEnumerable Method(in int p) yield return 2; } }").VerifyDiagnostics( - // (5,46): error CS1623: Iterators cannot have ref or out parameters + // (5,36): error CS1623: Iterators cannot have ref or out parameters // IEnumerable Method(in int p) - Diagnostic(ErrorCode.ERR_BadIteratorArgType, "p").WithLocation(5, 46)); + Diagnostic(ErrorCode.ERR_BadIteratorArgType, "p").WithLocation(5, 36)); } [Fact] @@ -2745,9 +2745,9 @@ public IEnumerator GetEnumerator(in int p) yield return 0; } }").VerifyDiagnostics( - // (5,60): error CS1623: Iterators cannot have ref or out parameters + // (5,50): error CS1623: Iterators cannot have ref or out parameters // public IEnumerator GetEnumerator(in int p) - Diagnostic(ErrorCode.ERR_BadIteratorArgType, "p").WithLocation(5, 60)); + Diagnostic(ErrorCode.ERR_BadIteratorArgType, "p").WithLocation(5, 50)); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/VarianceTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/VarianceTests.cs index f14d71c584832..8016397e3e379 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/VarianceTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/VarianceTests.cs @@ -636,9 +636,9 @@ interface ITest { void M(in T p); }").VerifyDiagnostics( - // (4,25): error CS1961: Invalid variance: The type parameter 'T' must be invariantly valid on 'ITest.M(in T)'. 'T' is contravariant. + // (4,15): error CS1961: Invalid variance: The type parameter 'T' must be invariantly valid on 'ITest.M(in T)'. 'T' is contravariant. // void M(in T p); - Diagnostic(ErrorCode.ERR_UnexpectedVariance, "T").WithArguments("ITest.M(in T)", "T", "contravariant", "invariantly").WithLocation(4, 25)); + Diagnostic(ErrorCode.ERR_UnexpectedVariance, "T").WithArguments("ITest.M(in T)", "T", "contravariant", "invariantly").WithLocation(4, 15)); } [Fact] diff --git a/src/Compilers/CSharp/Test/Symbol/SymbolDisplay/SymbolDisplayTests.cs b/src/Compilers/CSharp/Test/Symbol/SymbolDisplay/SymbolDisplayTests.cs index 4771e4b030c26..db5e8d6da25cc 100644 --- a/src/Compilers/CSharp/Test/Symbol/SymbolDisplay/SymbolDisplayTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/SymbolDisplay/SymbolDisplayTests.cs @@ -5698,6 +5698,8 @@ private static void RefReadonlyReturnInternal(Compilation comp) SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Space, SymbolDisplayPartKind.Keyword, + SymbolDisplayPartKind.Space, + SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Punctuation, SymbolDisplayPartKind.Keyword, SymbolDisplayPartKind.Space, @@ -5943,9 +5945,7 @@ async unsafe Task Local(in int* x, out char? c) SymbolDisplayPartKind.Space, SymbolDisplayPartKind.MethodName, // Local SymbolDisplayPartKind.Punctuation, // ( - SymbolDisplayPartKind.Keyword, // ref - SymbolDisplayPartKind.Space, - SymbolDisplayPartKind.Keyword, // readonly + SymbolDisplayPartKind.Keyword, // in SymbolDisplayPartKind.Space, SymbolDisplayPartKind.NamespaceName, // System SymbolDisplayPartKind.Punctuation, // . diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs index e00f739d2a6ba..83fad8d168b18 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs @@ -3160,7 +3160,7 @@ public void DoSomething(in int x) { } ParseAndValidate(code, new CSharpParseOptions(LanguageVersion.CSharp7), // (4,29): error CS8107: Feature 'readonly references' is not available in C# 7. Please use language version 7.2 or greater. // public void DoSomething(in int x) { } - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "ref").WithArguments("readonly references", "7.2").WithLocation(4, 29) + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "in").WithArguments("readonly references", "7.2").WithLocation(4, 29) ); } @@ -3432,12 +3432,9 @@ public static void Test5(in in int[] i) {} "; CreateCompilationWithMscorlibAndSystemCore(test).GetDeclarationDiagnostics().Verify( - // (8,43): error CS1107: A parameter can only have one 'ref' modifier + // (8,33): error CS1107: A parameter can only have one 'in' modifier // public static void Test5(in in int[] i) {} - Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(8, 43), - // (8,47): error CS1107: A parameter can only have one 'readonly' modifier - // public static void Test6(in in int[] i) {} - Diagnostic(ErrorCode.ERR_DupParamMod, "readonly").WithArguments("readonly").WithLocation(8, 47), + Diagnostic(ErrorCode.ERR_DupParamMod, "in").WithArguments("in").WithLocation(8, 33), // (5,34): error CS1107: A parameter can only have one 'out' modifier // public static void Test2(out out int i) {} Diagnostic(ErrorCode.ERR_DupParamMod, "out").WithArguments("out").WithLocation(5, 34), @@ -3474,24 +3471,24 @@ public static void Method6(ref in int i) { } "; CreateCompilationWithMscorlibAndSystemCore(test).GetDeclarationDiagnostics().Verify( - // (5,41): error CS1107: A parameter can only have one 'ref' modifier - // public static void Method1(in ref int i) { } - Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(5, 41), - // (6,32): error CS1107: A parameter can only have one 'ref' modifier + // (6,32): error CS8328: The parameter modifier 'in' cannot be used with 'ref' // public static void Method2(ref in int i) { } - Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(6, 32), - // (9,44): error CS1107: A parameter can only have one 'ref' modifier + Diagnostic(ErrorCode.ERR_BadParameterModifiers, "in").WithArguments("in", "ref").WithLocation(6, 32), + // (9,34): error CS8328: The parameter modifier 'out' cannot be used with 'in' // public static void Method3(in ref int i) { } - Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(9, 44), - // (10,35): error CS1107: A parameter can only have one 'ref' modifier + Diagnostic(ErrorCode.ERR_BadParameterModifiers, "ref").WithArguments("out", "in").WithLocation(9, 34), + // (10,35): error CS8328: The parameter modifier 'in' cannot be used with 'ref' // public static void Method4(ref in int i) { } - Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(10, 35), - // (13,50): error CS1107: A parameter can only have one 'ref' modifier + Diagnostic(ErrorCode.ERR_BadParameterModifiers, "in").WithArguments("in", "ref").WithLocation(10, 35), + // (13,40): error CS8328: The parameter modifier 'out' cannot be used with 'in' // public static void Method5(in ref int i) { } - Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(13, 50), - // (14,41): error CS1107: A parameter can only have one 'ref' modifier + Diagnostic(ErrorCode.ERR_BadParameterModifiers, "ref").WithArguments("out", "in").WithLocation(13, 40), + // (14,41): error CS8328: The parameter modifier 'in' cannot be used with 'ref' // public static void Method6(ref in int i) { } - Diagnostic(ErrorCode.ERR_DupParamMod, "ref").WithArguments("ref").WithLocation(14, 41)); + Diagnostic(ErrorCode.ERR_BadParameterModifiers, "in").WithArguments("in", "ref").WithLocation(14, 41), + // (5,31): error CS8328: The parameter modifier 'out' cannot be used with 'in' + // public static void Method1(in ref int i) { } + Diagnostic(ErrorCode.ERR_BadParameterModifiers, "ref").WithArguments("out", "in").WithLocation(5, 31)); } [Fact] @@ -3516,24 +3513,15 @@ public static void Method6(this in int i) { } "; CreateCompilationWithMscorlibAndSystemCore(test).GetDeclarationDiagnostics().Verify( - // (14,42): error CS8339: The parameter modifier 'ref' cannot be used after the modifier 'this' - // public static void Method6(this in int i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "ref").WithArguments("ref", "this").WithLocation(14, 42), - // (14,46): error CS8339: The parameter modifier 'readonly' cannot be used after the modifier 'this' + // (14,42): error CS8339: The parameter modifier 'in' cannot be used after the modifier 'this' // public static void Method6(this in int i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "readonly").WithArguments("readonly", "this").WithLocation(14, 46), - // (6,33): error CS8339: The parameter modifier 'ref' cannot be used after the modifier 'this' + Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "in").WithArguments("in", "this").WithLocation(14, 42), + // (6,33): error CS8339: The parameter modifier 'in' cannot be used after the modifier 'this' // public static void Method2(this in int i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "ref").WithArguments("ref", "this").WithLocation(6, 33), - // (6,37): error CS8339: The parameter modifier 'readonly' cannot be used after the modifier 'this' - // public static void Method2(this in int i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "readonly").WithArguments("readonly", "this").WithLocation(6, 37), - // (10,36): error CS8339: The parameter modifier 'ref' cannot be used after the modifier 'this' - // public static void Method4(this in int i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "ref").WithArguments("ref", "this").WithLocation(10, 36), - // (10,40): error CS8339: The parameter modifier 'readonly' cannot be used after the modifier 'this' + Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "in").WithArguments("in", "this").WithLocation(6, 33), + // (10,36): error CS8339: The parameter modifier 'in' cannot be used after the modifier 'this' // public static void Method4(this in int i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "readonly").WithArguments("readonly", "this").WithLocation(10, 40)); + Diagnostic(ErrorCode.ERR_BadParameterModifiersOrder, "in").WithArguments("in", "this").WithLocation(10, 36)); } [Fact] @@ -3558,38 +3546,29 @@ public static void Method6(params in int[] i) { } "; CreateCompilationWithMscorlibAndSystemCore(test).GetDeclarationDiagnostics().Verify( - // (6,35): error CS1611: The params parameter cannot be declared as ref + // (6,35): error CS1611: The params parameter cannot be declared as in // public static void Method2(params in int[] i) { } - Diagnostic(ErrorCode.ERR_ParamsCantBeWithModifier, "ref").WithArguments("ref").WithLocation(6, 35), - // (6,39): error CS1611: The params parameter cannot be declared as readonly - // public static void Method2(params in int[] i) { } - Diagnostic(ErrorCode.ERR_ParamsCantBeWithModifier, "readonly").WithArguments("readonly").WithLocation(6, 39), - // (9,44): error CS8328: The parameter modifier 'params' cannot be used with 'ref' + Diagnostic(ErrorCode.ERR_ParamsCantBeWithModifier, "in").WithArguments("in").WithLocation(6, 35), + // (9,34): error CS8328: The parameter modifier 'out' cannot be used with 'in' // public static void Method3(in params int[] i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiers, "params").WithArguments("params", "ref").WithLocation(9, 44), - // (10,38): error CS1611: The params parameter cannot be declared as ref - // public static void Method4(params in int[] i) { } - Diagnostic(ErrorCode.ERR_ParamsCantBeWithModifier, "ref").WithArguments("ref").WithLocation(10, 38), - // (10,42): error CS1611: The params parameter cannot be declared as readonly + Diagnostic(ErrorCode.ERR_BadParameterModifiers, "params").WithArguments("out", "in").WithLocation(9, 34), + // (10,38): error CS1611: The params parameter cannot be declared as in // public static void Method4(params in int[] i) { } - Diagnostic(ErrorCode.ERR_ParamsCantBeWithModifier, "readonly").WithArguments("readonly").WithLocation(10, 42), - // (13,50): error CS8328: The parameter modifier 'params' cannot be used with 'ref' + Diagnostic(ErrorCode.ERR_ParamsCantBeWithModifier, "in").WithArguments("in").WithLocation(10, 38), + // (13,40): error CS8328: The parameter modifier 'out' cannot be used with 'in' // public static void Method5(in params int[] i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiers, "params").WithArguments("params", "ref").WithLocation(13, 50), - // (14,44): error CS1611: The params parameter cannot be declared as ref + Diagnostic(ErrorCode.ERR_BadParameterModifiers, "params").WithArguments("out", "in").WithLocation(13, 40), + // (14,44): error CS1611: The params parameter cannot be declared as in // public static void Method6(params in int[] i) { } - Diagnostic(ErrorCode.ERR_ParamsCantBeWithModifier, "ref").WithArguments("ref").WithLocation(14, 44), - // (14,48): error CS1611: The params parameter cannot be declared as readonly - // public static void Method6(params in int[] i) { } - Diagnostic(ErrorCode.ERR_ParamsCantBeWithModifier, "readonly").WithArguments("readonly").WithLocation(14, 48), - // (5,41): error CS8328: The parameter modifier 'params' cannot be used with 'ref' + Diagnostic(ErrorCode.ERR_ParamsCantBeWithModifier, "in").WithArguments("in").WithLocation(14, 44), + // (5,31): error CS8328: The parameter modifier 'out' cannot be used with 'in' // public static void Method1(in params int[] i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiers, "params").WithArguments("params", "ref").WithLocation(5, 41)); + Diagnostic(ErrorCode.ERR_BadParameterModifiers, "params").WithArguments("out", "in").WithLocation(5, 31)); } [Fact] [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public void BadRefReadOnlyWithOutParameterModifiers() + public void BadInWithOutParameterModifiers() { var test = @" public class TestType @@ -3609,33 +3588,24 @@ public static void Method6(out in int i) { } "; CreateCompilationWithMscorlibAndSystemCore(test).GetDeclarationDiagnostics().Verify( - // (5,41): error CS8328: The parameter modifier 'out' cannot be used with 'ref' - // public static void Method1(in out int i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiers, "out").WithArguments("out", "ref").WithLocation(5, 41), - // (6,32): error CS8328: The parameter modifier 'ref' cannot be used with 'out' + // (6,32): error CS8328: The parameter modifier 'in' cannot be used with 'out' // public static void Method2(out in int i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiers, "ref").WithArguments("ref", "out").WithLocation(6, 32), - // (6,36): error CS8328: The parameter modifier 'readonly' cannot be used with 'out' - // public static void Method2(out in int i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiers, "readonly").WithArguments("readonly", "out").WithLocation(6, 36), - // (9,44): error CS8328: The parameter modifier 'out' cannot be used with 'ref' + Diagnostic(ErrorCode.ERR_BadParameterModifiers, "in").WithArguments("in", "out").WithLocation(6, 32), + // (9,34): error CS8328: The parameter modifier 'out' cannot be used with 'in' // public static void Method3(in out int i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiers, "out").WithArguments("out", "ref").WithLocation(9, 44), - // (10,35): error CS8328: The parameter modifier 'ref' cannot be used with 'out' - // public static void Method4(out in int i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiers, "ref").WithArguments("ref", "out").WithLocation(10, 35), - // (10,39): error CS8328: The parameter modifier 'readonly' cannot be used with 'out' + Diagnostic(ErrorCode.ERR_BadParameterModifiers, "out").WithArguments("out", "in").WithLocation(9, 34), + // (10,35): error CS8328: The parameter modifier 'in' cannot be used with 'out' // public static void Method4(out in int i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiers, "readonly").WithArguments("readonly", "out").WithLocation(10, 39), - // (13,50): error CS8328: The parameter modifier 'out' cannot be used with 'ref' + Diagnostic(ErrorCode.ERR_BadParameterModifiers, "in").WithArguments("in", "out").WithLocation(10, 35), + // (13,40): error CS8328: The parameter modifier 'out' cannot be used with 'in' // public static void Method5(in out int i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiers, "out").WithArguments("out", "ref").WithLocation(13, 50), - // (14,41): error CS8328: The parameter modifier 'ref' cannot be used with 'out' - // public static void Method6(out in int i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiers, "ref").WithArguments("ref", "out").WithLocation(14, 41), - // (14,45): error CS8328: The parameter modifier 'readonly' cannot be used with 'out' + Diagnostic(ErrorCode.ERR_BadParameterModifiers, "out").WithArguments("out", "in").WithLocation(13, 40), + // (14,41): error CS8328: The parameter modifier 'in' cannot be used with 'out' // public static void Method6(out in int i) { } - Diagnostic(ErrorCode.ERR_BadParameterModifiers, "readonly").WithArguments("readonly", "out").WithLocation(14, 45)); + Diagnostic(ErrorCode.ERR_BadParameterModifiers, "in").WithArguments("in", "out").WithLocation(14, 41), + // (5,31): error CS8328: The parameter modifier 'out' cannot be used with 'in' + // public static void Method1(in out int i) { } + Diagnostic(ErrorCode.ERR_BadParameterModifiers, "out").WithArguments("out", "in").WithLocation(5, 31)); } [Fact] @@ -3672,34 +3642,25 @@ public int this [in int f] tree.GetDiagnostics().Verify(); var methodDeclaration = (MethodDeclarationSyntax)tree.GetRoot().DescendantNodes().Single(node => node is MethodDeclarationSyntax); - verifyModifier(methodDeclaration.ParameterList.Parameters); + Assert.Equal(SyntaxKind.InKeyword, methodDeclaration.ParameterList.Parameters.Single().Modifiers.Single().Kind()); var delegateDeclaration = (DelegateDeclarationSyntax)tree.GetRoot().DescendantNodes().Single(node => node is DelegateDeclarationSyntax); - verifyModifier(delegateDeclaration.ParameterList.Parameters); + Assert.Equal(SyntaxKind.InKeyword, delegateDeclaration.ParameterList.Parameters.Single().Modifiers.Single().Kind()); var localFunctionStatement = (LocalFunctionStatementSyntax)tree.GetRoot().DescendantNodes().Single(node => node is LocalFunctionStatementSyntax); - verifyModifier(localFunctionStatement.ParameterList.Parameters); + Assert.Equal(SyntaxKind.InKeyword, localFunctionStatement.ParameterList.Parameters.Single().Modifiers.Single().Kind()); var lambdaExpression = (ParenthesizedLambdaExpressionSyntax)tree.GetRoot().DescendantNodes().Single(node => node is ParenthesizedLambdaExpressionSyntax); - verifyModifier(lambdaExpression.ParameterList.Parameters); + Assert.Equal(SyntaxKind.InKeyword, lambdaExpression.ParameterList.Parameters.Single().Modifiers.Single().Kind()); var anonymousMethodExpression = (AnonymousMethodExpressionSyntax)tree.GetRoot().DescendantNodes().Single(node => node is AnonymousMethodExpressionSyntax); - verifyModifier(anonymousMethodExpression.ParameterList.Parameters); + Assert.Equal(SyntaxKind.InKeyword, anonymousMethodExpression.ParameterList.Parameters.Single().Modifiers.Single().Kind()); var indexerDeclaration = (IndexerDeclarationSyntax)tree.GetRoot().DescendantNodes().Single(node => node is IndexerDeclarationSyntax); - verifyModifier(indexerDeclaration.ParameterList.Parameters); + Assert.Equal(SyntaxKind.InKeyword, indexerDeclaration.ParameterList.Parameters.Single().Modifiers.Single().Kind()); var operatorDeclaration = (OperatorDeclarationSyntax)tree.GetRoot().DescendantNodes().Single(node => node is OperatorDeclarationSyntax); - verifyModifier(operatorDeclaration.ParameterList.Parameters); - - void verifyModifier(SeparatedSyntaxList list) - { - var parameter = list.Single(); - Assert.Equal(2, parameter.Modifiers.Count); - - Assert.Equal(SyntaxKind.RefKeyword, parameter.Modifiers.First().Kind()); - Assert.Equal(SyntaxKind.ReadOnlyKeyword, parameter.Modifiers.Last().Kind()); - } + Assert.Equal(SyntaxKind.InKeyword, operatorDeclaration.ParameterList.Parameters.Single().Modifiers.Single().Kind()); } [Fact] @@ -5618,10 +5579,10 @@ public static void Main() CreateCompilationWithMscorlibAndSystemCore(code, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_1)).GetParseDiagnostics().Verify( // (4,30): error CS8302: Feature 'readonly references' is not available in C# 7.1. Please use language version 7.2 or greater. // public static void Print(in this int p) - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "ref").WithArguments("readonly references", "7.2").WithLocation(4, 30), + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "in").WithArguments("readonly references", "7.2").WithLocation(4, 30), // (4,30): error CS8302: Feature 'ref extension methods' is not available in C# 7.1. Please use language version 7.2 or greater. // public static void Print(in this int p) - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "ref").WithArguments("ref extension methods", "7.2").WithLocation(4, 30) + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_1, "in").WithArguments("ref extension methods", "7.2").WithLocation(4, 30) ); CompileAndVerify(code, additionalRefs: new[] { SystemCoreRef }, expectedOutput: "5"); diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs index 265bd599e83cb..e2c100e24d13f 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/RefReadonlyTests.cs @@ -288,7 +288,7 @@ void M(in int p) void N() { int x = 0; - M(in x); + M(ref readonly x); } }").GetParseDiagnostics().Verify( // (10,15): error CS1525: Invalid expression term 'readonly' @@ -314,6 +314,43 @@ void N() Diagnostic(ErrorCode.ERR_RbraceExpected, ")").WithLocation(10, 25)); } + [Fact] + public void InAtCallSite() + { + CreateStandardCompilation(@" +class Test +{ + void M(in int p) + { + } + void N() + { + int x = 0; + M(in x); + } +}").GetParseDiagnostics().Verify( + // (10,11): error CS1041: Identifier expected; 'in' is a keyword + // M(in x); + Diagnostic(ErrorCode.ERR_IdentifierExpectedKW, "in").WithArguments("", "in").WithLocation(10, 11)); + } + + [Fact] + public void NothingAtCallSite() + { + CreateStandardCompilation(@" +class Test +{ + void M(in int p) + { + } + void N() + { + int x = 0; + M(x); + } +}").GetParseDiagnostics().Verify(); + } + [Fact] public void InverseReadOnlyRefShouldBeIllegal() { @@ -364,9 +401,10 @@ public void InNotAllowedInReturnType() class Test { in int M() => throw null; -}").VerifyDiagnostics(); - - Assert.False(true); +}").VerifyDiagnostics( + // (4,5): error CS1519: Invalid token 'in' in class, struct, or interface member declaration + // in int M() => throw null; + Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "in").WithArguments("in").WithLocation(4, 5)); } [Fact] @@ -376,9 +414,28 @@ public void RefReadOnlyNotAllowedInParameters() class Test { void M(ref readonly int p) => throw null; -}").VerifyDiagnostics(); - - Assert.False(true); +}").VerifyDiagnostics( + // (4,16): error CS1031: Type expected + // void M(ref readonly int p) => throw null; + Diagnostic(ErrorCode.ERR_TypeExpected, "readonly").WithLocation(4, 16), + // (4,16): error CS1001: Identifier expected + // void M(ref readonly int p) => throw null; + Diagnostic(ErrorCode.ERR_IdentifierExpected, "readonly").WithLocation(4, 16), + // (4,16): error CS1026: ) expected + // void M(ref readonly int p) => throw null; + Diagnostic(ErrorCode.ERR_CloseParenExpected, "readonly").WithLocation(4, 16), + // (4,16): error CS1002: ; expected + // void M(ref readonly int p) => throw null; + Diagnostic(ErrorCode.ERR_SemicolonExpected, "readonly").WithLocation(4, 16), + // (4,30): error CS1003: Syntax error, ',' expected + // void M(ref readonly int p) => throw null; + Diagnostic(ErrorCode.ERR_SyntaxError, ")").WithArguments(",", ")").WithLocation(4, 30), + // (4,10): error CS0501: 'Test.M(ref ?)' must declare a body because it is not marked abstract, extern, or partial + // void M(ref readonly int p) => throw null; + Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M").WithArguments("Test.M(ref ?)").WithLocation(4, 10), + // (4,29): warning CS0169: The field 'Test.p' is never used + // void M(ref readonly int p) => throw null; + Diagnostic(ErrorCode.WRN_UnreferencedField, "p").WithArguments("Test.p").WithLocation(4, 29)); } } } diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/InAttributeModifierTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/InAttributeModifierTests.vb index 94274de4b5490..9082c2944709d 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/InAttributeModifierTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/InAttributeModifierTests.vb @@ -184,7 +184,7 @@ BC30657: 'M' has a return type that is not supported or parameter types that are public class TestRef { private int value = 0; - public virtual in int M() + public virtual ref readonly int M() { return ref value; } @@ -216,7 +216,7 @@ BC30657: 'M' has a return type that is not supported or parameter types that are Dim reference = CreateCSharpCompilation(" public abstract class TestRef { - public abstract in int M(); + public abstract ref readonly int M(); }", parseOptions:=New CSharpParseOptions(CSharp.LanguageVersion.Latest)).EmitToImageReference() Dim source = @@ -245,7 +245,7 @@ BC30657: 'M' has a return type that is not supported or parameter types that are public class TestRef { private static int value = 0; - public static in int M() + public static ref readonly int M() { return ref value; } diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs index 3f1e8e94ab093..9bdd99ef3feb4 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs @@ -6698,7 +6698,7 @@ static void Main(int X) } [Fact] - public void LocalFunction_ReadOnlyRef_Parameter_InsertWhole() + public void LocalFunction_In_Parameter_InsertWhole() { var src1 = @"class Test { void M() { } }"; var src2 = @"class Test { void M() { void local(in int b) { throw null; } } }"; @@ -6713,7 +6713,7 @@ public void LocalFunction_ReadOnlyRef_Parameter_InsertWhole() } [Fact] - public void LocalFunction_ReadOnlyRef_Parameter_InsertParameter() + public void LocalFunction_In_Parameter_InsertParameter() { var src1 = @"class Test { void M() { void local() { throw null; } } }"; var src2 = @"class Test { void M() { void local(in int b) { throw null; } } }"; @@ -6728,7 +6728,7 @@ public void LocalFunction_ReadOnlyRef_Parameter_InsertParameter() } [Fact] - public void LocalFunction_ReadOnlyRef_Parameter_Update() + public void LocalFunction_In_Parameter_Update() { var src1 = @"class Test { void M() { void local(int b) { throw null; } } }"; var src2 = @"class Test { void M() { void local(in int b) { throw null; } } }"; diff --git a/src/EditorFeatures/CSharpTest2/Recommendations/ThisKeywordRecommenderTests.cs b/src/EditorFeatures/CSharpTest2/Recommendations/ThisKeywordRecommenderTests.cs index 24f583679b733..6a8ed59e44fc2 100644 --- a/src/EditorFeatures/CSharpTest2/Recommendations/ThisKeywordRecommenderTests.cs +++ b/src/EditorFeatures/CSharpTest2/Recommendations/ThisKeywordRecommenderTests.cs @@ -647,22 +647,7 @@ public static class Extensions public static void Extension(ref $$ object obj, int x) { } }"); } - - [Fact] - public async Task TestExtensionMethods_FirstParameter_AfterRefReadOnlyKeywords_InClass() - { - await VerifyKeywordAsync(@" -public static class Extensions -{ - public static void Extension(ref readonly $$"); - - await VerifyKeywordAsync(@" -public static class Extensions -{ - public static void Extension(ref readonly $$ object obj, int x) { } -}"); - } - + [Fact] public async Task TestExtensionMethods_SecondParameter_AfterRefKeyword_InClass() { diff --git a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ExpressionCompilerTests.cs b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ExpressionCompilerTests.cs index c29828dfef086..a4ee201f54ae2 100644 --- a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ExpressionCompilerTests.cs +++ b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ExpressionCompilerTests.cs @@ -6350,7 +6350,7 @@ void M(D lambda) public void RefReadOnlyLambdasEvaluationWillSynthesizeRequiredAttributes_ReturnTypes() { var reference = CreateStandardCompilation(@" -public delegate in int D();"); +public delegate ref readonly int D();"); CompileAndVerify(reference, symbolValidator: module => { diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InKeywordRecommender.cs index 2dc8cbf48eefd..594e4f77c44ef 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InKeywordRecommender.cs @@ -19,10 +19,14 @@ public InKeywordRecommender() protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { + var syntaxTree = context.SyntaxTree; return IsValidContextInForEachClause(context) || IsValidContextInFromClause(context, cancellationToken) || IsValidContextInJoinClause(context, cancellationToken) || + syntaxTree.IsParameterModifierContext(position, context.LeftToken, cancellationToken) || + syntaxTree.IsAnonymousMethodParameterModifierContext(position, context.LeftToken, cancellationToken) || + syntaxTree.IsPossibleLambdaParameterModifierContext(position, context.LeftToken, cancellationToken) || context.TargetToken.IsTypeParameterVarianceContext(); } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReadOnlyKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReadOnlyKeywordRecommender.cs index 6d3a434536b9a..0bea09d8d3473 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReadOnlyKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReadOnlyKeywordRecommender.cs @@ -42,9 +42,13 @@ private bool IsRefReadOnlyContext(int position, CSharpSyntaxContext context) { var previousToken = context.LeftToken.GetPreviousTokenIfTouchingWord(position); - return - previousToken.IsKind(SyntaxKind.RefKeyword) && - previousToken.Parent.IsKind(SyntaxKind.Parameter, SyntaxKind.RefType); + return previousToken.IsKind(SyntaxKind.RefKeyword) && + previousToken.Parent.IsKind(SyntaxKind.RefType) && + previousToken.Parent.Parent.IsKind( + SyntaxKind.PropertyDeclaration, + SyntaxKind.MethodDeclaration, + SyntaxKind.DelegateDeclaration, + SyntaxKind.IncompleteMember); } } } diff --git a/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs b/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs index feceb5b61dd76..8c553f876c0eb 100644 --- a/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs +++ b/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs @@ -1908,7 +1908,7 @@ private void ClassifyInsert(SyntaxNode node) case SyntaxKind.DelegateDeclaration: var delegateDeclaration = (DelegateDeclarationSyntax)node; ClassifyPossibleReadOnlyRefAttributesForType(delegateDeclaration, delegateDeclaration.ReturnType); - ClassifyPossibleReadOnlyRefAttributesForParameters(delegateDeclaration.ParameterList); + ClassifyPossibleInModifierForParameters(delegateDeclaration.ParameterList); return; case SyntaxKind.PropertyDeclaration: @@ -1920,7 +1920,7 @@ private void ClassifyInsert(SyntaxNode node) var indexerDeclaration = (IndexerDeclarationSyntax)node; ClassifyModifiedMemberInsert(indexerDeclaration.Modifiers); ClassifyPossibleReadOnlyRefAttributesForType(indexerDeclaration, indexerDeclaration.Type); - ClassifyPossibleReadOnlyRefAttributesForParameters(indexerDeclaration.ParameterList); + ClassifyPossibleInModifierForParameters(indexerDeclaration.ParameterList); return; case SyntaxKind.ConversionOperatorDeclaration: @@ -1949,7 +1949,7 @@ private void ClassifyInsert(SyntaxNode node) } ClassifyModifiedMemberInsert(method.Modifiers); - ClassifyPossibleReadOnlyRefAttributesForParameters(method.ParameterList); + ClassifyPossibleInModifierForParameters(method.ParameterList); return; case SyntaxKind.GetAccessorDeclaration: @@ -2030,29 +2030,18 @@ private void ClassifyPossibleEmbeddedAttributesForType(TypeDeclarationSyntax typ } } - private void ClassifyPossibleReadOnlyRefAttributesForParameters(BaseParameterListSyntax list) + private void ClassifyPossibleInModifierForParameters(BaseParameterListSyntax list) { foreach (var parameter in list.Parameters) { - bool foundRef = false, foundReadonly = false; - foreach (var modifier in parameter.Modifiers) { - switch (modifier.Kind()) + if (modifier.IsKind(SyntaxKind.InKeyword)) { - case SyntaxKind.RefKeyword: - foundRef = true; - break; - case SyntaxKind.ReadOnlyKeyword: - foundReadonly = true; - break; + ReportError(RudeEditKind.ReadOnlyReferences, parameter, parameter); + return; } } - - if (foundRef && foundReadonly) - { - ReportError(RudeEditKind.ReadOnlyReferences, parameter, parameter); - } } } @@ -2104,7 +2093,7 @@ private void ClassifyMethodInsert(MethodDeclarationSyntax method) } ClassifyPossibleReadOnlyRefAttributesForType(method, method.ReturnType); - ClassifyPossibleReadOnlyRefAttributesForParameters(method.ParameterList); + ClassifyPossibleInModifierForParameters(method.ParameterList); } private void ClassifyAccessorInsert(AccessorDeclarationSyntax accessor) @@ -2876,7 +2865,7 @@ public void ClassifyDeclarationBodyRudeUpdates(SyntaxNode newDeclarationOrBody) case SyntaxKind.LocalFunctionStatement: var localFunction = (LocalFunctionStatementSyntax)node; ClassifyPossibleReadOnlyRefAttributesForType(localFunction, localFunction.ReturnType); - ClassifyPossibleReadOnlyRefAttributesForParameters(localFunction.ParameterList); + ClassifyPossibleInModifierForParameters(localFunction.ParameterList); break; } } diff --git a/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTreeExtensions.cs b/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTreeExtensions.cs index 2b32b3703720b..132e8712c8c32 100644 --- a/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTreeExtensions.cs +++ b/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTreeExtensions.cs @@ -1025,7 +1025,7 @@ public static bool IsParameterModifierContext( } if (isThisKeyword && - (token.IsKind(SyntaxKind.RefKeyword) || token.IsKind(SyntaxKind.ReadOnlyKeyword)) && + token.IsKind(SyntaxKind.RefKeyword) && token.Parent.GetParent().IsDelegateOrConstructorOrLocalFunctionOrMethodParameterList()) { var parameter = token.GetAncestor(); From e1bdefe0c702948c2c6e00af3f6adc8eff2b4002 Mon Sep 17 00:00:00 2001 From: Omar Tawfik Date: Fri, 29 Sep 2017 03:30:50 -0700 Subject: [PATCH 14/16] more refactoring --- .../LocalRewriter/LocalRewriter_Call.cs | 2 +- .../Symbols/Metadata/PE/PEParameterSymbol.cs | 2 +- .../Attributes/AttributeTests_RefReadOnly.cs | 14 ++--- .../CodeGenRefReadOnlyParametersTests.cs | 50 +++++++++--------- .../Emit/Emit/InAttributeModifierTests.cs | 22 ++++---- .../IOperation/IOperationTests_IArgument.cs | 2 +- .../Semantics/AmbiguousOverrideTests.cs | 4 +- .../Test/Semantic/Semantics/NameOfTests.cs | 2 +- .../Semantics/OverloadResolutionTests.cs | 12 ++--- .../Semantics/RefExtensionMethodsTests.cs | 52 +++++++++---------- ...InterfaceOverriddenOrHiddenMembersTests.cs | 8 +-- .../Symbols/OverriddenOrHiddenMembersTests.cs | 6 +-- .../Syntax/Parsing/ParserErrorMessageTests.cs | 12 ++--- .../ExtensionMethods/ExtensionMethodTests.vb | 2 +- .../Metadata/PE/InAttributeModifierTests.vb | 6 +-- .../ExtractInterface/ExtractInterfaceTests.cs | 4 +- .../ImplementAbstractClassTests.cs | 4 +- .../ImplementInterfaceTests.cs | 4 +- .../UseLocalFunction/UseLocalFunctionTests.cs | 2 +- .../ExpressionCompilerTests.cs | 2 +- 20 files changed, 106 insertions(+), 106 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs index d3269841d0cf2..2ef9574cd00df 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs @@ -495,7 +495,7 @@ private ImmutableArray MakeArguments( } /// - /// patch refKinds for "readonly ref" to have effective RefReadOnly kind. + /// Patch refKinds for "in" arguments to have effective RefKind.In /// private static ImmutableArray GetEffectiveArgumentRefKinds(ImmutableArray argumentRefKindsOpt, ImmutableArray parameters) { diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs index 20d11f1ed8a63..4177a51927168 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs @@ -228,7 +228,7 @@ private PEParameterSymbol( } else if (moduleSymbol.Module.HasIsReadOnlyAttribute(handle)) { - refKind = RefKind.RefReadOnly; + refKind = RefKind.In; } else { diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_RefReadOnly.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_RefReadOnly.cs index 7e26ebfcd43cc..bdcffed48778b 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_RefReadOnly.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_RefReadOnly.cs @@ -44,7 +44,7 @@ class Test } [Fact] - public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Method_Parameter() + public void InIsWrittenToMetadata_NeedsToBeGenerated_Method_Parameter() { var text = @" class Test @@ -145,7 +145,7 @@ struct Test } [Fact] - public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Operator_Parameter() + public void InIsWrittenToMetadata_NeedsToBeGenerated_Operator_Parameter() { var text = @" struct Test @@ -223,7 +223,7 @@ public Test(in int x) { } } [Fact] - public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Constructor_Parameter() + public void InIsWrittenToMetadata_NeedsToBeGenerated_Constructor_Parameter() { var text = @" class Test @@ -399,7 +399,7 @@ class Test } [Fact] - public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Indexer_Parameter() + public void InIsWrittenToMetadata_NeedsToBeGenerated_Indexer_Parameter() { var text = @" class Test @@ -498,7 +498,7 @@ public class IsReadOnlyAttribute : System.Attribute { } } [Fact] - public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Delegate_Parameter() + public void InIsWrittenToMetadata_NeedsToBeGenerated_Delegate_Parameter() { var text = @" public delegate void D(in int x); @@ -597,7 +597,7 @@ ref readonly int Inner(in int x) } [Fact] - public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_LocalFunctions_Parameters() + public void InIsWrittenToMetadata_NeedsToBeGenerated_LocalFunctions_Parameters() { var text = @" public class Test @@ -725,7 +725,7 @@ public void M2(D value) { } } [Fact] - public void RefReadOnlyIsWrittenToMetadata_NeedsToBeGenerated_Lambda_Parameter() + public void InIsWrittenToMetadata_NeedsToBeGenerated_Lambda_Parameter() { var text = @" delegate void D(in int x); diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs index 7031510a8d94c..2346c7c52724e 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs @@ -13,7 +13,7 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests { [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public class CodeGenRefReadOnlyParametersTests : CompilingTestBase + public class CodeGenInParametersTests : CompilingTestBase { [Fact] public void RefReturnParamAccess() @@ -40,7 +40,7 @@ .maxstack 1 } [Fact] - public void RefReadOnlyParamPassLValue() + public void InParamPassLValue() { var text = @" struct Program @@ -108,7 +108,7 @@ .locals init (int V_0, //local } [Fact] - public void RefReadOnlyParamPassRValue() + public void InParamPassRValue() { var text = @" class Program @@ -174,7 +174,7 @@ .locals init (int V_0, [Fact] [CompilerTrait(CompilerFeature.PEVerifyCompat)] - public void RefReadOnlyParamPassRoField() + public void InParamPassRoField() { var text = @" class Program @@ -234,7 +234,7 @@ .locals init (int V_0) } [Fact] - public void RefReadOnlyParamPassRoParamReturn() + public void InParamPassRoParamReturn() { var text = @" class Program @@ -271,7 +271,7 @@ .maxstack 1 } [Fact] - public void RefReadOnlyParamBase() + public void InParamBase() { var text = @" class Program @@ -358,7 +358,7 @@ .maxstack 1 } [Fact] - public void ReadonlyParamCannotAssign() + public void InParamCannotAssign() { var text = @" class Program @@ -400,7 +400,7 @@ static void M(in int arg1, in (int Alice, int Bob) arg2) } [Fact] - public void ReadonlyParamCannotRefReturn() + public void InParamCannotRefReturn() { var text = @" class Program @@ -441,7 +441,7 @@ static ref int M2(in int arg1, in (int Alice, int Bob) arg2) } [Fact] - public void ReadonlyParamCannotAssignByref() + public void InParamCannotAssignByref() { var text = @" class Program @@ -465,7 +465,7 @@ static void M(in int arg1, in (int Alice, int Bob) arg2) } [Fact] - public void ReadonlyParamCannotTakePtr() + public void InParamCannotTakePtr() { var text = @" class Program @@ -504,7 +504,7 @@ unsafe static void M(in int arg1, in (int Alice, int Bob) arg2) } [Fact] - public void ReadonlyParamCannotReturnByOrdinaryRef() + public void InParamCannotReturnByOrdinaryRef() { var text = @" class Program @@ -537,7 +537,7 @@ static ref int M(in int arg1, in (int Alice, int Bob) arg2) } [Fact] - public void ReadonlyParamCanReturnByRefReadonly() + public void InParamCanReturnByRefReadonly() { var text = @" class Program @@ -575,7 +575,7 @@ .maxstack 1 } [Fact, WorkItem(18357, "https://github.com/dotnet/roslyn/issues/18357")] - public void ReadonlyParamCanReturnByRefReadonlyNested() + public void InParamCanReturnByRefReadonlyNested() { var text = @" class Program @@ -618,7 +618,7 @@ .maxstack 1 } [Fact, WorkItem(18357, "https://github.com/dotnet/roslyn/issues/18357")] - public void ReadonlyParamCannotReturnByRefNested() + public void InParamCannotReturnByRefNested() { var text = @" class Program @@ -656,7 +656,7 @@ ref int M1(in int arg11, in (int Alice, int Bob) arg21) } [Fact] - public void ReadonlyParamOptional() + public void InParamOptional() { var text = @" class Program @@ -688,7 +688,7 @@ .locals init (int V_0) } [Fact] - public void ReadonlyParamConv() + public void InParamConv() { var text = @" class Program @@ -722,7 +722,7 @@ .locals init (double V_0) } [Fact] - public void ReadonlyParamAsyncSpill1() + public void InParamAsyncSpill1() { var text = @" using System.Threading.Tasks; @@ -758,7 +758,7 @@ public static void M1(in int arg1, in int arg2, in int arg3) } [Fact] - public void ReadonlyParamAsyncSpill2() + public void InParamAsyncSpill2() { var text = @" using System.Threading.Tasks; @@ -795,7 +795,7 @@ public static void M1(in int arg1, in int arg2, in int arg3) [WorkItem(20764, "https://github.com/dotnet/roslyn/issues/20764")] [Fact] - public void ReadonlyParamAsyncSpillMethods() + public void InParamAsyncSpillMethods() { var text = @" using System.Threading.Tasks; @@ -863,7 +863,7 @@ public struct S1 [WorkItem(20764, "https://github.com/dotnet/roslyn/issues/20764")] [Fact] - public void ReadonlyParamAsyncSpillMethodsWriteable() + public void InParamAsyncSpillMethodsWriteable() { var text = @" using System.Threading.Tasks; @@ -932,7 +932,7 @@ public struct S1 [WorkItem(20764, "https://github.com/dotnet/roslyn/issues/20764")] [Fact] - public void ReadonlyParamAsyncSpillStructField() + public void InParamAsyncSpillStructField() { var text = @" using System.Threading.Tasks; @@ -989,7 +989,7 @@ public struct S1 } [Fact] - public void ReadonlyParamAsyncSpillClassField() + public void InParamAsyncSpillClassField() { var text = @" using System.Threading.Tasks; @@ -1046,7 +1046,7 @@ public class S1 } [Fact] - public void ReadonlyParamAsyncSpillExtension() + public void InParamAsyncSpillExtension() { var text = @" using System.Threading.Tasks; @@ -1107,7 +1107,7 @@ public struct S1 [Fact] [CompilerTrait(CompilerFeature.PEVerifyCompat)] - public void ReadonlyParamAsyncSpillReadOnlyStructThis() + public void InParamAsyncSpillReadOnlyStructThis() { var text = @" using System.Threading.Tasks; @@ -1209,7 +1209,7 @@ public void M1(in int arg2, in int arg3, in int arg4) [Fact] [CompilerTrait(CompilerFeature.PEVerifyCompat)] - public void ReadonlyParamAsyncSpillReadOnlyStructThis_NoValCapture() + public void InParamAsyncSpillReadOnlyStructThis_NoValCapture() { var text = @" using System.Threading.Tasks; diff --git a/src/Compilers/CSharp/Test/Emit/Emit/InAttributeModifierTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/InAttributeModifierTests.cs index 6532e3fc3d445..3cdb19fff5242 100644 --- a/src/Compilers/CSharp/Test/Emit/Emit/InAttributeModifierTests.cs +++ b/src/Compilers/CSharp/Test/Emit/Emit/InAttributeModifierTests.cs @@ -1024,7 +1024,7 @@ private static void Process(D func) } [Fact] - public void OtherModReqsAreNotAllowedOnRefCustomModifiersForRefReadOnlySignatures_Methods_Parameters() + public void OtherModReqsAreNotAllowedOnRefCustomModifiersForInSignatures_Methods_Parameters() { var ilSource = IsReadOnlyAttributeIL + @" .class public auto ansi beforefieldinit TestRef @@ -1206,7 +1206,7 @@ public static void Main() } [Fact] - public void OtherModReqsAreNotAllowedOnRefCustomModifiersForRefReadOnlySignatures_Indexers_Parameters() + public void OtherModReqsAreNotAllowedOnRefCustomModifiersForInSignatures_Indexers_Parameters() { var ilSource = IsReadOnlyAttributeIL + @" .class public auto ansi beforefieldinit TestRef @@ -1356,7 +1356,7 @@ public static void Main() } [Fact] - public void OtherModReqsAreNotAllowedOnRefCustomModifiersForRefReadOnlySignatures_Delegates_Parameters() + public void OtherModReqsAreNotAllowedOnRefCustomModifiersForInSignatures_Delegates_Parameters() { var ilSource = IsReadOnlyAttributeIL + @" .class public auto ansi sealed D @@ -1620,7 +1620,7 @@ public class MulticastDelegate : Delegate {} } [Fact] - public void InAttributeIsWrittenOnRefReadOnlyMembers_Methods_Parameters_Virtual() + public void InAttributeIsWrittenOnInMembers_Methods_Parameters_Virtual() { var code = @" class Test @@ -1640,7 +1640,7 @@ public virtual void Method(in int x) { } } [Fact] - public void InAttributeIsWrittenOnRefReadOnlyMembers_Methods_Parameters_Abstract() + public void InAttributeIsWrittenOnInMembers_Methods_Parameters_Abstract() { var code = @" abstract class Test @@ -1826,7 +1826,7 @@ class Test } [Fact] - public void InAttributeIsWrittenOnRefReadOnlyMembers_Indexers_Parameters_Virtual() + public void InAttributeIsWrittenOnInMembers_Indexers_Parameters_Virtual() { var code = @" class Test @@ -1846,7 +1846,7 @@ class Test } [Fact] - public void InAttributeIsWrittenOnRefReadOnlyMembers_Indexers_Parameters_Abstract() + public void InAttributeIsWrittenOnInMembers_Indexers_Parameters_Abstract() { var code = @" abstract class Test @@ -1929,7 +1929,7 @@ class Test } [Fact] - public void InAttributeIsWrittenOnRefReadOnlyMembers_Delegates_Parameters() + public void InAttributeIsWrittenOnInMembers_Delegates_Parameters() { var code = "public delegate void D(in int p);"; @@ -1975,7 +1975,7 @@ public void InAttributeIsWrittenOnRefReadOnlyMembers_Delegates_ReturnTypes() } [Fact] - public void InAttributeIsNotWrittenOnRefReadOnlyMembers_Methods_Parameters_NoModifiers() + public void InAttributeIsNotWrittenOnInMembers_Methods_Parameters_NoModifiers() { var code = @" class Test @@ -1995,7 +1995,7 @@ public void Method(in int x) { } } [Fact] - public void InAttributeIsNotWrittenOnRefReadOnlyMembers_Methods_Parameters_Static() + public void InAttributeIsNotWrittenOnInMembers_Methods_Parameters_Static() { var code = @" class Test @@ -2015,7 +2015,7 @@ public static void Method(in int x) { } } [Fact] - public void InAttributeIsNotWrittenOnRefReadOnlyMembers_Indexers_Parameters_NoModifiers() + public void InAttributeIsNotWrittenOnInMembers_Indexers_Parameters_NoModifiers() { var code = @" class Test diff --git a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IArgument.cs b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IArgument.cs index 0b9e6818f22c8..101330a68fae2 100644 --- a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IArgument.cs +++ b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IArgument.cs @@ -2300,7 +2300,7 @@ static void M2(ref int i) { } } [Fact] - public void DirectlyBindRefReadonlyArgument_InvocationExpression() + public void DirectlyBindInArgument_InvocationExpression() { string source = @" class P diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs index cb9437b583938..100869373809e 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/AmbiguousOverrideTests.cs @@ -1324,7 +1324,7 @@ public static void Main(string[] args) [Fact] [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public void OverloadsWithDifferentParameterModifiers_Ref_RefReadOnly() + public void OverloadsWithDifferentParameterModifiers_Ref_In() { var text = @" abstract class TestClass @@ -1341,7 +1341,7 @@ public void Method(in int x) { } [Fact] [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public void OverloadsWithDifferentParameterModifiers_Out_RefReadOnly() + public void OverloadsWithDifferentParameterModifiers_Out_In() { var text = @" abstract class TestClass diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs index 867cf5c42d541..7dc665458f55e 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NameOfTests.cs @@ -1328,7 +1328,7 @@ public static void Main(string[] args) } [Fact] - public void PassingNameOfToRefReadOnlyShouldCopy() + public void PassingNameOfToInShouldCopy() { CompileAndVerify(@" class Program diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs index 9e0f985a44ddc..f79dacf05de7e 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs @@ -9315,7 +9315,7 @@ public class Program } [Fact] - public void PassingArgumentsToRefReadOnlyParameters_RefKind_None() + public void PassingArgumentsToInParameters_RefKind_None() { var code = @" public static class Program @@ -9335,7 +9335,7 @@ public static void Main() } [Fact] - public void PassingArgumentsToRefReadOnlyParameters_RefKind_Ref() + public void PassingArgumentsToInParameters_RefKind_Ref() { var code = @" public static class Program @@ -9359,7 +9359,7 @@ public static void Main() [WorkItem(20799, "https://github.com/dotnet/roslyn/issues/20799")] [Fact] - public void PassingArgumentsToRefReadOnlyParameters_RefKind_None_WrongType() + public void PassingArgumentsToInParameters_RefKind_None_WrongType() { var code = @" public static class Program @@ -9408,7 +9408,7 @@ public static void Main() } [Fact] - public void PassingArgumentsToRefReadOnlyParameters_RefKind_RefReadOnly() + public void PassingArgumentsToInParameters_RefKind_RefReadOnly() { var code = @" public static class Program @@ -9455,7 +9455,7 @@ public static void Main() } [Fact] - public void PassingArgumentsToRefReadOnlyParameters_RefKind_In() + public void PassingArgumentsToInParameters_RefKind_In() { var code = @" public static class Program @@ -9478,7 +9478,7 @@ public static void Main() } [Fact] - public void PassingArgumentsToRefReadOnlyParameters_RefKind_Out() + public void PassingArgumentsToInParameters_RefKind_Out() { var code = @" public static class Program diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefExtensionMethodsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefExtensionMethodsTests.cs index 36dc918a4b12c..115d8462b54cf 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefExtensionMethodsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefExtensionMethodsTests.cs @@ -63,7 +63,7 @@ public static void Main() } [Fact] - public void ExtensionMethods_RValues_RefReadOnly_Allowed() + public void ExtensionMethods_RValues_In_Allowed() { var code = @" public static class Extensions @@ -86,7 +86,7 @@ public static void Main() } [Fact] - public void ExtensionMethods_LValues_RefReadOnly_Allowed() + public void ExtensionMethods_LValues_In_Allowed() { var code = @" public static class Extensions @@ -133,7 +133,7 @@ public static void Call(ref this TestType obj) } [Fact] - public void ExtensionMethods_NullConditionalOperator_RefReadOnly_NotAllowed() + public void ExtensionMethods_NullConditionalOperator_In_NotAllowed() { var code = @" public struct TestType @@ -701,7 +701,7 @@ public static void Main() } [Fact] - public void RefReadOnlyExtensionMethodsReceiverTypes_ValueTypes_Allowed() + public void InExtensionMethodsReceiverTypes_ValueTypes_Allowed() { var reference = CreateCompilationWithMscorlibAndSystemCore(@" public static class Extensions @@ -739,7 +739,7 @@ public static void Main() } [Fact] - public void RefReadOnlyExtensionMethodsReceiverTypes_ReferenceTypes_NotAllowed() + public void InExtensionMethodsReceiverTypes_ReferenceTypes_NotAllowed() { var code = @" public static class Extensions @@ -783,7 +783,7 @@ public static void Main() } [Fact] - public void RefReadOnlyExtensionMethodsReceiverTypes_InterfaceTypes_NotAllowed() + public void InExtensionMethodsReceiverTypes_InterfaceTypes_NotAllowed() { var code = @" public static class Extensions @@ -827,7 +827,7 @@ public static void Main() } [Fact] - public void RefReadOnlyExtensionMethodsReceiverTypes_UnconstrainedGenericTypes_NotAllowed() + public void InExtensionMethodsReceiverTypes_UnconstrainedGenericTypes_NotAllowed() { var code = @" public static class Extensions @@ -871,7 +871,7 @@ public static void Main() } [Fact] - public void RefReadOnlyExtensionMethodsReceiverTypes_StructConstrainedGenericTypes_NotAllowed() + public void InExtensionMethodsReceiverTypes_StructConstrainedGenericTypes_NotAllowed() { var code = @" public static class Extensions @@ -915,7 +915,7 @@ public static void Main() } [Fact] - public void RefReadOnlyExtensionMethodsReceiverTypes_ClassConstrainedGenericTypes_NotAllowed() + public void InExtensionMethodsReceiverTypes_ClassConstrainedGenericTypes_NotAllowed() { var code = @" public static class Extensions @@ -959,7 +959,7 @@ public static void Main() } [Fact] - public void RefReadOnlyExtensionMethodsReceiverTypes_InterfaceConstrainedGenericTypes_NotAllowed() + public void InExtensionMethodsReceiverTypes_InterfaceConstrainedGenericTypes_NotAllowed() { var code = @" public static class Extensions @@ -1003,7 +1003,7 @@ public static void Main() } [Fact] - public void RefReadOnlyExtensionMethodsReceiverTypes_ValueTypes_Allowed_IL() + public void InExtensionMethodsReceiverTypes_ValueTypes_Allowed_IL() { var reference = CompileIL(ExtraRefReadOnlyIL + @" .class public abstract auto ansi sealed beforefieldinit Extensions extends [mscorlib]System.Object @@ -1040,7 +1040,7 @@ public static void Main() } [Fact] - public void RefReadOnlyExtensionMethodsReceiverTypes_ReferenceTypes_NotAllowed_IL() + public void InExtensionMethodsReceiverTypes_ReferenceTypes_NotAllowed_IL() { var reference = CompileIL(ExtraRefReadOnlyIL + @" .class public abstract auto ansi sealed beforefieldinit Extensions extends [mscorlib]System.Object @@ -1079,7 +1079,7 @@ public static void Main() } [Fact] - public void RefReadOnlyExtensionMethodsReceiverTypes_InterfaceTypes_NotAllowed_IL() + public void InExtensionMethodsReceiverTypes_InterfaceTypes_NotAllowed_IL() { var reference = CompileIL(ExtraRefReadOnlyIL + @" .class public abstract auto ansi sealed beforefieldinit Extensions extends [mscorlib]System.Object @@ -1118,7 +1118,7 @@ public static void Main() } [Fact] - public void RefReadOnlyExtensionMethodsReceiverTypes_UnconstrainedGenericTypes_NotAllowed_IL() + public void InExtensionMethodsReceiverTypes_UnconstrainedGenericTypes_NotAllowed_IL() { var reference = CompileIL(ExtraRefReadOnlyIL + @" .class public abstract auto ansi sealed beforefieldinit Extensions extends [mscorlib]System.Object @@ -1157,7 +1157,7 @@ public static void Main() } [Fact] - public void RefReadOnlyExtensionMethodsReceiverTypes_StructConstrainedGenericTypes_NotAllowed_IL() + public void InExtensionMethodsReceiverTypes_StructConstrainedGenericTypes_NotAllowed_IL() { var reference = CompileIL(ExtraRefReadOnlyIL + @" .class public abstract auto ansi sealed beforefieldinit Extensions extends [mscorlib]System.Object @@ -1196,7 +1196,7 @@ public static void Main() } [Fact] - public void RefReadOnlyExtensionMethodsReceiverTypes_ClassConstrainedGenericTypes_NotAllowed_IL() + public void InExtensionMethodsReceiverTypes_ClassConstrainedGenericTypes_NotAllowed_IL() { var reference = CompileIL(ExtraRefReadOnlyIL + @" .class public abstract auto ansi sealed beforefieldinit Extensions extends [mscorlib]System.Object @@ -1235,7 +1235,7 @@ public static void Main() } [Fact] - public void RefReadOnlyExtensionMethodsReceiverTypes_InterfaceConstrainedGenericTypes_NotAllowed_IL() + public void InExtensionMethodsReceiverTypes_InterfaceConstrainedGenericTypes_NotAllowed_IL() { var reference = CompileIL(ExtraRefReadOnlyIL + @" .class public abstract auto ansi sealed beforefieldinit Extensions extends [mscorlib]System.Object @@ -1274,7 +1274,7 @@ public static void Main() } [Fact] - public void RefReadOnlyErrorsArePropagatedThroughExtensionMethods() + public void InErrorsArePropagatedThroughExtensionMethods() { var code = @" public static class Extensions @@ -1358,7 +1358,7 @@ .locals init (int V_0) } [Fact] - public void RefReadOnlyExtensionMethods_CodeGen() + public void InExtensionMethods_CodeGen() { var code = @" public static class Extensions @@ -1433,7 +1433,7 @@ public static void Main() } [Fact] - public void Conversions_Numeric_RefReadOnlyExtensionMethods_NotAllowed() + public void Conversions_Numeric_InExtensionMethods_NotAllowed() { var code = @" public static class Extensions @@ -1495,7 +1495,7 @@ public static void Main() } [Fact] - public void Conversion_Tuples_RefReadOnlyExtensionMethods_NotAllowed() + public void Conversion_Tuples_InExtensionMethods_NotAllowed() { var code = @" public static class Extensions @@ -1562,7 +1562,7 @@ public static void Main() } [Fact] - public void Conversions_Nullables_RefReadOnlyExtensionMethods_NotAllowed() + public void Conversions_Nullables_InExtensionMethods_NotAllowed() { var code = @" public static class Extensions @@ -1627,7 +1627,7 @@ public void TryMethod() } [Fact] - public void Conversions_ImplicitOperators_RefReadOnlyExtensionMethods_NotAllowed() + public void Conversions_ImplicitOperators_InExtensionMethods_NotAllowed() { var code = @" public static class Extensions @@ -1697,7 +1697,7 @@ public static void Main() } [Fact] - public void ColorColorCasesShouldBeResolvedCorrectly_RefReadOnlyExtensionMethods() + public void ColorColorCasesShouldBeResolvedCorrectly_InExtensionMethods() { var code = @" public struct Color @@ -1796,7 +1796,7 @@ public static void Main() } [Fact] - public void RecursiveCalling_RefReadOnlyExtensionMethods() + public void RecursiveCalling_InExtensionMethods() { var code = @" public struct S1 @@ -1947,7 +1947,7 @@ public static void Method(ref this int p) { } } [Fact] - public void ParameterSymbolsRetrievedThroughSemanticModel_RefReadOnlyExtensionMethods() + public void ParameterSymbolsRetrievedThroughSemanticModel_InExtensionMethods() { var code = @" public static class Ext diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/InterfaceOverriddenOrHiddenMembersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/InterfaceOverriddenOrHiddenMembersTests.cs index 074cc1b0f7e03..4c8ae86d574be 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/InterfaceOverriddenOrHiddenMembersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/InterfaceOverriddenOrHiddenMembersTests.cs @@ -822,7 +822,7 @@ public interface Test { } [Fact] [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public void HidingMethodWithRefReadOnlyParameter() + public void HidingMethodWithInParameter() { var code = @" interface A @@ -1025,7 +1025,7 @@ interface B : A [Fact] [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public void HidingMethodWithRefReadOnlyParameterAndNewKeyword() + public void HidingMethodWithInParameterAndNewKeyword() { var code = @" interface A @@ -1103,7 +1103,7 @@ interface B : A [Fact] [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public void ImplementingMethodWithRefReadOnlyParameter() + public void ImplementingMethodWithInParameter() { var code = @" interface A @@ -1199,7 +1199,7 @@ class DerivedClass : BaseInterface [Fact] [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public void MethodImplementationsShouldPreserveReadOnlyRefnessInParameters() + public void MethodImplementationsShouldPreserveRefKindInParameters() { var text = @" interface BaseInterface diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/OverriddenOrHiddenMembersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/OverriddenOrHiddenMembersTests.cs index 361cb7cece4c7..c5a411f60bbe2 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/OverriddenOrHiddenMembersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/OverriddenOrHiddenMembersTests.cs @@ -3987,7 +3987,7 @@ public class Required : ValidatorBase [Fact] [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public void HidingMethodWithRefReadOnlyParameter() + public void HidingMethodWithInParameter() { var code = @" class A @@ -4196,7 +4196,7 @@ class B : A [Fact] [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public void HidingMethodWithRefReadOnlyParameterAndNewKeyword() + public void HidingMethodWithInParameterAndNewKeyword() { var code = @" class A @@ -4276,7 +4276,7 @@ class B : A [Fact] [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public void OverridingMethodWithRefReadOnlyParameter() + public void OverridingMethodWithInParameter() { var code = @" class A diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs index 83fad8d168b18..f53ff1b0ebb2b 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs @@ -3149,7 +3149,7 @@ public static void Goo2(this ref X x) {} [Fact] [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public void RefReadOnlyParametersWouldErrorOutInEarlierCSharpVersions() + public void InParametersWouldErrorOutInEarlierCSharpVersions() { var code = @" public class Test @@ -3451,7 +3451,7 @@ public static void Test5(in in int[] i) {} [Fact] [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public void BadRefReadOnlyWithRefParameterModifiers() + public void BadInWithRefParameterModifiers() { var test = @" public class TestType @@ -3493,7 +3493,7 @@ public static void Method6(ref in int i) { } [Fact] [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public void BadRefReadOnlyWithThisParameterModifiers() + public void BadInWithThisParameterModifiers() { var test = @" public static class TestType @@ -3526,7 +3526,7 @@ public static void Method6(this in int i) { } [Fact] [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public void BadRefReadOnlyWithParamsParameterModifiers() + public void BadInWithParamsParameterModifiers() { var test = @" public class TestType @@ -3610,7 +3610,7 @@ public static void Method6(out in int i) { } [Fact] [CompilerTrait(CompilerFeature.ReadOnlyReferences)] - public void RefReadonlyParametersAreParsedCorrectly() + public void InParametersAreParsedCorrectly() { var test = @" public class Test @@ -5557,7 +5557,7 @@ class TestClass { }"; } [Fact] - public void RefExtensionMethodsNotSupportedBefore7_2_RefReadOnlySyntax() + public void RefExtensionMethodsNotSupportedBefore7_2_InSyntax() { var code = @" public static class Extensions diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/ExtensionMethods/ExtensionMethodTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/ExtensionMethods/ExtensionMethodTests.vb index 52744fe55dfaf..e6787361c238f 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/ExtensionMethods/ExtensionMethodTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/ExtensionMethods/ExtensionMethodTests.vb @@ -2516,7 +2516,7 @@ End Module End Sub - Public Sub ConsumeRefReadOnlyExtensionMethods() + Public Sub ConsumeInExtensionMethods() Dim options = New CSharpParseOptions(CodeAnalysis.CSharp.LanguageVersion.Latest) Dim csharp = CreateCSharpCompilation(" public static class Extensions diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/InAttributeModifierTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/InAttributeModifierTests.vb index 9082c2944709d..b9413b2610854 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/InAttributeModifierTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/InAttributeModifierTests.vb @@ -569,7 +569,7 @@ BC30643: Property 'TestRef.Item(p As )' is of an unsupported type. End Sub - Public Sub UsingLambdasOfRefReadOnlyDelegatesIsNotSupported_Invoke_Parameters() + Public Sub UsingLambdasOfInDelegatesIsNotSupported_Invoke_Parameters() Dim reference = CreateCSharpCompilation(" public delegate void D(in int p); ", parseOptions:=New CSharpParseOptions(CSharp.LanguageVersion.Latest)).EmitToImageReference() @@ -596,7 +596,7 @@ BC30657: 'D' has a return type that is not supported or parameter types that are End Sub - Public Sub UsingLambdasOfRefReadOnlyDelegatesIsNotSupported_BeginInvoke_Parameters() + Public Sub UsingLambdasOfInDelegatesIsNotSupported_BeginInvoke_Parameters() Dim reference = CreateCSharpCompilation(" public delegate void D(in int p); ", parseOptions:=New CSharpParseOptions(CSharp.LanguageVersion.Latest)).EmitToImageReference() @@ -623,7 +623,7 @@ BC30657: 'BeginInvoke' has a return type that is not supported or parameter type End Sub - Public Sub UsingLambdasOfRefReadOnlyDelegatesIsNotSupported_EndInvoke_Parameters() + Public Sub UsingLambdasOfInDelegatesIsNotSupported_EndInvoke_Parameters() Dim reference = CreateCSharpCompilation(" public delegate void D(in int p); ", parseOptions:=New CSharpParseOptions(CSharp.LanguageVersion.Latest)).EmitToImageReference() diff --git a/src/EditorFeatures/CSharpTest/ExtractInterface/ExtractInterfaceTests.cs b/src/EditorFeatures/CSharpTest/ExtractInterface/ExtractInterfaceTests.cs index 0b3f39b12beda..524caf9ffdbea 100644 --- a/src/EditorFeatures/CSharpTest/ExtractInterface/ExtractInterfaceTests.cs +++ b/src/EditorFeatures/CSharpTest/ExtractInterface/ExtractInterfaceTests.cs @@ -1094,7 +1094,7 @@ CommandState nextHandler() } [WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)] - public async Task TestRefReadOnlyWithMethod_Parameters() + public async Task TestInWithMethod_Parameters() { var markup = @" using System; @@ -1147,7 +1147,7 @@ await TestExtractInterfaceCommandCSharpAsync(markup, expectedSuccess: true, expe } [WpfFact, Trait(Traits.Feature, Traits.Features.ExtractInterface)] - public async Task TestRefReadOnlyWithIndexer_Parameters() + public async Task TestInWithIndexer_Parameters() { var markup = @" using System; diff --git a/src/EditorFeatures/CSharpTest/ImplementAbstractClass/ImplementAbstractClassTests.cs b/src/EditorFeatures/CSharpTest/ImplementAbstractClass/ImplementAbstractClassTests.cs index 75b3fdd26bc9c..dfda238a0aac1 100644 --- a/src/EditorFeatures/CSharpTest/ImplementAbstractClass/ImplementAbstractClassTests.cs +++ b/src/EditorFeatures/CSharpTest/ImplementAbstractClass/ImplementAbstractClassTests.cs @@ -1574,7 +1574,7 @@ class C : AbstractClass } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementAbstractClass)] - public async Task TestRefReadOnlyWithMethod_Parameters() + public async Task TestInWithMethod_Parameters() { await TestInRegularAndScriptAsync( @"abstract class TestParent @@ -1643,7 +1643,7 @@ public class Test : TestParent } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementAbstractClass)] - public async Task TestRefReadOnlyWithIndexer_Parameters() + public async Task TestInWithIndexer_Parameters() { await TestInRegularAndScriptAsync( @"abstract class TestParent diff --git a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs index f0efb87d577a2..c8323436ed4c4 100644 --- a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs +++ b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs @@ -6834,7 +6834,7 @@ public void Method1(CancellationToken cancellationToken = default) } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)] - public async Task TestRefReadOnlyWithMethod_Parameters() + public async Task TestInWithMethod_Parameters() { await TestInRegularAndScriptAsync( @"interface ITest @@ -6903,7 +6903,7 @@ public class Test : ITest } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)] - public async Task TestRefReadOnlyWithIndexer_Parameters() + public async Task TestInWithIndexer_Parameters() { await TestInRegularAndScriptAsync( @"interface ITest diff --git a/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs b/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs index 08324d85245f6..a128d46f56b9b 100644 --- a/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs +++ b/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs @@ -1145,7 +1145,7 @@ int fibonacci(int v) } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseLocalFunction)] - public async Task TestRefReadOnlyWithParameters() + public async Task TestInWithParameters() { await TestInRegularAndScriptAsync( @" diff --git a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ExpressionCompilerTests.cs b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ExpressionCompilerTests.cs index a4ee201f54ae2..178cfebf3cd7f 100644 --- a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ExpressionCompilerTests.cs +++ b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/ExpressionCompilerTests.cs @@ -6311,7 +6311,7 @@ .locals init (int V_0) //a } [Fact] - public void RefReadOnlyLambdasEvaluationWillSynthesizeRequiredAttributes_Parameters() + public void InLambdasEvaluationWillSynthesizeRequiredAttributes_Parameters() { var reference = CreateStandardCompilation(@" public delegate void D(in int p);"); From 48f180dae809121d3fcedeb551a5385e6bab83b9 Mon Sep 17 00:00:00 2001 From: Omar Tawfik Date: Fri, 29 Sep 2017 05:05:25 -0700 Subject: [PATCH 15/16] clean up --- .../CSharp/Portable/Parser/LanguageParser.cs | 6 +-- ...rsTests.cs => CodeGenInParametersTests.cs} | 0 .../InKeywordRecommenderTests.cs | 9 ++++ .../ThisKeywordRecommenderTests.cs | 49 ++++++++++++++----- .../ContextQuery/SyntaxTreeExtensions.cs | 2 +- 5 files changed, 47 insertions(+), 19 deletions(-) rename src/Compilers/CSharp/Test/Emit/CodeGen/{CodeGenRefReadOnlyParametersTests.cs => CodeGenInParametersTests.cs} (100%) diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index 842fe9063497f..d088ccec5e869 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -5895,11 +5895,6 @@ private ScanTypeFlags ScanNonArrayType(ParseTypeMode mode, out SyntaxToken lastT this.EatToken(); } } - else if (this.CurrentToken.Kind == SyntaxKind.InKeyword) - { - // Start of a lambda parameter - this.EatToken(); - } if (this.CurrentToken.Kind == SyntaxKind.IdentifierToken) { @@ -9815,6 +9810,7 @@ private bool ScanExplicitlyTypedLambda(Precedence precedence) } break; case SyntaxKind.OutKeyword: + case SyntaxKind.InKeyword: case SyntaxKind.ParamsKeyword: this.EatToken(); foundParameterModifier = true; diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenInParametersTests.cs similarity index 100% rename from src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefReadOnlyParametersTests.cs rename to src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenInParametersTests.cs diff --git a/src/EditorFeatures/CSharpTest2/Recommendations/InKeywordRecommenderTests.cs b/src/EditorFeatures/CSharpTest2/Recommendations/InKeywordRecommenderTests.cs index f3aea0bd8ea2d..442a5f2b9b2b0 100644 --- a/src/EditorFeatures/CSharpTest2/Recommendations/InKeywordRecommenderTests.cs +++ b/src/EditorFeatures/CSharpTest2/Recommendations/InKeywordRecommenderTests.cs @@ -422,5 +422,14 @@ class Program public $$ int Test { get; set; } }"); } + + [Test.Utilities.CompilerTrait(Test.Utilities.CompilerFeature.ReadOnlyReferences)] + [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)] + public async Task TestNotAfterThis() + { + await VerifyAbsenceAsync( +@"static class C { + static void Goo(this $$"); + } } } diff --git a/src/EditorFeatures/CSharpTest2/Recommendations/ThisKeywordRecommenderTests.cs b/src/EditorFeatures/CSharpTest2/Recommendations/ThisKeywordRecommenderTests.cs index 6a8ed59e44fc2..8dcd0057b0196 100644 --- a/src/EditorFeatures/CSharpTest2/Recommendations/ThisKeywordRecommenderTests.cs +++ b/src/EditorFeatures/CSharpTest2/Recommendations/ThisKeywordRecommenderTests.cs @@ -120,6 +120,14 @@ await VerifyAbsenceAsync( void Goo(ref $$"); } + [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)] + public async Task TestNotAfterIn() + { + await VerifyAbsenceAsync( +@"class C { + void Goo(in $$"); + } + [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)] public async Task TestNotAfterThis_InBogusMethod() { @@ -647,7 +655,22 @@ public static class Extensions public static void Extension(ref $$ object obj, int x) { } }"); } - + + [Fact] + public async Task TestExtensionMethods_FirstParameter_AfterInKeyword_InClass() + { + await VerifyKeywordAsync(@" +public static class Extensions +{ + public static void Extension(in $$"); + + await VerifyKeywordAsync(@" +public static class Extensions +{ + public static void Extension(in $$ object obj, int x) { } +}"); + } + [Fact] public async Task TestExtensionMethods_SecondParameter_AfterRefKeyword_InClass() { @@ -664,17 +687,17 @@ public static void Extension(int x, ref $$ object obj) { } } [Fact] - public async Task TestExtensionMethods_SecondParameter_AfterRefReadonlyKeywords_InClass() + public async Task TestExtensionMethods_SecondParameter_AfterInKeywords_InClass() { await VerifyAbsenceAsync(@" public static class Extensions { - public static void Extension(int x, ref readonly $$"); + public static void Extension(int x, in $$"); await VerifyAbsenceAsync(@" public static class Extensions { - public static void Extension(int x, ref readonly $$ object obj) { } + public static void Extension(int x, in $$ object obj) { } }"); } @@ -687,11 +710,11 @@ public async Task TestExtensionMethods_FirstParameter_AfterRefKeyword_OutsideCla } [Fact] - public async Task TestExtensionMethods_FirstParameter_AfterRefReadOnlyKeywords_OutsideClass() + public async Task TestExtensionMethods_FirstParameter_AfterInKeywords_OutsideClass() { - await VerifyAbsenceAsync("public static void Extension(ref readonly $$"); + await VerifyAbsenceAsync("public static void Extension(in $$"); - await VerifyAbsenceAsync("public static void Extension(ref readonly $$ object obj, int x) { }"); + await VerifyAbsenceAsync("public static void Extension(in $$ object obj, int x) { }"); } [Fact] @@ -710,17 +733,17 @@ public static void Extension(ref $$ object obj, int x) { } } [Fact] - public async Task TestExtensionMethods_FirstParameter_AfterRefReadOnlyKeywords_NonStaticClass() + public async Task TestExtensionMethods_FirstParameter_AfterInKeywords_NonStaticClass() { await VerifyAbsenceAsync(@" public class Extensions { - public static void Extension(ref readonly $$"); + public static void Extension(in $$"); await VerifyAbsenceAsync(@" public class Extensions { - public static void Extension(ref readonly $$ object obj, int x) { } + public static void Extension(in $$ object obj, int x) { } }"); } @@ -740,17 +763,17 @@ public void Extension(ref $$ object obj, int x) { } } [Fact] - public async Task TestExtensionMethods_FirstParameter_AfterRefReadOnlyKeywords_NonStaticMethod() + public async Task TestExtensionMethods_FirstParameter_AfterInKeywords_NonStaticMethod() { await VerifyAbsenceAsync(@" public static class Extensions { - public void Extension(ref readonly $$"); + public void Extension(in $$"); await VerifyAbsenceAsync(@" public static class Extensions { - public void Extension(ref readonly $$ object obj, int x) { } + public void Extension(in $$ object obj, int x) { } }"); } } diff --git a/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTreeExtensions.cs b/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTreeExtensions.cs index 132e8712c8c32..0dc4d6c222725 100644 --- a/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTreeExtensions.cs +++ b/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTreeExtensions.cs @@ -1025,7 +1025,7 @@ public static bool IsParameterModifierContext( } if (isThisKeyword && - token.IsKind(SyntaxKind.RefKeyword) && + (token.IsKind(SyntaxKind.RefKeyword) || token.IsKind(SyntaxKind.InKeyword)) && token.Parent.GetParent().IsDelegateOrConstructorOrLocalFunctionOrMethodParameterList()) { var parameter = token.GetAncestor(); From 009f92e412c718f0cf6e6f9e04d59602359ca0f7 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 29 Sep 2017 10:44:55 -0700 Subject: [PATCH 16/16] Report binding error for typed LINQ query on a type expression (#22412) --- .../Portable/Binder/Binder_Conversions.cs | 14 ++++-- .../Test/Semantic/Semantics/QueryTests.cs | 46 +++++++++++++++++++ 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs index 24d1df9c9f6ff..4baf29ff15f5c 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs @@ -584,10 +584,18 @@ private bool MemberGroupFinalValidationAccessibilityChecks(BoundExpression recei if (invokedAsExtensionMethod) { - if (receiverOpt?.Kind == BoundKind.QueryClause && IsMemberAccessedThroughType(receiverOpt)) + if (IsMemberAccessedThroughType(receiverOpt)) { - // Could not find an implementation of the query pattern for source type '{0}'. '{1}' not found. - diagnostics.Add(ErrorCode.ERR_QueryNoProvider, node.Location, receiverOpt.Type, memberSymbol.Name); + if (receiverOpt.Kind == BoundKind.QueryClause) + { + // Could not find an implementation of the query pattern for source type '{0}'. '{1}' not found. + diagnostics.Add(ErrorCode.ERR_QueryNoProvider, node.Location, receiverOpt.Type, memberSymbol.Name); + } + else + { + // An object reference is required for the non-static field, method, or property '{0}' + diagnostics.Add(ErrorCode.ERR_ObjectRequired, node.Location, memberSymbol); + } return true; } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/QueryTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/QueryTests.cs index 7ba5950f56a44..0feba1a496fcc 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/QueryTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/QueryTests.cs @@ -4078,5 +4078,51 @@ public static void Main(string[] args) VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } + + [Fact, WorkItem(21484, "https://github.com/dotnet/roslyn/issues/21484")] + public void QueryOnTypeExpression() + { + var code = @" +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +class Program +{ + static void M() where T : IEnumerable + { + var query1 = from object a in IEnumerable select 1; + var query2 = from b in IEnumerable select 2; + + var query3 = from int c in IEnumerable select 3; + var query4 = from d in IEnumerable select 4; + + var query5 = from object d in T select 5; + var query6 = from d in T select 6; + } +} +"; + var comp = CreateCompilationWithMscorlibAndSystemCore(code); + comp.VerifyDiagnostics( + // (10,22): error CS0120: An object reference is required for the non-static field, method, or property 'Enumerable.Cast(IEnumerable)' + // var query1 = from object a in IEnumerable select 1; + Diagnostic(ErrorCode.ERR_ObjectRequired, "from object a in IEnumerable").WithArguments("System.Linq.Enumerable.Cast(System.Collections.IEnumerable)").WithLocation(10, 22), + // (11,32): error CS1934: Could not find an implementation of the query pattern for source type 'IEnumerable'. 'Select' not found. Consider explicitly specifying the type of the range variable 'b'. + // var query2 = from b in IEnumerable select 2; + Diagnostic(ErrorCode.ERR_QueryNoProviderCastable, "IEnumerable").WithArguments("System.Collections.IEnumerable", "Select", "b").WithLocation(11, 32), + // (13,22): error CS0120: An object reference is required for the non-static field, method, or property 'Enumerable.Cast(IEnumerable)' + // var query3 = from int c in IEnumerable select 3; + Diagnostic(ErrorCode.ERR_ObjectRequired, "from int c in IEnumerable").WithArguments("System.Linq.Enumerable.Cast(System.Collections.IEnumerable)").WithLocation(13, 22), + // (14,49): error CS1936: Could not find an implementation of the query pattern for source type 'IEnumerable'. 'Select' not found. + // var query4 = from d in IEnumerable select 4; + Diagnostic(ErrorCode.ERR_QueryNoProvider, "select 4").WithArguments("System.Collections.Generic.IEnumerable", "Select").WithLocation(14, 49), + // (16,22): error CS0120: An object reference is required for the non-static field, method, or property 'Enumerable.Cast(IEnumerable)' + // var query5 = from object d in T select 5; + Diagnostic(ErrorCode.ERR_ObjectRequired, "from object d in T").WithArguments("System.Linq.Enumerable.Cast(System.Collections.IEnumerable)").WithLocation(16, 22), + // (17,32): error CS1936: Could not find an implementation of the query pattern for source type 'T'. 'Select' not found. + // var query6 = from d in T select 6; + Diagnostic(ErrorCode.ERR_QueryNoProvider, "T").WithArguments("T", "Select").WithLocation(17, 32) + ); + } } }