' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Roslyn.Test.Utilities Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests Public Class CodeGenRefReturnTests Inherits BasicTestBase Public Sub LocalType() Dim comp1 = CreateCSharpCompilation( "public class A { #pragma warning disable 0649 private static T _f; public static ref T F() { return ref _f; } } public class B { }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o = A(Of B).F() End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.VerifyEmitDiagnostics() Dim tree = comp2.SyntaxTrees(0) Dim model = comp2.GetSemanticModel(tree) Dim syntax = tree.GetRoot().DescendantNodes().OfType(Of Syntax.VariableDeclaratorSyntax).Single().Names(0) Dim symbol = DirectCast(model.GetDeclaredSymbol(syntax), LocalSymbol) Assert.Equal("o As B", symbol.ToTestDisplayString()) Assert.False(symbol.IsByRef) End Sub Public Sub ArrayAccess() Dim comp1 = CreateCSharpCompilation( "public class C { public static ref T F(T[] t, int i) { return ref t[i]; } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim a = {1, 2, 3} C.F(a, 2) *= 2 For Each o in a System.Console.Write(""{0} "", o) Next End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) Dim verifier = CompileAndVerify(comp2, expectedOutput:="1 2 6") verifier.VerifyIL("M.Main", .__StaticArrayInitTypeSize=12 .E429CCA3F703A39CC5954A6572FEC9086135B34E" IL_000d: call "Sub System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)" IL_0012: stloc.0 IL_0013: ldloc.0 IL_0014: ldc.i4.2 IL_0015: call "ByRef Function C.F(Of Integer)(Integer(), Integer) As Integer" IL_001a: dup IL_001b: stloc.1 IL_001c: ldloc.1 IL_001d: ldind.i4 IL_001e: ldc.i4.2 IL_001f: mul.ovf IL_0020: stind.i4 IL_0021: ldloc.0 IL_0022: stloc.2 IL_0023: ldc.i4.0 IL_0024: stloc.3 IL_0025: br.s IL_0043 IL_0027: ldloc.2 IL_0028: ldloc.3 IL_0029: ldelem.i4 IL_002a: stloc.s V_4 IL_002c: ldstr "{0} " IL_0031: ldloc.s V_4 IL_0033: box "Integer" IL_0038: call "Sub System.Console.Write(String, Object)" IL_003d: nop IL_003e: nop IL_003f: ldloc.3 IL_0040: ldc.i4.1 IL_0041: add.ovf IL_0042: stloc.3 IL_0043: ldloc.3 IL_0044: ldloc.2 IL_0045: ldlen IL_0046: conv.i4 IL_0047: clt IL_0049: stloc.s V_5 IL_004b: ldloc.s V_5 IL_004d: brtrue.s IL_0027 IL_004f: ret } ]]>) verifier.VerifyDiagnostics() End Sub Public Sub [Delegate]() Dim comp1 = CreateCSharpCompilation( "public delegate ref T D(); public class C { public T F; public ref T G() { return ref F; } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o = New C(Of Integer)() Dim d As D(Of Integer) = AddressOf o.G d() = 2 System.Console.Write(o.F) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) Dim verifier = CompileAndVerify(comp2, expectedOutput:="2") verifier.VerifyIL("M.Main", ) verifier.VerifyDiagnostics() End Sub ''' ''' Locals should be values not references. ''' Public Sub Local() Dim comp1 = CreateCSharpCompilation( "public class C { public static ref T F(ref T t) { return ref t; } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim x = 2 Dim y = C.F(x) y = 3 System.Console.Write(""{0} {1}"", x, y) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) Dim verifier = CompileAndVerify(comp2, expectedOutput:="2 3") verifier.VerifyIL("M.Main", ) verifier.VerifyDiagnostics() End Sub Public Sub SharedPropertyAssignment() Dim comp1 = CreateCSharpCompilation( "public class C { #pragma warning disable 0649 private static T _p; public static ref T P { get { return ref _p; } } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim d = 1.5 ' must not be stack local C(Of Double).P = d C(Of Double).P = d ' assign second time, should not be on stack C(Of Double).P += 2.0 System.Console.Write(C(Of Double).P) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.ReleaseExe) Dim verifier = CompileAndVerify(comp2, expectedOutput:="3.5") verifier.VerifyIL("M.Main", ) verifier.VerifyDiagnostics() End Sub Public Sub PropertyAssignment() Dim comp1 = CreateCSharpCompilation( "public class C { #pragma warning disable 0649 private T _p; public ref T P { get { return ref _p; } } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o = New C(Of Integer)() o.P = 1 o.P += 2 System.Console.Write(o.P) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) Dim verifier = CompileAndVerify(comp2, expectedOutput:="3") verifier.VerifyIL("M.Main", ) verifier.VerifyDiagnostics() End Sub Public Sub DefaultPropertyAssignment() Dim comp1 = CreateCSharpCompilation( "public class C { #pragma warning disable 0649 private T[] _p = new T[10]; public ref T this[int index] { get { return ref _p[index]; } } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o = New C(Of Integer)() o(2) = 1 o(2) += 2 System.Console.Write(o(2)) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) Dim verifier = CompileAndVerify(comp2, expectedOutput:="3") verifier.VerifyIL("M.Main", ) verifier.VerifyDiagnostics() End Sub Public Sub PropertyArgument() Dim comp1 = CreateCSharpCompilation( "public class A { public A(T p) { _p = p; } #pragma warning disable 0649 private T _p; public ref T P { get { return ref _p; } } } public class B { public static void F(ref int i) { i *= 2; } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim x = New A(Of Integer)(1) Dim y = New A(Of Byte)(2) B.F(x.P) ' No conversion, passed by ref B.F(y.P) ' Widening conversion, passed by value with copy-back System.Console.Write(""{0} {1}"", x.P, y.P) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) Dim verifier = CompileAndVerify(comp2, expectedOutput:="2 4") verifier.VerifyIL("M.Main", ) verifier.VerifyDiagnostics() End Sub ''' ''' Setter of read/write property should be ignored. ''' Public Sub ReadWriteProperty() Dim ilSource = .Value Dim ref1 = CompileIL(ilSource) Dim comp = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o = New C() o.F() = 1 o.P = o.F() o.P += 2 System.Console.Write(""{0}, {1}"", o.F(), o.P) End Sub End Module", referencedAssemblies:={MscorlibRef, SystemRef, MsvbRef, ref1}, compilationOptions:=TestOptions.DebugExe) Dim verifier = CompileAndVerify(comp, expectedOutput:="1, 3") verifier.VerifyIL("M.Main", ) verifier.VerifyDiagnostics() End Sub ''' ''' Setter of read/write property should be ignored, ''' even if mismatched signature. ''' Public Sub ReadWriteProperty_DifferentSignatures() Dim ilSource = .Value Dim ref1 = CompileIL(ilSource) Dim comp = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o = New C() o.P = 1 o.Q(1) = 2 System.Console.Write(""{0}, {1}"", o.P, o.Q(1)) End Sub End Module", referencedAssemblies:={MscorlibRef, SystemRef, MsvbRef, ref1}, compilationOptions:=TestOptions.DebugExe) Dim verifier = CompileAndVerify(comp, expectedOutput:="1, 2") verifier.VerifyIL("M.Main", ) verifier.VerifyDiagnostics() Dim p = comp.GetMember(Of PropertySymbol)("C.P") Assert.True(p.ReturnsByRef) Assert.Equal("ByRef Property C.P As System.Object", p.ToTestDisplayString()) Dim q = comp.GetMember(Of PropertySymbol)("C.Q") Assert.True(q.ReturnsByRef) Assert.Equal("ByRef Property C.Q(i As System.Object) As System.Object", q.ToTestDisplayString()) End Sub Public Sub Implement() Dim comp1 = CreateCSharpCompilation( "public interface I { ref object F(); ref object P { get; } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Class C Implements I Public Function F() As Object Implements I.F Return Nothing End Function Public ReadOnly Property P As Object Implements I.P Get Return Nothing End Get End Property End Class", referencedCompilations:={comp1}) comp2.AssertTheseDiagnostics( ) End Sub Public Sub Override() Dim comp1 = CreateCSharpCompilation( "public abstract class A { public abstract ref object F(); public abstract ref object P { get; } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "MustInherit Class B Inherits A Public Overrides Function F() As Object Return Nothing End Function Public Overrides ReadOnly Property P As Object Get Return Nothing End Get End Property End Class", referencedCompilations:={comp1}) comp2.AssertTheseDiagnostics( ) End Sub Public Sub Override_Metadata() Dim ilSource = .Value Dim ref1 = CompileIL(ilSource) Dim comp = CreateVisualBasicCompilation( Nothing, "", referencedAssemblies:={MscorlibRef, SystemRef, MsvbRef, ref1}, compilationOptions:=TestOptions.DebugDll) Dim method = comp.GetMember(Of MethodSymbol)("B1.F") Assert.Equal("Function B1.F() As System.Object", method.ToTestDisplayString()) Assert.Equal("Function A.F() As System.Object", method.OverriddenMethod.ToTestDisplayString()) Dim [property] = comp.GetMember(Of PropertySymbol)("B1.P") Assert.Equal("ReadOnly Property B1.P As System.Object", [property].ToTestDisplayString()) Assert.Null([property].OverriddenProperty) method = comp.GetMember(Of MethodSymbol)("B2.F") Assert.Equal("ByRef Function B2.F() As System.Object", method.ToTestDisplayString()) Assert.Null(method.OverriddenMethod) [property] = comp.GetMember(Of PropertySymbol)("B2.P") Assert.Equal("ReadOnly ByRef Property B2.P As System.Object", [property].ToTestDisplayString()) Assert.Equal("ReadOnly ByRef Property A.P As System.Object", [property].OverriddenProperty.ToTestDisplayString()) End Sub Public Sub ExpressionLambdas() Dim comp1 = CreateCSharpCompilation( "public class A { #pragma warning disable 0649 private static T _f; public static ref T F() { return ref _f; } private T _p; public ref T P { get { return ref _p; } } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Imports System Imports System.Linq.Expressions Module M Sub Main() Dim e As Expression(Of Action) = Sub() M(A(Of Integer).F()) Dim f As Expression(Of Action) = Sub() M(New A(Of Integer)().P) End Sub Sub M(i As Integer) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics( ) End Sub Public Sub MidAssignment() Dim comp1 = CreateCSharpCompilation( "public class C { #pragma warning disable 0649 private string _p = ""abcd""; public ref string P { get { return ref _p; } } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o = New C() Mid(o.P, 2, 2) = ""efg"" System.Console.Write(o.P) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) Dim verifier = CompileAndVerify(comp2, expectedOutput:="aefd") verifier.VerifyIL("M.Main", ) verifier.VerifyDiagnostics() End Sub ''' ''' Early-bound calls to ByRef-returning methods ''' supported as arguments to late-bound methods. ''' Public Sub RefReturnArgumentToLateBoundCall() Dim comp1 = CreateCSharpCompilation( "public class A { #pragma warning disable 0649 private string _f; public ref string F() { return ref _f; } private string _g; public ref string G() { return ref _g; } } public class B { public void F(string a, ref string b) { a = a.ToLower(); b = b.ToLower(); } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim a = New A() a.F() = ""ABC"" a.G() = ""DEF"" F(New B(), a) System.Console.Write(a.F() + a.G()) End Sub Sub F(b As Object, a As A) b.F(a.F(), a.G()) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) Dim verifier = CompileAndVerify(comp2, expectedOutput:="ABCdef") verifier.VerifyIL("M.F", ) verifier.VerifyDiagnostics() End Sub ''' ''' Late-bound calls with ByRef return values not supported. ''' Public Sub RefReturnLateBoundCall() Dim comp1 = CreateCSharpCompilation( "public class A { #pragma warning disable 0649 private string _f = ""ABC""; public string F() { return _f; } private string _g = ""DEF""; public ref string G() { return ref _g; } } public class B { public void F(string a, ref string b) { a = a.ToLower(); b = b.ToLower(); } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim a = New A() Try F(New B(), a) Catch e As System.Exception System.Console.Write(e.Message) End Try End Sub Sub F(b As B, a As Object) b.F(a.F(), a.G()) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) Dim verifier = CompileAndVerify(comp2, expectedOutput:="Public member 'G' on type 'A' not found.") verifier.VerifyIL("M.F", ) verifier.VerifyDiagnostics() End Sub Public Sub InLambda() Dim comp1 = CreateCSharpCompilation( "public class C { public static ref T F(ref T t) { return ref t; } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim f = Sub(ByRef x As Integer, y As Integer) C.F(x) = y Dim o = 2 f(o, 3) System.Console.Write(o) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) Dim verifier = CompileAndVerify(comp2, expectedOutput:="3") verifier.VerifyIL("M.Main", " IL_0006: brfalse.s IL_000f IL_0008: ldsfld "M._Closure$__.$I0-0 As " IL_000d: br.s IL_0025 IL_000f: ldsfld "M._Closure$__.$I As M._Closure$__" IL_0014: ldftn "Sub M._Closure$__._Lambda$__0-0(ByRef Integer, Integer)" IL_001a: newobj "Sub VB$AnonymousDelegate_0(Of Integer, Integer)..ctor(Object, System.IntPtr)" IL_001f: dup IL_0020: stsfld "M._Closure$__.$I0-0 As " IL_0025: stloc.0 IL_0026: ldc.i4.2 IL_0027: stloc.1 IL_0028: ldloc.0 IL_0029: ldloca.s V_1 IL_002b: ldc.i4.3 IL_002c: callvirt "Sub VB$AnonymousDelegate_0(Of Integer, Integer).Invoke(ByRef Integer, Integer)" IL_0031: nop IL_0032: ldloc.1 IL_0033: call "Sub System.Console.Write(Integer)" IL_0038: nop IL_0039: ret } ]]>) verifier.VerifyDiagnostics() End Sub Public Sub LambdaToByRefDelegate() Dim comp1 = CreateCSharpCompilation( "public delegate ref T D(); public class A { #pragma warning disable 0649 private T _t; public ref T F() { return ref _t; } } public class B { public static void F(D d, T t) { d() = t; } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o As New A(Of Integer)() B.F(Function() o.F(), 2) Dim d = Function() o.F() B.F(d, 2) System.Console.Write(o.F()) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics( () As Integer' cannot be converted to 'D(Of Integer)'. B.F(d, 2) ~ ]]>) End Sub Public Sub LambdaCallingByRefFunction() Dim comp1 = CreateCSharpCompilation( "public delegate T D(); public class A { private T _t; public A(T t) { _t = t; } public ref T F() { return ref _t; } } public class B { public static void F(D d) { System.Console.WriteLine(d()); } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o As New A(Of String)(""13206"") B.F(Function() o.F()) Dim d = Function() o.F() B.F(d) System.Console.WriteLine(o.F()) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics() Dim verifier = CompileAndVerify(comp2, expectedOutput:= "13206 13206 13206") verifier.VerifyDiagnostics() End Sub Public Sub LambdaCallingByRefFunctionDifferentType() Dim comp1 = CreateCSharpCompilation( "public delegate string D(); public class A { private T _t; public A(T t) { _t = t; } public ref T F() { return ref _t; } } public class B { public static void F(D d) { System.Console.WriteLine(d()); } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o As New A(Of Integer)(13206) B.F(Function() o.F()) Dim d = Function() o.F() B.F(d) System.Console.WriteLine(o.F()) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics() Dim verifier = CompileAndVerify(comp2, expectedOutput:= "13206 13206 13206") verifier.VerifyDiagnostics() End Sub Public Sub LambdaCallingByRefFunctionDropReturn() Dim comp1 = CreateCSharpCompilation( "public delegate void D(); public class A { private T _t; public A(T t) { _t = t; } public ref T F() { System.Console.WriteLine(""A.F""); return ref _t; } } public class B { public static void F(D d) { System.Console.WriteLine(""B.F""); d(); } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o As New A(Of Integer)(13206) B.F(Function() o.F()) Dim d = Function() o.F() B.F(d) System.Console.WriteLine(o.F()) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics() Dim verifier = CompileAndVerify(comp2, expectedOutput:= "B.F A.F B.F A.F A.F 13206") verifier.VerifyDiagnostics() End Sub Public Sub LambdaCallingByRefFunctionKeepingVsDroppingByRef() Dim comp1 = CreateCSharpCompilation( " public delegate T D1(); public delegate ref T D2(); public class A { private T _t; public A(T t) { _t = t; } public ref T F() { return ref _t; } } public class B { public static void F(D1 d, T t) { System.Console.WriteLine(""D1""); d(); } public static void F(D2 d, T t) { System.Console.WriteLine(""D2""); d() = t; } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o As New A(Of Integer)(13206) B.F(Function() o.F, 1) Dim d = Function() o.F B.F(d, 2) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics() Dim verifier = CompileAndVerify(comp2, expectedOutput:= "D1 D1") verifier.VerifyDiagnostics() End Sub Public Sub DelegateToByRefFunction() Dim comp1 = CreateCSharpCompilation( "public delegate ref T D(); public class A { #pragma warning disable 0649 private T _t; public ref T F() { return ref _t; } } public class B { public static void F(D d, T t) { d() = t; } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o As New A(Of Integer)() B.F(AddressOf o.F, 2) System.Console.Write(o.F()) B.F(New D(Of Integer)(AddressOf o.F), 3) System.Console.Write(o.F()) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics() Dim verifier = CompileAndVerify(comp2, expectedOutput:="23") verifier.VerifyDiagnostics() End Sub Public Sub DelegateToByRefFunctionDropArguments() Dim comp1 = CreateCSharpCompilation( "public delegate ref T D(int x); public class A { #pragma warning disable 0649 private T _t; public ref T F() { return ref _t; } } public class B { public static void F(D d, T t) { d(1) = t; } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o As New A(Of Integer)() B.F(AddressOf o.F, 2) System.Console.Write(o.F()) B.F(New D(Of Integer)(AddressOf o.F), 3) System.Console.Write(o.F()) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics( BC31143: Method 'Public Overloads ByRef Function F() As Integer' does not have a signature compatible with delegate 'Delegate ByRef Function D(Of Integer)(x As Integer) As Integer'. B.F(AddressOf o.F, 2) ~~~ BC31143: Method 'Public Overloads ByRef Function F() As Integer' does not have a signature compatible with delegate 'Delegate ByRef Function D(Of Integer)(x As Integer) As Integer'. B.F(New D(Of Integer)(AddressOf o.F), 3) ~~~ ) End Sub Public Sub DelegateToByRefFunctionDropArgumentsAndByRef() Dim comp1 = CreateCSharpCompilation( "public delegate T D(int x); public class A { #pragma warning disable 0649 private T _t; public ref T F() { System.Console.WriteLine(""A.F""); return ref _t; } } public class B { public static void F(D d, T t) { System.Console.WriteLine(""B.F""); d(1); } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o As New A(Of Integer)() B.F(AddressOf o.F, 2) B.F(New D(Of Integer)(AddressOf o.F), 3) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics( BC31143: Method 'Public Overloads ByRef Function F() As Integer' does not have a signature compatible with delegate 'Delegate Function D(Of Integer)(x As Integer) As Integer'. B.F(AddressOf o.F, 2) ~~~ BC31143: Method 'Public Overloads ByRef Function F() As Integer' does not have a signature compatible with delegate 'Delegate Function D(Of Integer)(x As Integer) As Integer'. B.F(New D(Of Integer)(AddressOf o.F), 3) ~~~ ) End Sub Public Sub DelegateToByRefFunctionDropByRef() Dim comp1 = CreateCSharpCompilation( "public delegate T D(); public class A { private T _t; public A(T t) { _t = t; } public ref T F() { return ref _t; } } public class B { public static void F(D d) { System.Console.WriteLine(d()); } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o As New A(Of String)(13206) B.F(AddressOf o.F) System.Console.WriteLine(o.F()) o = New A(Of String)(13207) B.F(New D(Of Integer)(AddressOf o.F)) System.Console.WriteLine(o.F()) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics( BC31143: Method 'Public Overloads ByRef Function F() As String' does not have a signature compatible with delegate 'Delegate Function D(Of String)() As String'. B.F(AddressOf o.F) ~~~ BC32050: Type parameter 'T' for 'Public Shared Overloads Sub F(Of T)(d As D(Of T))' cannot be inferred. B.F(New D(Of Integer)(AddressOf o.F)) ~ BC31143: Method 'Public Overloads ByRef Function F() As String' does not have a signature compatible with delegate 'Delegate Function D(Of Integer)() As Integer'. B.F(New D(Of Integer)(AddressOf o.F)) ~~~ ) End Sub Public Sub DelegateToByRefFunctionDropReturn() Dim comp1 = CreateCSharpCompilation( "public delegate void D(); public class A { private T _t; public A(T t) { _t = t; } public ref T F() { System.Console.WriteLine(""A.F""); return ref _t; } } public class B { public static void F(D d) { System.Console.WriteLine(""B.F""); d(); } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o As New A(Of String)(13206) B.F(AddressOf o.F) B.F(New D(AddressOf o.F)) System.Console.Write(o.F()) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics( BC31143: Method 'Public Overloads ByRef Function F() As String' does not have a signature compatible with delegate 'Delegate Sub D()'. B.F(AddressOf o.F) ~~~ BC31143: Method 'Public Overloads ByRef Function F() As String' does not have a signature compatible with delegate 'Delegate Sub D()'. B.F(New D(AddressOf o.F)) ~~~ ) End Sub Public Sub DelegateToByRefFunctionDropByRefDifferentType() Dim comp1 = CreateCSharpCompilation( "public delegate string D(); public class A { private T _t; public A(T t) { _t = t; } public ref T F() { return ref _t; } } public class B { public static void F(D d) { System.Console.WriteLine(d()); } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o As New A(Of Integer)(13206) B.F(AddressOf o.F) System.Console.WriteLine(o.F()) o = New A(Of Integer)(13207) B.F(New D(AddressOf o.F)) System.Console.WriteLine(o.F()) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics( BC31143: Method 'Public Overloads ByRef Function F() As Integer' does not have a signature compatible with delegate 'Delegate Function D() As String'. B.F(AddressOf o.F) ~~~ BC31143: Method 'Public Overloads ByRef Function F() As Integer' does not have a signature compatible with delegate 'Delegate Function D() As String'. B.F(New D(AddressOf o.F)) ~~~ ) End Sub Public Sub DelegateAddByRef() Dim comp1 = CreateCSharpCompilation( "public delegate ref T D(); public class A { private T _t; public A(T t) { _t = t; } public T F() { return _t; } } public class B { public static void F(D d, T t) { d() = t; } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o As New A(Of String)(13206) B.F(AddressOf o.F, ""1"") System.Console.Write(o.F()) o = New A(Of String)(13207) B.F(New D(Of Integer)(AddressOf o.F), ""2"") System.Console.Write(o.F()) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics( BC31143: Method 'Public Overloads Function F() As String' does not have a signature compatible with delegate 'Delegate ByRef Function D(Of String)() As String'. B.F(AddressOf o.F, "1") ~~~ BC31143: Method 'Public Overloads Function F() As String' does not have a signature compatible with delegate 'Delegate ByRef Function D(Of Integer)() As Integer'. B.F(New D(Of Integer)(AddressOf o.F), "2") ~~~ ) End Sub Public Sub DelegateToByRefFunctionWithDifferentType() Dim comp1 = CreateCSharpCompilation( "public delegate ref string D(); public class A { #pragma warning disable 0649 private T _t; public ref T F() { return ref _t; } } public class B { public static void F(D d, T t) { d() = t.ToString(); } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o As New A(Of Integer)() B.F(AddressOf o.F, 2) System.Console.Write(o.F()) B.F(New D(AddressOf o.F), 3) System.Console.Write(o.F()) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics( BC31143: Method 'Public Overloads ByRef Function F() As Integer' does not have a signature compatible with delegate 'Delegate ByRef Function D() As String'. B.F(AddressOf o.F, 2) ~~~ BC31143: Method 'Public Overloads ByRef Function F() As Integer' does not have a signature compatible with delegate 'Delegate ByRef Function D() As String'. B.F(New D(AddressOf o.F), 3) ~~~ ) End Sub Public Sub DelegateToByRefFunctionWithDerivedType() Dim comp1 = CreateCSharpCompilation( " public delegate ref T D(); public class A { #pragma warning disable 0649 private T _t; public ref T F() { return ref _t; } } public class B { public static void F(D d, T t) { d() = t; } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o As New A(Of String)() B.F(Of Object)(AddressOf o.F, new Object) System.Console.Write(o.F()) B.F(Of Object)(New D(of Object)(AddressOf o.F), Nothing) System.Console.Write(o.F()) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics( BC31143: Method 'Public Overloads ByRef Function F() As String' does not have a signature compatible with delegate 'Delegate ByRef Function D(Of Object)() As Object'. B.F(Of Object)(AddressOf o.F, new Object) ~~~ BC31143: Method 'Public Overloads ByRef Function F() As String' does not have a signature compatible with delegate 'Delegate ByRef Function D(Of Object)() As Object'. B.F(Of Object)(New D(of Object)(AddressOf o.F), Nothing) ~~~ ) End Sub Public Sub RefMethodGroupConversionError_WithResolution() Dim comp1 = CreateCSharpCompilation( " public class Base { public static Base Instance = new Base(); } public class Derived1 : Base { public static new Derived1 Instance = new Derived1(); } public class Derived2 : Derived1 { } public delegate ref TResult RefFunc1(TArg arg); public class Methods { public static ref Base M1(Base arg) => ref Base.Instance; public static ref Derived1 M1(Derived1 arg) => ref Derived1.Instance; } ") Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim f as RefFunc1(OF Derived2, Base) = AddressOf Methods.M1 System.Console.WriteLine(f(Nothing)) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics( BC31143: Method 'Public Shared Overloads ByRef Function M1(arg As Derived1) As Derived1' does not have a signature compatible with delegate 'Delegate ByRef Function RefFunc1(Of Derived2, Base)(arg As Derived2) As Base'. Dim f as RefFunc1(OF Derived2, Base) = AddressOf Methods.M1 ~~~~~~~~~~ ) End Sub Public Sub RefMethodGroupConversionNoError_WithResolution() Dim comp1 = CreateCSharpCompilation( " public class Base { public static Base Instance = new Base(); } public class Derived1 : Base { public static new Derived1 Instance = new Derived1(); } public class Derived2 : Derived1 { } public delegate ref TResult RefFunc1(TArg arg); public class Methods { public static ref Base M1(Base arg) => throw null; public static ref Base M1(Derived1 arg) => ref Base.Instance; } ") Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim f as RefFunc1(of Derived2, Base) = AddressOf Methods.M1 System.Console.WriteLine(f(Nothing)) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) Dim verifier = CompileAndVerify(comp2, expectedOutput:="Base") verifier.VerifyDiagnostics() End Sub Public Sub RefMethodGroupConversionNoError_WithResolution1() Dim comp1 = CreateCSharpCompilation( " public class Base { public static Base Instance = new Base(); } public class Derived1 : Base { public static new Derived1 Instance = new Derived1(); } public class Derived2 : Derived1 { } public delegate ref TResult RefFunc1(TArg arg); public class Methods { public static ref Base M1(Derived1 arg) => ref Base.Instance; public static ref Base M3(Derived2 arg) => ref Base.Instance; public static void Test(RefFunc1 arg) => System.Console.WriteLine(arg); public static void Test(RefFunc1 arg) => System.Console.WriteLine(arg);} ") Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Methods.Test(AddressOf Methods.M1) Methods.Test(AddressOf Methods.M3) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) Dim verifier = CompileAndVerify(comp2, expectedOutput:="RefFunc1`2[Derived2,Base] RefFunc1`2[Derived2,Base]") verifier.VerifyDiagnostics() End Sub Public Sub RefMethodGroupOverloadResolution() Dim comp1 = CreateCSharpCompilation( " public class Base { public static Base Instance = new Base(); } public class Derived1 : Base { public static new Derived1 Instance = new Derived1(); } public class Derived2 : Derived1 { } public delegate ref TResult RefFunc1(TArg arg); public class Methods { public static ref Derived1 M2(Base arg) => ref Derived1.Instance; public static void Test(RefFunc1 arg) => System.Console.WriteLine(arg); public static void Test(RefFunc1 arg) => System.Console.WriteLine(arg); } ") Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Methods.Test(AddressOf Methods.M2) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) Dim verifier = CompileAndVerify(comp2, expectedOutput:="RefFunc1`2[Derived2,Derived1]") verifier.VerifyDiagnostics() End Sub Public Sub RefLambdaOverloadResolution() Dim comp1 = CreateCSharpCompilation( " public class Base { public static Base Instance = new Base(); } public class Derived1 : Base { public static new Derived1 Instance = new Derived1(); } public class Derived2 : Derived1 { } public delegate ref TResult RefFunc1(TArg arg); public class Methods { public static ref Derived1 M2(Base arg) => ref Derived1.Instance; public static void Test(RefFunc1 arg) => System.Console.WriteLine(arg); public static void Test(System.Func arg) => System.Console.WriteLine(arg); } ") Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Methods.Test(Function(t)Base.Instance) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) Dim verifier = CompileAndVerify(comp2, expectedOutput:="System.Func`2[Derived1,Base]") verifier.VerifyDiagnostics() End Sub Public Sub DelegateToByRefFunctionWithBaseType() Dim comp1 = CreateCSharpCompilation( " public delegate ref T D(); public class A { #pragma warning disable 0649 private T _t; public ref T F() { return ref _t; } } public class B { public static void F(D d, T t) { d() = t; } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o As New A(Of Object)() B.F(Of String)(AddressOf o.F, String.Empty) System.Console.Write(o.F()) B.F(Of String)(New D(of String)(AddressOf o.F), Nothing) System.Console.Write(o.F()) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics( BC31143: Method 'Public Overloads ByRef Function F() As Object' does not have a signature compatible with delegate 'Delegate ByRef Function D(Of String)() As String'. B.F(Of String)(AddressOf o.F, String.Empty) ~~~ BC31143: Method 'Public Overloads ByRef Function F() As Object' does not have a signature compatible with delegate 'Delegate ByRef Function D(Of String)() As String'. B.F(Of String)(New D(of String)(AddressOf o.F), Nothing) ~~~ ) End Sub Public Sub DelegateToByRefFunctionKeepingVsDroppingByRef() Dim comp1 = CreateCSharpCompilation( " public delegate T D1(); public delegate ref T D2(); public class A { private T _t; public A(T t) { _t = t; } public ref T F() { return ref _t; } } public class B { public static void F(D1 d, T t) { System.Console.WriteLine(""D1""); d(); } public static void F(D2 d, T t) { System.Console.WriteLine(""D2""); d() = t; } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o As New A(Of Integer)(13206) B.F(AddressOf o.F, 1) System.Console.WriteLine(o.F()) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics() Dim verifier = CompileAndVerify(comp2, expectedOutput:= "D2 1") verifier.VerifyDiagnostics() End Sub Public Sub DelegateToByRefFunctionDroppingByRefVsDroppingReturn() Dim comp1 = CreateCSharpCompilation( " public delegate T D1(); public delegate void D2(); public class A { private T _t; public A(T t) { _t = t; } public ref T F() { System.Console.WriteLine(""A.F""); return ref _t; } } public class B { public static void F(D1 d) { System.Console.WriteLine(""D1""); d(); } public static void F(D2 d) { System.Console.WriteLine(""D2""); d(); } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, "Module M Sub Main() Dim o As New A(Of Integer)(13206) B.F(AddressOf o.F) End Sub End Module", referencedCompilations:={comp1}, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics( BC31143: Method 'Public Overloads ByRef Function F() As Integer' does not have a signature compatible with delegate 'Delegate Function D1(Of Integer)() As Integer'. B.F(AddressOf o.F) ~~~ ) End Sub Public Sub SpillingByRefCall_NoSpilling() Dim comp1 = CreateCSharpCompilation( " using System; public class TestClass { int x = 0; public ref int Save(int y) { x = y; return ref x; } public void Write(ref int y) { Console.WriteLine(y); } public void Write(ref int y, int z) { Console.WriteLine(y); } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, " Imports System.Threading.Tasks Module Module1 Sub Main() TestMethod().Wait() End Sub Async Function TestMethod() As Task Dim inst = New TestClass ' this is OK. `ref` call is not spilled. ' prints: 10 (last value) inst.Write(inst.Save(Await Task.FromResult(10))) ' this is OK. `ref` call is not spilled. ' prints: 22 (last value) inst.Write(inst.Save(Await Task.FromResult(20)), inst.Save(22)) End Function End Module ", referencedCompilations:={comp1}, referencedAssemblies:=LatestVbReferences, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics() Dim verifier = CompileAndVerify(comp2, expectedOutput:= " 10 22 ") verifier.VerifyDiagnostics() End Sub Public Sub SpillingByRefCall_Spilling() Dim comp1 = CreateCSharpCompilation( " using System; public class TestClass { int x = 0; public ref int Save(int y) { x = y; return ref x; } public void Write(ref int y) { Console.WriteLine(y); } public void Write(ref int y, int z) { Console.WriteLine(y); } }") comp1.VerifyDiagnostics() Dim comp2 = CreateVisualBasicCompilation( Nothing, " Imports System.Threading.Tasks Module Module1 Sub Main() TestMethod().Wait() End Sub Async Function TestMethod() As Task Dim inst = New TestClass ' ERROR? ' currently `ref` is spilled 'by-value' and assert fires. inst.Write(inst.Save(Await Task.FromResult(30)), inst.Save(Await Task.FromResult(33))) End Function End Module ", referencedCompilations:={comp1}, referencedAssemblies:=LatestVbReferences, compilationOptions:=TestOptions.DebugExe) comp2.AssertTheseDiagnostics() Dim verifier = CompileAndVerify(comp2, expectedOutput:= " ?? ") verifier.VerifyDiagnostics() End Sub End Class End Namespace