Includes the following commits:
6f5bfe5cf5a
3812d1c13fc
a80f3d0d87c
b2f051f0b19
2a202a8478b
4d7d1606d73
d9970305731
94e80fc8d7f
0b9280083a9
07d1e5f36a5
5f279f14aa2
889421f3bef
f4c0fd3dc11
71df5c63b46
d6e5bf16782
207f5c2cd6d
c512752a416
9aca8d5fe4b
diff --git a/mcs/class/Mono.CSharp/Test/Evaluator/TypesTest.cs b/mcs/class/Mono.CSharp/Test/Evaluator/TypesTest.cs
index 97f9e047e6d..f8bf63455de 100644
--- a/mcs/class/Mono.CSharp/Test/Evaluator/TypesTest.cs
+++ b/mcs/class/Mono.CSharp/Test/Evaluator/TypesTest.cs
@@ -131,5 +131,17 @@ namespace MonoTests.EvaluatorTest
 		{
 			Evaluator.Run ("public class TestClass { private TestEnum _te; public string Get() { return _te.ToString(); } } public enum TestEnum { First, Second }");
 		}
+
+		[Test]
+		public void EnumTypeWithOrderDependency ()
+		{
+			Evaluator.Run ("public class TestClass { public enum TestEnum { Val1, Val2, Val3 } public TestEnum test; public TestClass() { test = TestEnum.Val3; } }");
+			object res = Evaluator.Evaluate ("new TestClass()");
+
+			var fields = res.GetType ().GetFields ();
+			foreach (var field in fields) {
+				Console.WriteLine ($"{field.Name} = {field.MemberType}");
+			}
+		}
 	}
 }
\ No newline at end of file
diff --git a/mcs/errors/cs0023-30.cs b/mcs/errors/cs0023-30.cs
new file mode 100644
index 00000000000..fc19cc24e3e
--- /dev/null
+++ b/mcs/errors/cs0023-30.cs
@@ -0,0 +1,11 @@
+// CS0023: The `is' operator cannot be applied to operand of type `default'
+// Line: 9
+// Compiler options: -langversion:latest
+
+class C
+{
+	static void Main ()
+	{
+		bool d = default is C;
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0029-39.cs b/mcs/errors/cs0029-39.cs
new file mode 100644
index 00000000000..0ed200036dc
--- /dev/null
+++ b/mcs/errors/cs0029-39.cs
@@ -0,0 +1,15 @@
+// CS0029: Cannot implicitly convert type `S' to `object'
+// Line: 13
+// Compiler options: -langversion:latest
+
+public ref struct S
+{
+}
+
+class Test
+{
+	public static void Main ()
+	{
+		object o = new S ();
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0029-40.cs b/mcs/errors/cs0029-40.cs
new file mode 100644
index 00000000000..6d9167c31fa
--- /dev/null
+++ b/mcs/errors/cs0029-40.cs
@@ -0,0 +1,19 @@
+// CS0029: Cannot implicitly convert type `S' to `System.ValueType'
+// Line: 16
+// Compiler options: -langversion:latest
+
+using System;
+
+public ref struct S
+{
+}
+
+class Test
+{
+	public static void Main ()
+	{
+		var s = default (S);
+		ValueType s2 = s;
+		var res = default (S).ToString ();
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0029-41.cs b/mcs/errors/cs0029-41.cs
new file mode 100644
index 00000000000..1a65f52f737
--- /dev/null
+++ b/mcs/errors/cs0029-41.cs
@@ -0,0 +1,12 @@
+// CS0029: Cannot implicitly convert type `System.TypedReference' to `object'
+// Line: 10
+
+using System;
+
+class Test
+{
+	public static void Main ()
+	{
+		var res = default (TypedReference).ToString ();
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0029-42.cs b/mcs/errors/cs0029-42.cs
new file mode 100644
index 00000000000..c7671000c76
--- /dev/null
+++ b/mcs/errors/cs0029-42.cs
@@ -0,0 +1,10 @@
+// CS0029: Cannot implicitly convert type `string' to `int'
+// Line: 8
+
+class C
+{
+	void Exists (int _)
+	{
+		_ = "2";
+	}	
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0030-17.cs b/mcs/errors/cs0030-17.cs
new file mode 100644
index 00000000000..b72b8bf71e5
--- /dev/null
+++ b/mcs/errors/cs0030-17.cs
@@ -0,0 +1,15 @@
+// CS0030: Cannot convert type `object' to `S'
+// Line: 13
+// Compiler options: -langversion:latest
+
+ref struct S
+{
+}
+
+class X
+{
+	public static void Foo (object o)
+	{
+		var res = (S) o;
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0103-18.cs b/mcs/errors/cs0103-18.cs
new file mode 100644
index 00000000000..8cec755d23d
--- /dev/null
+++ b/mcs/errors/cs0103-18.cs
@@ -0,0 +1,10 @@
+// CS0103: The name `_' does not exist in the current context
+// Line: 8
+
+class C
+{
+	void Test ()
+	{
+		_.ToString ();
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0123-10.cs b/mcs/errors/cs0123-10.cs
new file mode 100644
index 00000000000..43d5e5d6368
--- /dev/null
+++ b/mcs/errors/cs0123-10.cs
@@ -0,0 +1,18 @@
+// CS0123: A method or delegate `object.ToString()' parameters do not match delegate `System.Func<string>()' parameters
+// Line: 16
+// Compiler options: -langversion:latest
+
+using System;
+
+public ref struct S
+{
+}
+
+class Test
+{
+	public static void Main ()
+	{
+		var s = new S ();
+		Func<string> f = s.ToString;
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0123-11.cs b/mcs/errors/cs0123-11.cs
new file mode 100644
index 00000000000..427b628c159
--- /dev/null
+++ b/mcs/errors/cs0123-11.cs
@@ -0,0 +1,12 @@
+// CS0123: A method or delegate `object.ToString()' parameters do not match delegate `System.Func<string>()' parameters
+// Line: 16
+
+using System;
+
+class Test
+{
+	public static void Main ()
+	{
+		Func<string> f = default (TypedReference).ToString;
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0133-2.cs b/mcs/errors/cs0133-2.cs
index b7a37182d73..48488876f7e 100644
--- a/mcs/errors/cs0133-2.cs
+++ b/mcs/errors/cs0133-2.cs
@@ -1,4 +1,4 @@
-// CS0133: The expression being assigned to `c' must be constant
+// CS0133: The expression being assigned to `c' must be a constant or default value
 // Line: 10
 
 class C
diff --git a/mcs/errors/cs0133-3.cs b/mcs/errors/cs0133-3.cs
index caae3bde68c..2f7dac6880d 100644
--- a/mcs/errors/cs0133-3.cs
+++ b/mcs/errors/cs0133-3.cs
@@ -1,5 +1,5 @@
-// CS0133: The expression being assigned to `Foo' must be constant
-// Line: 12
+// CS0133: The expression being assigned to `Foo' must be a constant or default value
+// Line: 8
 
 class T
 {
diff --git a/mcs/errors/cs0133-4.cs b/mcs/errors/cs0133-4.cs
index 41fe639b446..54162d544ca 100644
--- a/mcs/errors/cs0133-4.cs
+++ b/mcs/errors/cs0133-4.cs
@@ -1,4 +1,4 @@
-// CS0133: The expression being assigned to `S.pathName' must be constant
+// CS0133: The expression being assigned to `S.pathName' must be a constant or default value
 // Line: 12
 // Compiler options: -unsafe
 
diff --git a/mcs/errors/cs0133-5.cs b/mcs/errors/cs0133-5.cs
index a49f265c690..32e6bfdf416 100644
--- a/mcs/errors/cs0133-5.cs
+++ b/mcs/errors/cs0133-5.cs
@@ -1,4 +1,4 @@
-// CS0133: The expression being assigned to `b' must be constant
+// CS0133: The expression being assigned to `b' must be a constant or default value
 // Line: 8
 
 class X
diff --git a/mcs/errors/cs0133-6.cs b/mcs/errors/cs0133-6.cs
index a523169cdbd..28448dd6de8 100644
--- a/mcs/errors/cs0133-6.cs
+++ b/mcs/errors/cs0133-6.cs
@@ -1,4 +1,4 @@
-// CS0133: The expression being assigned to `o' must be constant
+// CS0133: The expression being assigned to `o' must be a constant or default value
 // Line: 8
 
 class X
diff --git a/mcs/errors/cs0133-7.cs b/mcs/errors/cs0133-7.cs
index 10d82d9fe5e..024bc148229 100644
--- a/mcs/errors/cs0133-7.cs
+++ b/mcs/errors/cs0133-7.cs
@@ -1,4 +1,4 @@
-// CS0133: The expression being assigned to `o' must be constant
+// CS0133: The expression being assigned to `o' must be a constant or default value
 // Line: 8
 
 class X
diff --git a/mcs/errors/cs0133.cs b/mcs/errors/cs0133.cs
index 094194deabb..f0dda9ee3cb 100644
--- a/mcs/errors/cs0133.cs
+++ b/mcs/errors/cs0133.cs
@@ -1,5 +1,6 @@
-// CS0133: The expression being assigned to `x' must be constant
-// Line: 6
+// CS0133: The expression being assigned to `x' must be a constant or default value
+// Line: 7
+
 class X {
 	X (int arg)
 	{
diff --git a/mcs/errors/cs0306-4.cs b/mcs/errors/cs0306-4.cs
new file mode 100644
index 00000000000..4653512e55b
--- /dev/null
+++ b/mcs/errors/cs0306-4.cs
@@ -0,0 +1,15 @@
+// CS0306: The type `S' may not be used as a type argument
+// Line: 13
+// Compiler options: -langversion:latest
+
+public ref struct S
+{
+}
+
+class Test<T>
+{
+	public static void Foo ()
+	{
+		Test<S> local;
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0611-3.cs b/mcs/errors/cs0611-3.cs
new file mode 100644
index 00000000000..6eda773dd24
--- /dev/null
+++ b/mcs/errors/cs0611-3.cs
@@ -0,0 +1,15 @@
+// CS0611: Array elements cannot be of type `S'
+// Line: 13
+// Compiler options: -langversion:latest
+
+public ref struct S
+{
+}
+
+class Test
+{
+	public static void Main ()
+	{
+		var x = new S[0];
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0815-9.cs b/mcs/errors/cs0815-9.cs
new file mode 100644
index 00000000000..f54703349be
--- /dev/null
+++ b/mcs/errors/cs0815-9.cs
@@ -0,0 +1,11 @@
+// CS0815: An implicitly typed local variable declaration cannot be initialized with `default'
+// Line: 9
+// Compiler options: -langversion:latest
+
+static class X
+{
+	public static void Main ()
+	{
+		var x = default;
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs1502-11.cs b/mcs/errors/cs1502-11.cs
deleted file mode 100644
index 82dcb3a2c17..00000000000
--- a/mcs/errors/cs1502-11.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-// CS1502: The best overloaded method match for `string.String(char*)' has some invalid arguments
-// Line: 8
-
-class C
-{
-	static string Prop {
-		get {
-			return new string ("s");
-		}
-    }
-}
diff --git a/mcs/errors/cs1599-2.cs b/mcs/errors/cs1599-2.cs
index 941ff6bb0d6..28aa05b2ed3 100644
--- a/mcs/errors/cs1599-2.cs
+++ b/mcs/errors/cs1599-2.cs
@@ -1,4 +1,4 @@
-// CS1599: Method or delegate cannot return type `System.ArgIterator'
+// CS1599: The return type of `System.ArgIterator' is not allowed
 // Line: 8
 
 using System;
diff --git a/mcs/errors/cs1599-3.cs b/mcs/errors/cs1599-3.cs
index e4869dcaf70..9d378099d82 100644
--- a/mcs/errors/cs1599-3.cs
+++ b/mcs/errors/cs1599-3.cs
@@ -1,4 +1,4 @@
-// CS1599: Method or delegate cannot return type `System.ArgIterator'
+// CS1599: The return type of `System.ArgIterator' is not allowed
 // Line: 8
 
 using System;
diff --git a/mcs/errors/cs1599-4.cs b/mcs/errors/cs1599-4.cs
new file mode 100644
index 00000000000..358eee59a13
--- /dev/null
+++ b/mcs/errors/cs1599-4.cs
@@ -0,0 +1,12 @@
+// CS1599: The return type of `System.TypedReference' is not allowed
+// Line: 8
+
+using System;
+
+public class Program
+{
+    public static TypedReference operator + (int a, Program b)
+    {
+    	throw new ApplicationException ();
+    }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs1599.cs b/mcs/errors/cs1599.cs
index 5cef32d7f97..871d9fb3e7a 100644
--- a/mcs/errors/cs1599.cs
+++ b/mcs/errors/cs1599.cs
@@ -1,4 +1,4 @@
-// CS1599: Method or delegate cannot return type `System.TypedReference'
+// CS1599: The return type of `System.TypedReference' is not allowed
 // Line: 8
 
 using System;
diff --git a/mcs/errors/cs1644-57.cs b/mcs/errors/cs1644-57.cs
new file mode 100644
index 00000000000..7ee98373080
--- /dev/null
+++ b/mcs/errors/cs1644-57.cs
@@ -0,0 +1,7 @@
+// CS1644: Feature `ref structs' cannot be used because it is not part of the C# 7.0 language specification
+// Line: 5
+// Compiler options: -langversion:7
+
+ref struct S
+{
+}
\ No newline at end of file
diff --git a/mcs/errors/cs1644-58.cs b/mcs/errors/cs1644-58.cs
new file mode 100644
index 00000000000..e994cf338bd
--- /dev/null
+++ b/mcs/errors/cs1644-58.cs
@@ -0,0 +1,8 @@
+// CS1644: Feature `default literal' cannot be used because it is not part of the C# 7.0 language specification
+// Line: 7
+// Compiler options: -langversion:7
+
+class X
+{
+	int i = default;
+}
diff --git a/mcs/errors/cs1644-59.cs b/mcs/errors/cs1644-59.cs
new file mode 100644
index 00000000000..2f8aed6b958
--- /dev/null
+++ b/mcs/errors/cs1644-59.cs
@@ -0,0 +1,13 @@
+// CS1644: Feature `readonly references' cannot be used because it is not part of the C# 7.0 language specification
+// Line: 9
+// Compiler options: -langversion:7
+
+class X
+{
+	int i;
+
+	ref readonly int Test ()
+	{
+		return ref i;
+	}
+}
diff --git a/mcs/errors/cs1644-60.cs b/mcs/errors/cs1644-60.cs
new file mode 100644
index 00000000000..ca9547bc561
--- /dev/null
+++ b/mcs/errors/cs1644-60.cs
@@ -0,0 +1,11 @@
+// CS1644: Feature `discards' cannot be used because it is not part of the C# 6.0 language specification
+// Line: 9
+// Compiler options: -langversion:6
+
+class X
+{
+	int Test ()
+	{
+		_ = 2;
+	}
+}
diff --git a/mcs/errors/cs1738-2.cs b/mcs/errors/cs1738-2.cs
index f59221f4c7a..44b3f6d1b14 100644
--- a/mcs/errors/cs1738-2.cs
+++ b/mcs/errors/cs1738-2.cs
@@ -1,4 +1,4 @@
-// CS1738: Named arguments must appear after the positional arguments
+// CS1738: Named arguments must appear after the positional arguments when using language version older than 7.2
 // Line: 13
 
 using System;
diff --git a/mcs/errors/cs1738-3.cs b/mcs/errors/cs1738-3.cs
index 53c4efc3553..901ac0e5d59 100644
--- a/mcs/errors/cs1738-3.cs
+++ b/mcs/errors/cs1738-3.cs
@@ -1,4 +1,4 @@
-// CS1738: Named arguments must appear after the positional arguments
+// CS1738: Named arguments must appear after the positional arguments when using language version older than 7.2
 // Line: 14
 
 class C
diff --git a/mcs/errors/cs1738.cs b/mcs/errors/cs1738.cs
index dab9a61160b..537bc17b917 100644
--- a/mcs/errors/cs1738.cs
+++ b/mcs/errors/cs1738.cs
@@ -1,4 +1,4 @@
-// CS1738: Named arguments must appear after the positional arguments
+// CS1738: Named arguments must appear after the positional arguments when using language version older than 7.2
 // Line: 12
 
 class C
diff --git a/mcs/errors/cs1983.cs b/mcs/errors/cs1983.cs
index a2ef6c150d6..76d2db4e677 100644
--- a/mcs/errors/cs1983.cs
+++ b/mcs/errors/cs1983.cs
@@ -1,4 +1,4 @@
-// CS1983: The return type of an async method must be void, Task, or Task<T>
+// CS1983: The return type of an async method must be void or task type
 // Line: 6
 
 class C
diff --git a/mcs/errors/cs4012-3.cs b/mcs/errors/cs4012-3.cs
new file mode 100644
index 00000000000..fb3d1dc276f
--- /dev/null
+++ b/mcs/errors/cs4012-3.cs
@@ -0,0 +1,19 @@
+// CS4012: Parameters or local variables of type `S' cannot be declared in async methods or iterators
+// Line: 16
+// Compiler options: -langversion:latest
+
+using System;
+using System.Threading.Tasks;
+
+public ref struct S
+{
+}
+
+class C
+{
+	public async void Test ()
+	{
+		var tr = new S ();
+		await Task.Factory.StartNew (() => 6);
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs8175-2.cs b/mcs/errors/cs8175-2.cs
new file mode 100644
index 00000000000..27c4babf8bf
--- /dev/null
+++ b/mcs/errors/cs8175-2.cs
@@ -0,0 +1,19 @@
+// CS8175: Cannot use by-reference variable `s' inside an anonymous method, lambda expression, or query expression
+// Line: 17
+// Compiler options: -langversion:latest
+
+using System;
+
+public ref struct S
+{
+}
+
+class Test
+{
+	public static void Main ()
+	{
+		var s = new S ();
+
+		Action a = () => Console.WriteLine (s);
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs8183.cs b/mcs/errors/cs8183.cs
new file mode 100644
index 00000000000..f9e9004b737
--- /dev/null
+++ b/mcs/errors/cs8183.cs
@@ -0,0 +1,11 @@
+// CS8183: Cannot infer the type of implicitly-typed discard
+// Line: 9
+// Compiler options: -langversion:7.2
+
+class X
+{
+	public static void Main ()
+	{
+		_ = default;
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs8184.cs b/mcs/errors/cs8184.cs
new file mode 100644
index 00000000000..19a4685d7bd
--- /dev/null
+++ b/mcs/errors/cs8184.cs
@@ -0,0 +1,10 @@
+// CS8184: A deconstruction cannot mix declarations and expressions on the left-hand-side
+// Line: 8
+
+class X
+{
+	public static void Main ()
+	{
+		(int a, b) = (1, 2);
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs8207.cs b/mcs/errors/cs8207.cs
new file mode 100644
index 00000000000..31090948b45
--- /dev/null
+++ b/mcs/errors/cs8207.cs
@@ -0,0 +1,19 @@
+// CS8207: An expression tree cannot contain a discard
+// Line: 11
+
+using System;
+using System.Linq.Expressions;
+
+class X
+{
+	void Test ()
+	{
+		Expression<Func<bool>> e = () => TryGetValue (out _);
+	}
+
+	bool TryGetValue (out int arg)
+	{
+		arg = 3;
+		return true;
+	}
+}
diff --git a/mcs/errors/cs8209.cs b/mcs/errors/cs8209.cs
new file mode 100644
index 00000000000..3a46a206c8e
--- /dev/null
+++ b/mcs/errors/cs8209.cs
@@ -0,0 +1,10 @@
+// CS8209: Cannot assign void to a discard
+// Line: 8
+
+class C
+{
+	public static void Main ()
+	{
+		_ = Main ();
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs8310.cs b/mcs/errors/cs8310.cs
new file mode 100644
index 00000000000..134624c03b7
--- /dev/null
+++ b/mcs/errors/cs8310.cs
@@ -0,0 +1,11 @@
+// CS8310: Operator `+' cannot be applied to operand `default'
+// Line: 9
+// Compiler options: -langversion:latest
+
+class C
+{
+	static void Main ()
+	{
+		int h = 1 + default;
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs8311.cs b/mcs/errors/cs8311.cs
new file mode 100644
index 00000000000..5b35229442d
--- /dev/null
+++ b/mcs/errors/cs8311.cs
@@ -0,0 +1,12 @@
+// CS8311: Cannot use a default literal as an argument to a dynamically dispatched operation
+// Line: 10
+// Compiler options: -langversion:latest
+
+class C
+{
+    static void Main ()
+    {
+        dynamic d = null;
+        d.M2 (default);
+    }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs8312.cs b/mcs/errors/cs8312.cs
new file mode 100644
index 00000000000..d2ad3f52f02
--- /dev/null
+++ b/mcs/errors/cs8312.cs
@@ -0,0 +1,12 @@
+// CS8312: Use of default literal is not valid in this context
+// Line: 9
+// Compiler options: -langversion:latest
+
+class C
+{
+	static void Main ()
+	{
+		foreach (var x in default) {
+		}
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs8315.cs b/mcs/errors/cs8315.cs
new file mode 100644
index 00000000000..c40bf8613b4
--- /dev/null
+++ b/mcs/errors/cs8315.cs
@@ -0,0 +1,11 @@
+// CS8315: Operator `==' is ambiguous on operands `default' and `default'
+// Line: 9
+// Compiler options: -langversion:latest
+
+class C
+{
+	static void Main ()
+	{
+		bool d = default == default;
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs8323.cs b/mcs/errors/cs8323.cs
new file mode 100644
index 00000000000..c6c9309ec0d
--- /dev/null
+++ b/mcs/errors/cs8323.cs
@@ -0,0 +1,15 @@
+// CS8323: Named argument `str' is used out of position but is followed by positional argument
+// Line: 9
+// Compiler options: -langversion:7.2
+
+class X
+{
+	public static void Main ()
+	{
+		Test (str: "", "");
+	}
+
+	static void Test (int arg, string str)
+	{
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs8324.cs b/mcs/errors/cs8324.cs
new file mode 100644
index 00000000000..8a0be1aefb9
--- /dev/null
+++ b/mcs/errors/cs8324.cs
@@ -0,0 +1,12 @@
+// CS8324: Named argument specifications must appear after all fixed arguments have been specified in a dynamic invocation
+// Line: 10
+// Compiler options: -langversion:7.2
+
+class C
+{
+	void M ()
+	{
+		dynamic d = new object ();
+		d.M (arg: 1, "");
+	}
+}
\ No newline at end of file
diff --git a/mcs/errors/cs8343.cs b/mcs/errors/cs8343.cs
new file mode 100644
index 00000000000..b6aa8e83a09
--- /dev/null
+++ b/mcs/errors/cs8343.cs
@@ -0,0 +1,12 @@
+// CS8343: `S': ref structs cannot implement interfaces
+// Line: 7
+// Compiler options: -langversion:latest
+
+using System;
+
+public ref struct S : IDisposable
+{
+	public void Dispose ()
+	{			
+	}
+}
diff --git a/mcs/errors/cs8345-2.cs b/mcs/errors/cs8345-2.cs
new file mode 100644
index 00000000000..3f6137b1b56
--- /dev/null
+++ b/mcs/errors/cs8345-2.cs
@@ -0,0 +1,12 @@
+// CS8345: Field or auto-implemented property cannot be of type `S' unless it is an instance member of a ref struct
+// Line: 11
+// Compiler options: -langversion:latest
+
+public ref struct S
+{
+}
+
+ref struct Test
+{
+	static S field;
+}
\ No newline at end of file
diff --git a/mcs/errors/cs8345.cs b/mcs/errors/cs8345.cs
new file mode 100644
index 00000000000..0b5bd05518f
--- /dev/null
+++ b/mcs/errors/cs8345.cs
@@ -0,0 +1,12 @@
+// CS8345: Field or auto-implemented property cannot be of type `S' unless it is an instance member of a ref struct
+// Line: 11
+// Compiler options: -langversion:latest
+
+public ref struct S
+{
+}
+
+struct Test
+{
+	S field;
+}
\ No newline at end of file
diff --git a/mcs/errors/cs8346.cs b/mcs/errors/cs8346.cs
new file mode 100644
index 00000000000..58e22a2ae7f
--- /dev/null
+++ b/mcs/errors/cs8346.cs
@@ -0,0 +1,13 @@
+// CS8346: Cannot convert a stackalloc expression of type `byte' to type `System.Span<int>'
+// Line: 11
+// Compiler options: -langversion:7.2
+
+using System;
+
+class X
+{
+	public static void Main ()
+	{
+		Span<int> stackSpan = stackalloc byte[1];
+	}
+}
\ No newline at end of file
diff --git a/mcs/mcs/argument.cs b/mcs/mcs/argument.cs
index 8421b4dfbfc..5b1003dbadf 100644
--- a/mcs/mcs/argument.cs
+++ b/mcs/mcs/argument.cs
@@ -106,11 +106,6 @@ namespace Mono.CSharp
 
 		public virtual Expression CreateExpressionTree (ResolveContext rc)
 		{
-			if (Type.Kind == MemberKind.ByRef) {
-				rc.Report.Error (8153, Expr.Location, "An expression tree lambda cannot contain a call to a method, property, or indexer that returns by reference");
-				return null;
-			}
-
 			if (ArgType == AType.Default)
 				rc.Report.Error (854, Expr.Location, "An expression tree cannot contain an invocation which uses optional parameter");
 
diff --git a/mcs/mcs/assign.cs b/mcs/mcs/assign.cs
index a07c8c0ef39..596623feae4 100644
--- a/mcs/mcs/assign.cs
+++ b/mcs/mcs/assign.cs
@@ -391,9 +391,21 @@ namespace Mono.CSharp {
 			return System.Linq.Expressions.Expression.Assign (target_object, source_object);
 		}
 
-		protected virtual Expression ResolveConversions (ResolveContext ec)
+		protected virtual Expression ResolveConversions (ResolveContext rc)
 		{
-			source = Convert.ImplicitConversionRequired (ec, source, target.Type, source.Location);
+			var ttype = target.Type;
+			var stackAlloc = source as StackAlloc;
+			if (stackAlloc != null && ttype.Arity == 1 && ttype.GetDefinition () == rc.Module.PredefinedTypes.SpanGeneric.TypeSpec &&
+			    rc.Module.Compiler.Settings.Version >= LanguageVersion.V_7_2) {
+
+				var etype = ttype.TypeArguments [0];
+				var stype = ((PointerContainer)source.Type).Element;
+				if (etype == stype && stackAlloc.ResolveSpanConversion (rc, ttype)) {
+					return this;
+				}
+			}
+
+			source = Convert.ImplicitConversionRequired (rc, source, ttype, source.Location);
 			if (source == null)
 				return null;
 
diff --git a/mcs/mcs/async.cs b/mcs/mcs/async.cs
index fd6499346e8..643aed5e568 100644
--- a/mcs/mcs/async.cs
+++ b/mcs/mcs/async.cs
@@ -628,58 +628,112 @@ namespace Mono.CSharp
 
 		protected override bool DoDefineMembers ()
 		{
-			PredefinedType builder_type;
-			PredefinedMember<MethodSpec> bf;
-			PredefinedMember<MethodSpec> bs;
-			PredefinedMember<MethodSpec> sr;
-			PredefinedMember<MethodSpec> se;
-			PredefinedMember<MethodSpec> sm;
+			TypeSpec bt;
 			bool has_task_return_type = false;
-			var pred_members = Module.PredefinedMembers;
+			var istate_machine = Module.PredefinedTypes.IAsyncStateMachine;
+			MethodSpec set_statemachine;
 
-			if (return_type.Kind == MemberKind.Void) {
-				builder_type = Module.PredefinedTypes.AsyncVoidMethodBuilder;
-				bf = pred_members.AsyncVoidMethodBuilderCreate;
-				bs = pred_members.AsyncVoidMethodBuilderStart;
-				sr = pred_members.AsyncVoidMethodBuilderSetResult;
-				se = pred_members.AsyncVoidMethodBuilderSetException;
-				sm = pred_members.AsyncVoidMethodBuilderSetStateMachine;
-			} else if (return_type == Module.PredefinedTypes.Task.TypeSpec) {
-				builder_type = Module.PredefinedTypes.AsyncTaskMethodBuilder;
-				bf = pred_members.AsyncTaskMethodBuilderCreate;
-				bs = pred_members.AsyncTaskMethodBuilderStart;
-				sr = pred_members.AsyncTaskMethodBuilderSetResult;
-				se = pred_members.AsyncTaskMethodBuilderSetException;
-				sm = pred_members.AsyncTaskMethodBuilderSetStateMachine;
-				task = pred_members.AsyncTaskMethodBuilderTask.Get ();
+			if (return_type.IsCustomTaskType ()) {
+				//
+				// TODO: Would be nice to cache all this on per-type basis
+				//
+				var btypes = Compiler.BuiltinTypes;
+				bt = return_type.MemberDefinition.GetAsyncMethodBuilder ();
+				TypeSpec bt_inflated;
+				if (return_type.IsGeneric) {
+					bt_inflated = bt.MakeGenericType (Module, bt.MemberDefinition.TypeParameters);
+				} else {
+					bt_inflated = bt;
+				}
+
+				var set_result_sign = MemberFilter.Method ("SetResult", 0, ParametersCompiled.CreateFullyResolved (bt.MemberDefinition.TypeParameters), btypes.Void);
+				set_result = new PredefinedMember<MethodSpec> (Module, bt, set_result_sign).Resolve (Location);
+
+				var set_exception_sign = MemberFilter.Method ("SetException", 0, ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void);
+				set_exception = new PredefinedMember<MethodSpec> (Module, bt, set_exception_sign).Resolve (Location);
+
+				var builder_factory_sign = MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, bt_inflated);
+				builder_factory = new PredefinedMember<MethodSpec> (Module, bt, builder_factory_sign).Resolve (Location);
+				if (builder_factory?.IsStatic == false)
+					throw new NotImplementedException ("report better error message");
+
+				var builder_start_sign = MemberFilter.Method ("Start", 1, new ParametersImported (
+						new [] {
+								new ParameterData (null, Parameter.Modifier.REF),
+							},
+						new [] {
+								new TypeParameterSpec (0, null, SpecialConstraint.None, Variance.None, null),
+							}, false),
+					btypes.Void);
+				builder_start = new PredefinedMember<MethodSpec> (Module, bt, builder_start_sign).Resolve (Location);
+
+				if (!istate_machine.Define ())
+					return false;
+
+				var set_statemachine_sign = MemberFilter.Method ("SetStateMachine", 0, ParametersCompiled.CreateFullyResolved (istate_machine.TypeSpec), btypes.Void);
+				set_statemachine = new PredefinedMember<MethodSpec> (Module, bt, set_statemachine_sign).Resolve (Location); ;
+
+				var task_sign = MemberFilter.Property ("Task", return_type.MemberDefinition as TypeSpec);
+				task = new PredefinedMember<PropertySpec> (Module, bt, task_sign).Resolve (Location);
+
+				if (set_result == null || set_exception == null || builder_factory == null || builder_start == null || set_statemachine == null || task == null ||
+					!Module.PredefinedTypes.INotifyCompletion.Define ()) {
+					return false;
+				}
+
+				has_task_return_type = return_type.IsGeneric;
 			} else {
-				builder_type = Module.PredefinedTypes.AsyncTaskMethodBuilderGeneric;
-				bf = pred_members.AsyncTaskMethodBuilderGenericCreate;
-				bs = pred_members.AsyncTaskMethodBuilderGenericStart;
-				sr = pred_members.AsyncTaskMethodBuilderGenericSetResult;
-				se = pred_members.AsyncTaskMethodBuilderGenericSetException;
-				sm = pred_members.AsyncTaskMethodBuilderGenericSetStateMachine;
-				task = pred_members.AsyncTaskMethodBuilderGenericTask.Get ();
-				has_task_return_type = true;
-			}
+				PredefinedType builder_type;
+				PredefinedMember<MethodSpec> bf;
+				PredefinedMember<MethodSpec> bs;
+				PredefinedMember<MethodSpec> sr;
+				PredefinedMember<MethodSpec> se;
+				PredefinedMember<MethodSpec> sm;
+				var pred_members = Module.PredefinedMembers;
+
+				if (return_type.Kind == MemberKind.Void) {
+					builder_type = Module.PredefinedTypes.AsyncVoidMethodBuilder;
+					bf = pred_members.AsyncVoidMethodBuilderCreate;
+					bs = pred_members.AsyncVoidMethodBuilderStart;
+					sr = pred_members.AsyncVoidMethodBuilderSetResult;
+					se = pred_members.AsyncVoidMethodBuilderSetException;
+					sm = pred_members.AsyncVoidMethodBuilderSetStateMachine;
+				} else if (return_type == Module.PredefinedTypes.Task.TypeSpec) {
+					builder_type = Module.PredefinedTypes.AsyncTaskMethodBuilder;
+					bf = pred_members.AsyncTaskMethodBuilderCreate;
+					bs = pred_members.AsyncTaskMethodBuilderStart;
+					sr = pred_members.AsyncTaskMethodBuilderSetResult;
+					se = pred_members.AsyncTaskMethodBuilderSetException;
+					sm = pred_members.AsyncTaskMethodBuilderSetStateMachine;
+					task = pred_members.AsyncTaskMethodBuilderTask.Get ();
+				} else {
+					builder_type = Module.PredefinedTypes.AsyncTaskMethodBuilderGeneric;
+					bf = pred_members.AsyncTaskMethodBuilderGenericCreate;
+					bs = pred_members.AsyncTaskMethodBuilderGenericStart;
+					sr = pred_members.AsyncTaskMethodBuilderGenericSetResult;
+					se = pred_members.AsyncTaskMethodBuilderGenericSetException;
+					sm = pred_members.AsyncTaskMethodBuilderGenericSetStateMachine;
+					task = pred_members.AsyncTaskMethodBuilderGenericTask.Get ();
+					has_task_return_type = true;
+				}
 
-			set_result = sr.Get ();
-			set_exception = se.Get ();
-			builder_factory = bf.Get ();
-			builder_start = bs.Get ();
+				set_result = sr.Get ();
+				set_exception = se.Get ();
+				builder_factory = bf.Get ();
+				builder_start = bs.Get ();
 
-			var istate_machine = Module.PredefinedTypes.IAsyncStateMachine;
-			var set_statemachine = sm.Get ();
-
-			if (!builder_type.Define () || !istate_machine.Define () || set_result == null || builder_factory == null ||
-				set_exception == null || set_statemachine == null || builder_start == null ||
-				!Module.PredefinedTypes.INotifyCompletion.Define ()) {
-				Report.Error (1993, Location,
-					"Cannot find compiler required types for asynchronous functions support. Are you targeting the wrong framework version?");
-				return base.DoDefineMembers ();
-			}
+				set_statemachine = sm.Get ();
+
+				if (!builder_type.Define () || !istate_machine.Define () || set_result == null || builder_factory == null ||
+					set_exception == null || set_statemachine == null || builder_start == null ||
+					!Module.PredefinedTypes.INotifyCompletion.Define ()) {
+					Report.Error (1993, Location,
+						"Cannot find compiler required types for asynchronous functions support. Are you targeting the wrong framework version?");
+					return base.DoDefineMembers ();
+				}
 
-			var bt = builder_type.TypeSpec;
+				bt = builder_type.TypeSpec;
+			}
 
 			//
 			// Inflate generic Task types
@@ -825,9 +879,26 @@ namespace Mono.CSharp
 				predefined = unsafeVersion ? pm.AsyncVoidMethodBuilderOnCompletedUnsafe : pm.AsyncVoidMethodBuilderOnCompleted;
 			} else if (return_type == Module.PredefinedTypes.Task.TypeSpec) {
 				predefined = unsafeVersion ? pm.AsyncTaskMethodBuilderOnCompletedUnsafe : pm.AsyncTaskMethodBuilderOnCompleted;
-			} else {
+			} else if (return_type.IsGenericTask) {
 				predefined = unsafeVersion ? pm.AsyncTaskMethodBuilderGenericOnCompletedUnsafe : pm.AsyncTaskMethodBuilderGenericOnCompleted;
 				has_task_return_type = true;
+			} else {
+				var parameters = new ParametersImported (
+					new [] {
+								new ParameterData (null, Parameter.Modifier.REF),
+								new ParameterData (null, Parameter.Modifier.REF)
+						},
+					new [] {
+								new TypeParameterSpec (0, null, SpecialConstraint.None, Variance.None, null),
+								new TypeParameterSpec (1, null, SpecialConstraint.None, Variance.None, null)
+					}, false);
+
+				var on_completed_sign = unsafeVersion ?
+					MemberFilter.Method ("AwaitUnsafeOnCompleted", 2, parameters, Compiler.BuiltinTypes.Void) :
+				    MemberFilter.Method ("AwaitOnCompleted", 2, parameters, Compiler.BuiltinTypes.Void);
+				
+				predefined = new PredefinedMember<MethodSpec> (Module, return_type.MemberDefinition.GetAsyncMethodBuilder (), on_completed_sign);
+				has_task_return_type = return_type.IsGeneric;
 			}
 
 			var on_completed = predefined.Resolve (Location);
@@ -887,11 +958,14 @@ namespace Mono.CSharp
 			// stateMachine.$builder.Start<{storey-type}>(ref stateMachine);
 			//
 			instance.AddressOf (ec, AddressOp.Store);
-			ec.Emit (OpCodes.Ldflda, builder_field);
+
+			bool struct_builder = builder.MemberType.IsStruct;
+
+			ec.Emit (struct_builder ? OpCodes.Ldflda : OpCodes.Ldfld, builder_field);
 			if (Task != null)
 				ec.Emit (OpCodes.Dup);
 			instance.AddressOf (ec, AddressOp.Store);
-			ec.Emit (OpCodes.Call, builder_start.MakeGenericMethod (Module, instance.Type));
+			ec.Emit (struct_builder ? OpCodes.Call : OpCodes.Callvirt, builder_start.MakeGenericMethod (Module, instance.Type));
 
 			//
 			// Emits return stateMachine.$builder.Task;
@@ -1029,4 +1103,20 @@ namespace Mono.CSharp
 			EmitAssign (ec, new NullConstant (type, loc), false, false);
 		}
 	}
+
+	static class TypeSpecAsyncExtensions
+	{
+		public static bool IsCustomTaskType (this TypeSpec type)
+		{
+			// LAMESPEC: Arity is not mentioned
+			if (type.Arity > 1)
+				return false;
+			
+			var amb = type.MemberDefinition.GetAsyncMethodBuilder ();
+			if (amb == null)
+				return false;
+
+			return amb.Arity == type.Arity;
+		}
+	}
 }
diff --git a/mcs/mcs/attribute.cs b/mcs/mcs/attribute.cs
index 3ff2d68ccb5..83d403118ad 100644
--- a/mcs/mcs/attribute.cs
+++ b/mcs/mcs/attribute.cs
@@ -789,6 +789,17 @@ namespace Mono.CSharp {
 			return ((BoolConstant) pos_args[0].Expr).Value;
 		}
 
+		public TypeSpec GetAsyncMethodBuilderValue ()
+		{
+			if (!arg_resolved)
+				Resolve ();
+
+			if (resolve_error)
+				return null;
+
+			return GetArgumentType ();
+		}
+
 		public TypeSpec GetCoClassAttributeValue ()
 		{
 			if (!arg_resolved)
@@ -1754,9 +1765,11 @@ namespace Mono.CSharp {
 
 		// New in .NET 4.7
 		public readonly PredefinedTupleElementNamesAttribute TupleElementNames;
+		public readonly PredefinedAttribute AsyncMethodBuilder;
 
 		// New in .NET 4.7.1
 		public readonly PredefinedAttribute IsReadOnly;
+		public readonly PredefinedAttribute IsByRefLike;
 
 		//
 		// Optional types which are used as types and for member lookup
@@ -1837,8 +1850,10 @@ namespace Mono.CSharp {
 			CallerLineNumberAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerLineNumberAttribute");
 			CallerFilePathAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerFilePathAttribute");
 
+			AsyncMethodBuilder = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "AsyncMethodBuilderAttribute");
 			TupleElementNames = new PredefinedTupleElementNamesAttribute (module, "System.Runtime.CompilerServices", "TupleElementNamesAttribute");
 			IsReadOnly = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "IsReadOnlyAttribute");
+			IsByRefLike = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "IsByRefLikeAttribute");
 
 			// TODO: Should define only attributes which are used for comparison
 			const System.Reflection.BindingFlags all_fields = System.Reflection.BindingFlags.Public |
diff --git a/mcs/mcs/class.cs b/mcs/mcs/class.cs
index 9afb32c6fe5..6b1adc297a3 100644
--- a/mcs/mcs/class.cs
+++ b/mcs/mcs/class.cs
@@ -224,6 +224,24 @@ namespace Mono.CSharp
 			}
 		}
 
+		public void CloseContainerEarlyForReflectionEmit ()
+		{
+			if (containers != null) {
+				foreach (TypeContainer tc in containers) {
+					//
+					// SRE requires due to internal checks that any field of enum type is
+					// baked. We close all enum types before closing any other types to
+					// workaround this limitation
+					//
+					if (tc.Kind == MemberKind.Enum) {
+						tc.CloseContainer ();
+					} else {
+						tc.CloseContainerEarlyForReflectionEmit ();
+					}
+				}
+			}
+		}
+
 		public virtual void CreateMetadataName (StringBuilder sb)
 		{
 			if (Parent != null && Parent.MemberName != null)
@@ -1102,6 +1120,18 @@ namespace Mono.CSharp
 				member.GenerateDocComment (builder);
 		}
 
+		public TypeSpec GetAsyncMethodBuilder ()
+		{
+			if (OptAttributes == null)
+				return null;
+
+			Attribute a = OptAttributes.Search (Module.PredefinedAttributes.AsyncMethodBuilder);
+			if (a == null)
+				return null;
+
+			return a.GetAsyncMethodBuilderValue ();
+		}
+
 		public TypeSpec GetAttributeCoClass ()
 		{
 			if (OptAttributes == null)
@@ -2171,7 +2201,7 @@ namespace Mono.CSharp
 
 		public override void Emit ()
 		{
-			if (Interfaces != null) {
+			if (Interfaces != null && (ModFlags & Modifiers.PRIVATE) == 0) {
 				foreach (var iface in Interfaces) {
 					if (iface.HasNamedTupleElement) {
 						throw new NotImplementedException ("named tuples for .interfaceimpl");
@@ -3023,7 +3053,8 @@ namespace Mono.CSharp
 			Modifiers.INTERNAL  |
 			Modifiers.UNSAFE    |
 			Modifiers.PRIVATE   |
-			Modifiers.READONLY;
+			Modifiers.READONLY  |
+			Modifiers.REF;
 
 		public Struct (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
 			: base (parent, name, attrs, MemberKind.Struct)
@@ -3139,6 +3170,9 @@ namespace Mono.CSharp
 			if ((ModFlags & Modifiers.READONLY) != 0)
 				Module.PredefinedAttributes.IsReadOnly.EmitAttribute (TypeBuilder);
 
+			if ((ModFlags & Modifiers.REF) != 0)
+				Module.PredefinedAttributes.IsByRefLike.EmitAttribute (TypeBuilder);
+
 			CheckStructCycles ();
 
 			base.Emit ();
@@ -3213,6 +3247,10 @@ namespace Mono.CSharp
 		protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
 		{
 			var ifaces = base.ResolveBaseTypes (out base_class);
+			if (ifaces != null && (ModFlags & Modifiers.REF) != 0) {
+				Report.Error (8343, Location, "`{0}': ref structs cannot implement interfaces", GetSignatureForError ());
+			}
+
 			base_type = Compiler.BuiltinTypes.ValueType;
 			return ifaces;
 		}
@@ -3915,7 +3953,7 @@ namespace Mono.CSharp
 
 		protected void IsTypePermitted ()
 		{
-			if (MemberType.IsSpecialRuntimeType) {
+			if (MemberType.IsSpecialRuntimeType || MemberType.IsByRefLike) {
 				if (Parent is StateMachine) {
 					Report.Error (4012, Location,
 						"Parameters or local variables of type `{0}' cannot be declared in async methods or iterators",
@@ -3924,6 +3962,19 @@ namespace Mono.CSharp
 					Report.Error (4013, Location,
 						"Local variables of type `{0}' cannot be used inside anonymous methods, lambda expressions or query expressions",
 						MemberType.GetSignatureForError ());
+				} else if (MemberType.IsByRefLike) {
+					if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
+						return;
+
+					if ((ModFlags & Modifiers.AutoProperty) == 0 && this is Property)
+						return;
+
+					if ((ModFlags & Modifiers.STATIC) == 0 && (Parent.ModFlags & Modifiers.REF) != 0)
+						return;
+
+					Report.Error (8345, Location,
+						"Field or auto-implemented property cannot be of type `{0}' unless it is an instance member of a ref struct",
+						MemberType.GetSignatureForError ());
 				} else {
 					Report.Error (610, Location, 
 						"Field or property cannot be of type `{0}'", MemberType.GetSignatureForError ());
diff --git a/mcs/mcs/const.cs b/mcs/mcs/const.cs
index 046aec24c1b..658f15ec57a 100644
--- a/mcs/mcs/const.cs
+++ b/mcs/mcs/const.cs
@@ -206,7 +206,9 @@ namespace Mono.CSharp {
 					c = field.ConvertInitializer (rc, c);
 
 				if (c == null) {
-					if (TypeSpec.IsReferenceType (field.MemberType))
+					if (expr is DefaultLiteralExpression) {
+						// It's handled bellow in New.Constantify
+					} else if (TypeSpec.IsReferenceType (field.MemberType))
 						Error_ConstantCanBeInitializedWithNullOnly (rc, field.MemberType, expr.Location, GetSignatureForError ());
 					else if (!(expr is Constant))
 						Error_ExpressionMustBeConstant (rc, expr.Location, GetSignatureForError ());
diff --git a/mcs/mcs/convert.cs b/mcs/mcs/convert.cs
index b11477c1043..ae153fc49e8 100644
--- a/mcs/mcs/convert.cs
+++ b/mcs/mcs/convert.cs
@@ -392,6 +392,9 @@ namespace Mono.CSharp {
 				if (!TypeSpec.IsValueType (expr_type))
 					return null;
 
+				if (expr_type.IsByRefLike)
+					return null;
+
 				return expr == null ? EmptyExpression.Null : new BoxedCast (expr, target_type);
 
 			case BuiltinTypeSpec.Type.Enum:
@@ -816,7 +819,7 @@ namespace Mono.CSharp {
 			if (expr_type == target_type)
 				return true;
 
-			if (expr_type == InternalType.ThrowExpr)
+			if (expr_type == InternalType.ThrowExpr || expr_type == InternalType.DefaultType)
 				return target_type.Kind != MemberKind.InternalCompilerType;
 
 			if (target_type.IsNullableType)
@@ -1478,6 +1481,10 @@ namespace Mono.CSharp {
 				return target_type.Kind == MemberKind.InternalCompilerType ? null : EmptyCast.Create (expr, target_type);
 			}
 
+			if (expr_type == InternalType.DefaultType) {
+				return new DefaultValueExpression (new TypeExpression (target_type, expr.Location), expr.Location).Resolve (ec);
+			}
+
 			if (target_type.IsNullableType)
 				return ImplicitNulableConversion (ec, expr, target_type);
 
@@ -1967,7 +1974,7 @@ namespace Mono.CSharp {
 			// From object or dynamic to any reference type or value type (unboxing)
 			//
 			if (source_type.BuiltinType == BuiltinTypeSpec.Type.Object || source_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
-				if (target_type.IsPointer)
+				if (target_type.IsPointer || target_type.IsByRefLike)
 					return null;
 
 				return
diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay
index 2868d2fd8f6..4d6fcb44c0d 100644
--- a/mcs/mcs/cs-parser.jay
+++ b/mcs/mcs/cs-parser.jay
@@ -169,7 +169,8 @@ namespace Mono.CSharp
 %token CONST	
 %token CONTINUE	
 %token DECIMAL	
-%token DEFAULT	
+%token DEFAULT
+%token DEFAULT_VALUE
 %token DELEGATE	
 %token DO	
 %token DOUBLE	
@@ -336,6 +337,7 @@ namespace Mono.CSharp
 %token DEFAULT_COLON
 %token OPEN_BRACKET_EXPR
 %token OPEN_PARENS_DECONSTRUCT
+%token REF_STRUCT
 
 // Make the parser go into eval mode parsing (statements and compilation units).
 %token EVAL_STATEMENT_PARSER
@@ -863,7 +865,7 @@ attribute_arguments
 		}
 		
 		Arguments args = ((Arguments) o [0]);
-		if (args.Count > 0 && !($3 is NamedArgument) && args [args.Count - 1] is NamedArgument)
+		if (lang_version < LanguageVersion.V_7_2 && args.Count > 0 && !($3 is NamedArgument) && args [args.Count - 1] is NamedArgument)
 			Error_NamedArgumentExpected ((NamedArgument) args [args.Count - 1]);
 		
 		args.Add ((Argument) $3);
@@ -1015,17 +1017,34 @@ primary_constructor_body
 	  }
 	;
 
+struct_keyword
+	: STRUCT
+	  {
+		$$ = null;
+	  }
+	| REF_STRUCT
+	  {
+		if (lang_version < LanguageVersion.V_7_2) {
+			FeatureIsNotAvailable (GetLocation ($1), "ref structs");
+		}
+
+		$$ = this;
+	  }
+	;
+
 struct_declaration
 	: opt_attributes
 	  opt_modifiers
 	  opt_partial
-	  STRUCT
+	  struct_keyword
 	  type_declaration_name
 	  {
 		var mods = (Modifiers) $2;
 		if ((mods & Modifiers.READONLY) != 0 && lang_version < LanguageVersion.V_7_2) {
 			FeatureIsNotAvailable (GetLocation ($4), "readonly structs");
 		}
+		if ($4 != null)
+			mods |= Modifiers.REF;
 
 		lexer.ConstraintsParsing = true;
 		valid_param_mod = ParameterModifierType.PrimaryConstructor;
@@ -1071,7 +1090,7 @@ struct_declaration
 		}
 		$$ = pop_current_class ();
 	  }
-	| opt_attributes opt_modifiers opt_partial STRUCT error
+	| opt_attributes opt_modifiers opt_partial struct_keyword error
 	  {
 		Error_SyntaxError (yyToken);
 	  }
@@ -1384,6 +1403,18 @@ ref_member_type
 
 		$$ = new ReferenceTypeExpr ((FullNamedExpression) $3, GetLocation ($1));
 	  }
+	| REF READONLY
+	  {
+		lexer.parsing_generic_declaration = true;
+	  }
+	  type
+	  {
+		if (lang_version < LanguageVersion.V_7_2) {
+			FeatureIsNotAvailable (GetLocation ($2), "readonly references");
+		}
+
+		$$ = new ReferenceTypeExpr ((FullNamedExpression) $4, true, GetLocation ($1));
+	  }
 	;
 
 method_header
@@ -3448,6 +3479,7 @@ primary_expression
 	| anonymous_method_expression
 	| undocumented_expressions
 	| interpolated_string
+	| default_literal
 	;
 
 type_name_expression
@@ -3824,7 +3856,7 @@ argument_list
 	| argument_list COMMA argument
 	  {
 		Arguments list = (Arguments) $1;
-		if (list [list.Count - 1] is NamedArgument)
+		if (lang_version < LanguageVersion.V_7_2 && list [list.Count - 1] is NamedArgument)
 			Error_NamedArgumentExpected ((NamedArgument) list [list.Count - 1]);
 		
 		list.Add ((Argument) $3);
@@ -3969,7 +4001,7 @@ expression_list_arguments
 	| expression_list_arguments COMMA expression_list_argument
 	  {
 		Arguments args = (Arguments) $1;
-		if (args [args.Count - 1] is NamedArgument && !($3 is NamedArgument))
+		if (lang_version < LanguageVersion.V_7_2 && args [args.Count - 1] is NamedArgument && !($3 is NamedArgument))
 			Error_NamedArgumentExpected ((NamedArgument) args [args.Count - 1]);
 	  
 		args.Add ((Argument) $3);
@@ -4386,7 +4418,7 @@ anonymous_method_signature
 	;
 
 default_value_expression
-	: DEFAULT open_parens_any type CLOSE_PARENS
+	: DEFAULT_VALUE open_parens_any type CLOSE_PARENS
 	  {
 		if (lang_version < LanguageVersion.ISO_2)
 			FeatureIsNotAvailable (GetLocation ($1), "default value expression");
@@ -4396,6 +4428,16 @@ default_value_expression
 	  }
 	;
 
+default_literal
+	: DEFAULT
+	  {
+		if (lang_version < LanguageVersion.V_7_1)
+			FeatureIsNotAvailable (GetLocation ($1), "default literal");
+
+		$$ = new DefaultLiteralExpression (GetLocation ($1));
+	  }
+	;
+
 unary_expression
 	: primary_expression
 	| BANG prefixed_unary_expression
@@ -4750,7 +4792,7 @@ pattern_list
 	| pattern_list COMMA pattern_argument
 	  {
 		Arguments args = (Arguments) $1;
-		if (args [args.Count - 1] is NamedArgument && !($3 is NamedArgument))
+		if (lang_version < LanguageVersion.V_7_2 && args [args.Count - 1] is NamedArgument && !($3 is NamedArgument))
 			Error_NamedArgumentExpected ((NamedArgument) args [args.Count - 1]);
 
 		args.Add ((Argument) $3);
@@ -5067,17 +5109,25 @@ assignment_expression
 		$$ = new CompoundAssign (Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
 		lbag.AddLocation ($$, GetLocation ($2));
 	  }
-	| OPEN_PARENS_DECONSTRUCT deconstruct_exprs CLOSE_PARENS ASSIGN expression
+	| OPEN_PARENS_DECONSTRUCT deconstruct_assignment CLOSE_PARENS ASSIGN expression
 	  {
 		if (lang_version < LanguageVersion.V_7)
 			FeatureIsNotAvailable (GetLocation ($1), "tuples");
 
-	  	var exprs = (List<Expression>) $2;
+		var exprs = (List<Expression>) $2;
+		$$ = new TupleDeconstruct (exprs, (Expression) $5, GetLocation ($4));
+	  }
+	| OPEN_PARENS_DECONSTRUCT deconstruct_declaration CLOSE_PARENS ASSIGN expression
+	  {
+		if (lang_version < LanguageVersion.V_7)
+			FeatureIsNotAvailable (GetLocation ($1), "tuples");
+
+		var exprs = (List<BlockVariable>) $2;
 		$$ = new TupleDeconstruct (exprs, (Expression) $5, GetLocation ($4));
 	  }
 	;
 
-deconstruct_exprs
+deconstruct_assignment
 	: expression COMMA expression
 	  {
 		$$ = new List<Expression> () {
@@ -5085,7 +5135,7 @@ deconstruct_exprs
 			(Expression) $3
 	  	};
 	  }
-	| deconstruct_exprs COMMA expression
+	| deconstruct_assignment COMMA expression
 	  {
 		var src = (List<Expression>) $1;
 		src.Add ((Expression) $3);
@@ -5093,6 +5143,43 @@ deconstruct_exprs
 	  }
 	;
 
+deconstruct_declaration
+	: variable_type identifier_inside_body
+	  {
+		var lt = (LocatedToken) $2;
+		var li = new LocalVariable (current_block, lt.Value, lt.Location);
+		current_block.AddLocalName (li);
+		$$ = new List<BlockVariable> (2) {
+			new BlockVariable ((FullNamedExpression) $1, li)
+		};
+	  }
+	| deconstruct_declaration COMMA variable_type identifier_inside_body
+	  {
+		var lt = (LocatedToken) $4;
+		var li = new LocalVariable (current_block, lt.Value, lt.Location);
+		current_block.AddLocalName (li);
+
+		var src = (List<BlockVariable>) $1;
+		src.Add (new BlockVariable ((FullNamedExpression) $3, li));
+		$$ = src;
+	  }
+	| deconstruct_declaration COMMA identifier_inside_body
+	  {
+		var lt = (LocatedToken) $3;
+		var li = new LocalVariable (current_block, lt.Value, lt.Location);
+
+		if (lt.Value != "_") {
+			report.Error (8184, lt.Location, "A deconstruction cannot mix declarations and expressions on the left-hand-side");
+		} else {
+			li.Type = InternalType.Discard;
+		}
+
+		var src = (List<BlockVariable>) $1;
+		src.Add (new BlockVariable (new TypeExpression (li.Type, lt.Location), li));
+		$$ = src;
+	  }
+	;
+
 lambda_parameter_list
 	: lambda_parameter
 	  {
@@ -6008,6 +6095,28 @@ block_variable_declaration
 			lbag.AddLocation ($$, GetLocation ($7));
 		}
 	  }
+	| REF READONLY variable_type identifier_inside_body
+	  {
+		if (lang_version < LanguageVersion.V_7_2) {
+			FeatureIsNotAvailable (GetLocation ($2), "readonly references");
+		}
+
+		var lt = (LocatedToken) $4;
+		var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ByRef | LocalVariable.Flags.ReadonlyMask, lt.Location);
+		current_block.AddLocalName (li);
+		current_variable = new BlockVariable ((FullNamedExpression) $3, li);
+	  }
+	  opt_local_variable_initializer opt_variable_declarators SEMICOLON
+	  {
+		$$ = current_variable;
+		current_variable = null;
+		if ($6 != null) {
+			lbag.AddLocation ($$, PopLocation (), GetLocation ($8));
+		} else {
+			report.Error (8174, GetLocation ($3), "A declaration of a by-reference variable must have an initializer");
+			lbag.AddLocation ($$, GetLocation ($8));
+		}
+	  }
 	;
 
 opt_local_variable_initializer
@@ -7731,7 +7840,7 @@ void Warning_EmptyStatement (Location loc)
 
 void Error_NamedArgumentExpected (NamedArgument a)
 {
-	report.Error (1738, a.Location, "Named arguments must appear after the positional arguments");
+	report.Error (1738, a.Location, "Named arguments must appear after the positional arguments when using language version older than 7.2");
 }
 
 void Error_MissingInitializer (Location loc)
@@ -8255,6 +8364,7 @@ static string GetTokenName (int token)
 	case Token.CONTINUE:
 		return "continue";
 	case Token.DEFAULT:
+	case Token.DEFAULT_VALUE:
 		return "default";
 	case Token.DELEGATE:
 		return "delegate";
@@ -8334,6 +8444,7 @@ static string GetTokenName (int token)
 	case Token.STATIC:
 		return "static";
 	case Token.STRUCT:
+	case Token.REF_STRUCT:
 		return "struct";
 	case Token.SWITCH:
 		return "switch";
diff --git a/mcs/mcs/cs-tokenizer.cs b/mcs/mcs/cs-tokenizer.cs
index d6d00d31400..37edb5c1224 100644
--- a/mcs/mcs/cs-tokenizer.cs
+++ b/mcs/mcs/cs-tokenizer.cs
@@ -716,9 +716,18 @@ namespace Mono.CSharp
 					res = Token.EXTERN_ALIAS;
 				break;
 			case Token.DEFAULT:
-				if (peek_token () == Token.COLON) {
-					token ();
-					res = Token.DEFAULT_COLON;
+				switch (peek_token ()) {
+				case Token.COLON:
+					// Special case: foo == null ? default : 1;
+					if (current_token != Token.INTERR) {
+						token ();
+						res = Token.DEFAULT_COLON;
+					}
+					break;
+				case Token.OPEN_PARENS:
+				case Token.OPEN_PARENS_CAST:
+					res = Token.DEFAULT_VALUE;
+					break;
 				}
 				break;
 			case Token.WHEN:
@@ -812,10 +821,12 @@ namespace Mono.CSharp
 				PushPosition ();
 
 				next_token = token ();
-				bool ok = (next_token == Token.CLASS) ||
-					(next_token == Token.STRUCT) ||
-					(next_token == Token.INTERFACE) ||
-					(next_token == Token.VOID);
+				bool ok =
+					next_token == Token.CLASS ||
+					next_token == Token.STRUCT ||
+					next_token == Token.INTERFACE ||
+					next_token == Token.VOID ||
+					next_token == Token.REF_STRUCT;
 
 				PopPosition ();
 
@@ -903,6 +914,12 @@ namespace Mono.CSharp
 					break;
 				}
 
+				break;
+			case Token.REF:
+				if (peek_token () == Token.STRUCT) {
+					token ();
+					res = Token.REF_STRUCT;
+				}
 				break;
 			}
 
@@ -1094,6 +1111,7 @@ namespace Mono.CSharp
 						case Token.UNCHECKED:
 						case Token.UNSAFE:
 						case Token.DEFAULT:
+						case Token.DEFAULT_VALUE:
 						case Token.AWAIT:
 
 						//
@@ -1273,14 +1291,21 @@ namespace Mono.CSharp
 
 				return false;
 			case Token.OPEN_PARENS:
-				if (!parsing_generic_declaration)
-					return false;
-				
+				int parens_count = 1;
 				while (true) {
 					switch (token ()) {
 					case Token.COMMA:
 						// tuple declaration after <
-						return true;
+						if (parens_count == 1)
+							return true;
+						continue;
+					case Token.OPEN_PARENS:
+						++parens_count;
+						continue;
+					case Token.CLOSE_PARENS:
+						if (--parens_count <= 0)
+							return false;
+						continue;
 					case Token.OP_GENERICS_GT:
 					case Token.EOF:
 						return false;
@@ -1380,6 +1405,7 @@ namespace Mono.CSharp
 			case Token.NEW:
 			case Token.INTERPOLATED_STRING:
 			case Token.THROW:
+			case Token.DEFAULT_COLON:
 				next_token = Token.INTERR;
 				break;
 				
@@ -3502,6 +3528,7 @@ namespace Mono.CSharp
 						case Token.SWITCH:
 						case Token.USING:
 						case Token.DEFAULT:
+						case Token.DEFAULT_VALUE:
 						case Token.DELEGATE:
 						case Token.OP_GENERICS_GT:
 						case Token.REFVALUE:
@@ -3963,26 +3990,29 @@ namespace Mono.CSharp
 		{
 			int d;
 
-			// Save current position and parse next token.
-			PushPosition ();
-			int generic_dimension = 0;
-			if (parse_less_than (ref generic_dimension)) {
-				if (parsing_generic_declaration && (parsing_generic_declaration_doc || token () != Token.DOT)) {
-					d = Token.OP_GENERICS_LT_DECL;
-				} else {
-					if (generic_dimension > 0) {
-						val = generic_dimension;
-						DiscardPosition ();
-						return Token.GENERIC_DIMENSION;
-					}
+			if (current_token != Token.OPERATOR) {
+				// Save current position and parse next token.
+				PushPosition ();
+				int generic_dimension = 0;
+				if (parse_less_than (ref generic_dimension)) {
+					if (parsing_generic_declaration && (parsing_generic_declaration_doc || token () != Token.DOT)) {
+						d = Token.OP_GENERICS_LT_DECL;
+					} else {
+						if (generic_dimension > 0) {
+							val = generic_dimension;
+							DiscardPosition ();
+							return Token.GENERIC_DIMENSION;
+						}
 
-					d = Token.OP_GENERICS_LT;
+						d = Token.OP_GENERICS_LT;
+					}
+					PopPosition ();
+					return d;
 				}
+
 				PopPosition ();
-				return d;
 			}
 
-			PopPosition ();
 			parsing_generic_less_than = 0;
 
 			d = peek_char ();
diff --git a/mcs/mcs/delegate.cs b/mcs/mcs/delegate.cs
index 80eb7e265f1..52cee8f3455 100644
--- a/mcs/mcs/delegate.cs
+++ b/mcs/mcs/delegate.cs
@@ -188,8 +188,8 @@ namespace Mono.CSharp {
 
 			CheckProtectedModifier ();
 
-			if (Compiler.Settings.StdLib && ret_type.IsSpecialRuntimeType) {
-				Method.Error1599 (Location, ret_type, Report);
+			if (ret_type.IsSpecialRuntimeType && Compiler.Settings.StdLib) {
+				Method.Error_ReturnTypeCantBeRefAny (Location, ret_type, Report);
 				return false;
 			}
 
@@ -338,6 +338,8 @@ namespace Mono.CSharp {
 					Module.PredefinedAttributes.Dynamic.EmitAttribute (CreateReturnBuilder ().Builder);
 				} else if (rtype.HasDynamicElement) {
 					Module.PredefinedAttributes.Dynamic.EmitAttribute (CreateReturnBuilder ().Builder, rtype, Location);
+				} else if (rtype is ReadOnlyReferenceContainer) {
+					Module.PredefinedAttributes.IsReadOnly.EmitAttribute (CreateReturnBuilder ().Builder);
 				}
 
 				if (rtype.HasNamedTupleElement) {
@@ -603,8 +605,14 @@ namespace Mono.CSharp {
 			}
 
 			var expr = method_group.InstanceExpression;
-			if (expr != null && (expr.Type.IsGenericParameter || !TypeSpec.IsReferenceType (expr.Type)))
+			if (expr != null && (expr.Type.IsGenericParameter || !TypeSpec.IsReferenceType (expr.Type))) {
+				if (expr.Type.IsByRefLike || expr.Type.IsSpecialRuntimeType) {
+					// CSC: Should be better error code
+					Error_ConversionFailed (ec, delegate_method, null);
+				}
+
 				method_group.InstanceExpression = new BoxedCast (expr, ec.BuiltinTypes.Object);
+			}
 
 			eclass = ExprClass.Value;
 			return this;
diff --git a/mcs/mcs/dynamic.cs b/mcs/mcs/dynamic.cs
index fd4662b2fed..f8314b2f3cd 100644
--- a/mcs/mcs/dynamic.cs
+++ b/mcs/mcs/dynamic.cs
@@ -279,11 +279,19 @@ namespace Mono.CSharp
 
 		protected bool DoResolveCore (ResolveContext rc)
 		{
+			int i = 0;
 			foreach (var arg in arguments) {
 				if (arg.Type == InternalType.VarOutType) {
 					// Should be special error message about dynamic dispatch
 					rc.Report.Error (8197, arg.Expr.Location, "Cannot infer the type of implicitly-typed out variable `{0}'", ((DeclarationExpression) arg.Expr).Variable.Name);
+				} else if (arg.Type == InternalType.DefaultType) {
+					rc.Report.Error (8311, arg.Expr.Location, "Cannot use a default literal as an argument to a dynamically dispatched operation");
 				}
+
+				// Forced limitation because Microsoft.CSharp needs to catch up
+				if (i > 0 && arguments [i - 1] is NamedArgument && !(arguments [i] is NamedArgument))
+					rc.Report.Error (8324, loc, "Named argument specifications must appear after all fixed arguments have been specified in a dynamic invocation");
+				++i;
 			}
 
 			if (rc.CurrentTypeParameters != null && rc.CurrentTypeParameters[0].IsMethodTypeParameter)
diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs
index 34ff9a30dab..20ee9e73b19 100644
--- a/mcs/mcs/ecore.cs
+++ b/mcs/mcs/ecore.cs
@@ -255,7 +255,7 @@ namespace Mono.CSharp {
 
 		public void Error_ExpressionMustBeConstant (ResolveContext rc, Location loc, string e_name)
 		{
-			rc.Report.Error (133, loc, "The expression being assigned to `{0}' must be constant", e_name);
+			rc.Report.Error (133, loc, "The expression being assigned to `{0}' must be a constant or default value", e_name);
 		}
 
 		public void Error_ConstantCanBeInitializedWithNullOnly (ResolveContext rc, TypeSpec type, Location loc, string name)
@@ -2957,6 +2957,13 @@ namespace Mono.CSharp {
 				if ((restrictions & MemberLookupRestrictions.NameOfExcluded) == 0 && Name == "nameof")
 					return new NameOf (this);
 
+				if ((restrictions & MemberLookupRestrictions.ReadAccess) == 0 && Name == "_") {
+					if (rc.Module.Compiler.Settings.Version < LanguageVersion.V_7)
+						rc.Report.FeatureIsNotAvailable (rc.Module.Compiler, loc, "discards");
+
+					return new Discard (loc).Resolve (rc);
+				}
+
 				if (errorMode) {
 					if (variable_found) {
 						rc.Report.Error (841, loc, "A local variable `{0}' cannot be used before it is declared", Name);
@@ -4029,6 +4036,13 @@ namespace Mono.CSharp {
 			return Methods.First ().GetSignatureForError ();
 		}
 
+		static MethodSpec CandidateDevirtualization (TypeSpec type, MethodSpec method)
+		{
+			// Assumes no generics get involved
+			var filter = new MemberFilter (method.Name, method.Arity, MemberKind.Method, method.Parameters, null);
+			return MemberCache.FindMember (type, filter, BindingRestriction.InstanceOnly | BindingRestriction.OverrideOnly | BindingRestriction.DeclaredOnly) as MethodSpec;
+		}
+
 		public override Expression CreateExpressionTree (ResolveContext ec)
 		{
 			if (best_candidate == null) {
@@ -4177,6 +4191,22 @@ namespace Mono.CSharp {
 						}
 
 						InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup | ResolveFlags.Type);
+
+						var expr_type = InstanceExpression.Type;
+						if ((expr_type.IsByRefLike || expr_type.IsSpecialRuntimeType) && best_candidate.DeclaringType != expr_type) {
+							MethodSpec devirt = null;
+							if ((best_candidate.Modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) != 0) {
+								devirt = CandidateDevirtualization (expr_type, best_candidate);
+							}
+
+							if (devirt == null) {
+								// CSC: Should be better error message
+								ec.Report.Error (29, InstanceExpression.Location, "Cannot implicitly convert type `{0}' to `{1}'",
+												 InstanceExpression.Type.GetSignatureForError (), best_candidate.DeclaringType.GetSignatureForError ());
+							} else {
+								best_candidate = devirt;
+							}
+						}
 					}
 				}
 
@@ -5419,7 +5449,7 @@ namespace Mono.CSharp {
 				}
 
 				if (arg_type != parameter) {
-					if (arg_type == InternalType.VarOutType)
+					if (arg_type == InternalType.VarOutType || arg_type == InternalType.Discard)
 						return 0;
 
 					var ref_arg_type = arg_type as ReferenceContainer;
@@ -6028,6 +6058,11 @@ namespace Mono.CSharp {
 						continue;
 					}
 
+					if (arg_type == InternalType.Discard) {
+						a.Expr.Type = pt;
+						continue;
+					}
+
 					var ref_arg_type = arg_type as ReferenceContainer;
 					if (ref_arg_type != null) {
 						if (ref_arg_type.Element != pt)
@@ -6061,9 +6096,15 @@ namespace Mono.CSharp {
 						else
 							ec.Report.SymbolRelatedToPreviousError (member);
 
-						ec.Report.Error (1744, na.Location,
-							"Named argument `{0}' cannot be used for a parameter which has positional argument specified",
-							na.Name);
+						if (name_index > a_idx) {
+							ec.Report.Error (8323, na.Location,
+								"Named argument `{0}' is used out of position but is followed by positional argument",
+								na.Name);
+						} else {
+							ec.Report.Error (1744, na.Location,
+								"Named argument `{0}' cannot be used for a parameter which has positional argument specified",
+								na.Name);
+						}
 					}
 				}
 				
@@ -7350,6 +7391,9 @@ namespace Mono.CSharp {
 			if (!ResolveGetter (ec))
 				return null;
 
+			if (type.Kind == MemberKind.ByRef)
+				return ByRefDereference.Create (this).Resolve (ec);
+
 			return this;
 		}
 
@@ -7359,12 +7403,11 @@ namespace Mono.CSharp {
 				Error_NullPropagatingLValue (rc);
 
 			if (right_side == EmptyExpression.OutAccess) {
-				if (best_candidate?.MemberType.Kind == MemberKind.ByRef) {
-					if (Arguments?.ContainsEmitWithAwait () == true) {
-						rc.Report.Error (8178, loc, "`await' cannot be used in an expression containing a call to `{0}' because it returns by reference",
-							GetSignatureForError ());
-					}
+				if (OverloadResolve (rc, null) == null)
+					return null;
 
+				if (best_candidate?.MemberType.Kind == MemberKind.ByRef) {
+					getter = CandidateToBaseOverride (rc, best_candidate.Get);
 					return this;
 				}
 
@@ -7396,7 +7439,7 @@ namespace Mono.CSharp {
 
 				if (best_candidate.MemberType.Kind == MemberKind.ByRef) {
 					getter = CandidateToBaseOverride (rc, best_candidate.Get);
-					return ByRefDereference.Create(this).Resolve(rc);
+					return ByRefDereference.Create (this).Resolve (rc);
 				}
 
 				rc.Report.Error (200, loc, "Property or indexer `{0}' cannot be assigned to (it is read-only)",
diff --git a/mcs/mcs/eval.cs b/mcs/mcs/eval.cs
index 60e0c6d64a0..075697bb1df 100644
--- a/mcs/mcs/eval.cs
+++ b/mcs/mcs/eval.cs
@@ -788,6 +788,7 @@ namespace Mono.CSharp
 				return null;
 			}
 
+			module.CloseContainerEarlyForReflectionEmit ();
 			module.CloseContainer ();
 			if (host != null)
 				host.CloseContainer ();
diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs
index 732ee3ee934..518ccc8ef43 100644
--- a/mcs/mcs/expression.cs
+++ b/mcs/mcs/expression.cs
@@ -1220,6 +1220,7 @@ namespace Mono.CSharp
 				expr = expr.ResolveLValue (ec, expr);
 			} else {
 				ec.Report.Error (1059, loc, "The operand of an increment or decrement operator must be a variable, property or indexer");
+				return null;
 			}
 
 			//
@@ -1477,6 +1478,11 @@ namespace Mono.CSharp
 				return null;
 			}
 
+			if (expr.Type == InternalType.DefaultType) {
+				Error_OperatorCannotBeApplied (rc, loc, OperatorName, expr.Type);
+				return null;
+			}
+
 			return this;
 		}
 
@@ -4304,9 +4310,32 @@ namespace Mono.CSharp
 				CheckOutOfRangeComparison (ec, rc, left.Type);
 			}
 
-			if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic || right.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
+			var ltype = left.Type;
+			var rtype = right.Type;
+			if (ltype.BuiltinType == BuiltinTypeSpec.Type.Dynamic || rtype.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
 				return DoResolveDynamic (ec);
 
+			//
+			// Only default with == and != is explicitly allowed
+			//
+			if (ltype == InternalType.DefaultType || rtype == InternalType.DefaultType) {
+				if ((Oper & Operator.EqualityMask) == 0) {
+					ec.Report.Error (8310, loc, "Operator `{0}' cannot be applied to operand `default'", OperName (Oper));
+					return null;
+				}
+
+				if (ltype == rtype) {
+					ec.Report.Error (8315, loc, "Operator `{0}' is ambiguous on operands `default' and `default'", OperName (Oper));
+					return null;
+				}
+
+				if (rtype == InternalType.DefaultType) {
+					right = new DefaultValueExpression (new TypeExpression (ltype, right.Location), right.Location).Resolve (ec);
+				} else {
+					left = new DefaultValueExpression (new TypeExpression (rtype, left.Location), left.Location).Resolve (ec);
+				}
+			}
+
 			return DoResolveCore (ec, left, right);
 		}
 
@@ -6744,10 +6773,14 @@ namespace Mono.CSharp
 					ec.Report.Error (1764, loc,
 						"Cannot use fixed variable `{0}' inside an anonymous method, lambda expression or query expression",
 						GetSignatureForError ());
-				} else if (local_info.IsByRef) {
-					ec.Report.Error (8175, loc,
-						"Cannot use by-reference variable `{0}' inside an anonymous method, lambda expression, or query expression",
-						GetSignatureForError ());
+				} else if (local_info.IsByRef || local_info.Type.IsByRefLike) {
+					if (ec.CurrentAnonymousMethod is StateMachineInitializer) {
+						// It's reported later as 4012/4013
+					} else {
+						ec.Report.Error (8175, loc,
+							"Cannot use by-reference variable `{0}' inside an anonymous method, lambda expression, or query expression",
+							GetSignatureForError ());
+					}
 				}
 
 				if (ec.IsVariableCapturingRequired) {
@@ -6783,7 +6816,9 @@ namespace Mono.CSharp
 				local_info.SetIsUsed ();
 
 			if (local_info.IsReadonly && !ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.UsingInitializerScope)) {
-				if (rhs == EmptyExpression.LValueMemberAccess) {
+				if (local_info.IsByRef) {
+					// OK because it cannot be reassigned
+				} else if (rhs == EmptyExpression.LValueMemberAccess) {
 					// CS1654 already reported
 				} else {
 					int code;
@@ -7175,8 +7210,7 @@ namespace Mono.CSharp
 		{
 			var sn = expr as SimpleName;
 			if (sn != null && sn.Name == "var" && sn.Arity == 0 && arguments?.Count > 1) {
-				var targets = new List<Expression> (arguments.Count);
-				var variables = new List<LocalVariable> (arguments.Count);
+				var variables = new List<BlockVariable> (arguments.Count);
 				foreach (var arg in arguments) {
 					var arg_sn = arg.Expr as SimpleName;
 					if (arg_sn == null || arg_sn.Arity != 0) {
@@ -7186,12 +7220,10 @@ namespace Mono.CSharp
 
 					var lv = new LocalVariable (rc.CurrentBlock, arg_sn.Name, arg.Expr.Location);
 					rc.CurrentBlock.AddLocalName (lv);
-					variables.Add (lv);
-
-					targets.Add (new LocalVariableReference (lv, arg_sn.Location));
+					variables.Add (new BlockVariable (new VarExpr (lv.Location), lv));
 				}
 
-				var res = new TupleDeconstruct (targets, variables, right_side, loc);
+				var res = new TupleDeconstruct (variables, right_side, loc);
 				return res.Resolve (rc);
 			}
 
@@ -7306,15 +7338,8 @@ namespace Mono.CSharp
 			
 			eclass = ExprClass.Value;
 
-			if (type.Kind == MemberKind.ByRef) {
-				if (rhs == null && arguments?.ContainsEmitWithAwait () == true) {
-					ec.Report.Error (8178, loc, "`await' cannot be used in an expression containing a call to `{0}' because it returns by reference",
-						GetSignatureForError ());
-				}
-
-				if (rhs != EmptyExpression.OutAccess)
-					return ByRefDereference.Create (this).Resolve (ec);
-			}
+			if (type.Kind == MemberKind.ByRef && rhs != EmptyExpression.OutAccess)
+				return ByRefDereference.Create (this).Resolve (ec);
 
 			return this;
 		}
@@ -9034,7 +9059,7 @@ namespace Mono.CSharp
 			if (eclass == ExprClass.Unresolved)
 				ResolveBase (ec);
 
-			if (type.IsClass || type.IsReadOnly) {
+			if (type.IsClass || (type.IsReadOnly && !ec.HasSet (ResolveContext.Options.ConstructorScope))) {
 				if (right_side == EmptyExpression.UnaryAddress)
 					ec.Report.Error (459, loc, "Cannot take the address of `this' because it is read-only");
 				else if (right_side == EmptyExpression.OutAccess)
@@ -9908,7 +9933,7 @@ namespace Mono.CSharp
 		public static bool IsValidDotExpression (TypeSpec type)
 		{
 			const MemberKind dot_kinds = MemberKind.Class | MemberKind.Struct | MemberKind.Delegate | MemberKind.Enum |
-				MemberKind.Interface | MemberKind.TypeParameter | MemberKind.ArrayType;
+				MemberKind.Interface | MemberKind.TypeParameter | MemberKind.ArrayType  | MemberKind.ByRef;
 
 			return (type.Kind & dot_kinds) != 0 || type.BuiltinType == BuiltinTypeSpec.Type.Dynamic;
 		}
@@ -11614,7 +11639,7 @@ namespace Mono.CSharp
 			}
 
 			if (single_spec != null && single_spec.Dimension > 0) {
-				if (type.IsSpecialRuntimeType) {
+				if (type.IsSpecialRuntimeType || type.IsByRefLike) {
 					ec.Module.Compiler.Report.Error (611, loc, "Array elements cannot be of type `{0}'", type.GetSignatureForError ());
 				} else if (type.IsStatic) {
 					ec.Module.Compiler.Report.SymbolRelatedToPreviousError (type);
@@ -11650,6 +11675,13 @@ namespace Mono.CSharp
 	class ReferenceTypeExpr : TypeExpr
 	{
 		FullNamedExpression element;
+		readonly bool readOnly;
+
+		public ReferenceTypeExpr (FullNamedExpression element, bool readOnly, Location loc)
+			: this (element, loc)
+		{
+			this.readOnly = readOnly;
+		}
 
 		public ReferenceTypeExpr (FullNamedExpression element, Location loc)
 		{
@@ -11664,14 +11696,17 @@ namespace Mono.CSharp
 				return null;
 
 			eclass = ExprClass.Type;
-			type = ReferenceContainer.MakeType (mc.Module, type);
+			type = readOnly ?
+				ReadOnlyReferenceContainer.MakeType (mc.Module, type) :
+				ReferenceContainer.MakeType (mc.Module, type);
 
 			return type;
 		}
 
 		public override string GetSignatureForError ()
 		{
-			return "ref " + element.GetSignatureForError ();
+			var prefix = readOnly ? "ref " : "ref readonly ";
+			return prefix + element.GetSignatureForError ();
 		}
 
 		public override object Accept (StructuralVisitor visitor)
@@ -11783,6 +11818,7 @@ namespace Mono.CSharp
 		TypeSpec otype;
 		Expression texpr;
 		Expression count;
+		MethodSpec ctor;
 		
 		public StackAlloc (Expression type, Expression count, Location l)
 		{
@@ -11852,6 +11888,11 @@ namespace Mono.CSharp
 			int size = BuiltinTypeSpec.GetSize (otype);
 
 			count.Emit (ec);
+			bool count_on_stack = false;
+			if (ctor != null && !ExpressionAnalyzer.IsInexpensiveLoad (count)) {
+				ec.Emit (OpCodes.Dup);
+				count_on_stack = true;
+			}
 
 			if (size == 0)
 				ec.Emit (OpCodes.Sizeof, otype);
@@ -11860,6 +11901,19 @@ namespace Mono.CSharp
 
 			ec.Emit (OpCodes.Mul_Ovf_Un);
 			ec.Emit (OpCodes.Localloc);
+
+			if (ctor != null) {
+				if (!count_on_stack)
+					count.Emit (ec);
+				ec.Emit (OpCodes.Newobj, ctor);
+			}
+		}
+
+		public override void Error_ValueCannotBeConverted (ResolveContext rc, TypeSpec target, bool expl)
+		{
+			var etype = ((PointerContainer)type).Element;
+			rc.Report.Error (8346, loc, "Cannot convert a stackalloc expression of type `{0}' to type `{1}'",
+			                 etype.GetSignatureForError (), target.GetSignatureForError ());
 		}
 
 		protected override void CloneTo (CloneContext clonectx, Expression t)
@@ -11873,6 +11927,16 @@ namespace Mono.CSharp
 		{
 			return visitor.Visit (this);
 		}
+
+		public bool ResolveSpanConversion (ResolveContext rc, TypeSpec spanType)
+		{
+			ctor = MemberCache.FindMember (spanType, MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (PointerContainer.MakeType (rc.Module, rc.Module.Compiler.BuiltinTypes.Void), rc.Module.Compiler.BuiltinTypes.Int)), BindingRestriction.DeclaredOnly) as MethodSpec;
+			if (ctor == null)
+				return false;
+			
+			this.type = spanType;
+			return true;
+		}
 	}
 
 	//
@@ -13093,6 +13157,12 @@ namespace Mono.CSharp
 			expr.Emit (ec);
 		}
 
+		public override Expression CreateExpressionTree (ResolveContext rc)
+		{
+			rc.Report.Error (8153, Location, "An expression tree lambda cannot contain a call to a method, property, or indexer that returns by reference");
+			return null;
+		}
+
 		public void Emit (EmitContext ec, bool leave_copy)
 		{
 			Emit (ec);
@@ -13133,6 +13203,11 @@ namespace Mono.CSharp
 
 		public override Expression DoResolveLValue (ResolveContext rc, Expression right_side)
 		{
+			if (expr.ContainsEmitWithAwait ()) {
+				rc.Report.Error (8178, loc, "`await' cannot be used in an expression containing a call to `{0}' because it returns by reference",
+					expr.GetSignatureForError ());
+			}
+
 			return DoResolve (rc);
 		}
 
@@ -13149,4 +13224,98 @@ namespace Mono.CSharp
 			return visitor.Visit (this);
 		}
 	}
+
+	class DefaultLiteralExpression : Expression
+	{
+		public DefaultLiteralExpression (Location loc)
+		{
+			this.loc = loc;
+		}
+
+		public override Expression CreateExpressionTree (ResolveContext ec)
+		{
+			throw new NotImplementedException ();
+		}
+
+		protected override Expression DoResolve (ResolveContext rc)
+		{
+			type = InternalType.DefaultType;
+			eclass = ExprClass.Value;
+			return this;
+		}
+
+		public override void Emit (EmitContext ec)
+		{
+			throw new NotSupportedException ();
+		}
+	}
+
+	class Discard : Expression, IAssignMethod, IMemoryLocation
+	{
+		public Discard (Location loc)
+		{
+			this.loc = loc;
+		}
+
+		public override Expression CreateExpressionTree (ResolveContext rc)
+		{
+			rc.Report.Error (8207, loc, "An expression tree cannot contain a discard");
+			return null;
+		}
+
+		protected override Expression DoResolve (ResolveContext rc)
+		{
+			type = InternalType.Discard;
+			eclass = ExprClass.Variable;
+			return this;
+		}
+
+		public override Expression DoResolveLValue (ResolveContext rc, Expression right_side)
+		{
+			if (right_side.Type == InternalType.DefaultType) {
+				rc.Report.Error (8183, loc, "Cannot infer the type of implicitly-typed discard");
+				type = InternalType.ErrorType;
+				return this;
+			}
+
+			if (right_side.Type.Kind == MemberKind.Void) {
+				rc.Report.Error (8209, loc, "Cannot assign void to a discard");
+				type = InternalType.ErrorType;
+				return this;
+			}
+
+			if (right_side != EmptyExpression.OutAccess) {
+				type = right_side.Type;
+			}
+
+			return this;
+		}
+
+		public override void Emit (EmitContext ec)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void Emit (EmitContext ec, bool leave_copy)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool isCompound)
+		{
+			if (leave_copy)
+				source.Emit (ec);
+			else
+				source.EmitSideEffect (ec);
+		}
+
+		public void AddressOf (EmitContext ec, AddressOp mode)
+		{
+			var temp = ec.GetTemporaryLocal (type);
+			ec.Emit (OpCodes.Ldloca, temp);
+
+			// TODO: Should free it on next statement but don't have mechanism for that yet
+			// ec.FreeTemporaryLocal (temp, type);
+		}
+	}
 }
diff --git a/mcs/mcs/generic.cs b/mcs/mcs/generic.cs
index 625cd0c773f..ec2965df63b 100644
--- a/mcs/mcs/generic.cs
+++ b/mcs/mcs/generic.cs
@@ -693,6 +693,11 @@ namespace Mono.CSharp {
 					GetSignatureForError (), mc.GetSignatureForError (), input_variance, gtype_variance, parameters);
 		}
 
+		public TypeSpec GetAsyncMethodBuilder ()
+		{
+			return null;
+		}
+
 		public TypeSpec GetAttributeCoClass ()
 		{
 			return null;
@@ -2292,7 +2297,7 @@ namespace Mono.CSharp {
 					ok = false;
 				}
 
-				if (te.IsPointer || te.IsSpecialRuntimeType) {
+				if (te.IsPointer || te.IsSpecialRuntimeType || te.IsByRefLike) {
 					ec.Module.Compiler.Report.Error (306, args[i].Location,
 						"The type `{0}' may not be used as a type argument",
 						te.GetSignatureForError ());
@@ -3102,7 +3107,7 @@ namespace Mono.CSharp {
 			//
 			// Some types cannot be used as type arguments
 			//
-			if ((bound.Type.Kind == MemberKind.Void && !voidAllowed) || bound.Type.IsPointer || bound.Type.IsSpecialRuntimeType ||
+			if ((bound.Type.Kind == MemberKind.Void && !voidAllowed) || bound.Type.IsPointer || bound.Type.IsSpecialRuntimeType || bound.Type.IsByRefLike ||
 			    bound.Type == InternalType.MethodGroup || bound.Type == InternalType.AnonymousMethod || bound.Type == InternalType.VarOutType ||
 			    bound.Type == InternalType.ThrowExpr)
 				return;
@@ -3110,6 +3115,9 @@ namespace Mono.CSharp {
 			if (bound.Type.IsTupleType && TupleLiteral.ContainsNoTypeElement (bound.Type))
 				return;
 
+			if (bound.Type == InternalType.DefaultType)
+				return;
+
 			var a = bounds [index];
 			if (a == null) {
 				a = new List<BoundInfo> (2);
diff --git a/mcs/mcs/import.cs b/mcs/mcs/import.cs
index 1cddf7c01f4..f7c4fd74b08 100644
--- a/mcs/mcs/import.cs
+++ b/mcs/mcs/import.cs
@@ -975,6 +975,10 @@ namespace Mono.CSharp
 						mod |= Modifiers.READONLY;
 					}
 
+					if (HasAttribute (CustomAttributeData.GetCustomAttributes (type), "IsByRefLikeAttribute", CompilerServicesNamespace)) {
+						mod |= Modifiers.REF;
+					}
+
 					break;
 				}
 			}
@@ -1401,6 +1405,7 @@ namespace Mono.CSharp
 			public string DefaultIndexerName;
 			public bool? CLSAttributeValue;
 			public TypeSpec CoClass;
+			public TypeSpec AsyncMethodBuilder;
 
 			static bool HasMissingType (ConstructorInfo ctor)
 			{
@@ -1522,6 +1527,20 @@ namespace Mono.CSharp
 							bag.CoClass = importer.ImportType ((MetaType) a.ConstructorArguments[0].Value);
 							continue;
 						}
+
+						if (name == "AsyncMethodBuilderAttribute") {
+							if (dt.Namespace != "System.Runtime.CompilerServices")
+								continue;
+
+							if (HasMissingType (a.Constructor))
+								continue;
+
+							if (bag == null)
+								bag = new AttributesBag ();
+
+							bag.AsyncMethodBuilder = importer.ImportType ((MetaType)a.ConstructorArguments [0].Value);
+							continue;
+						}
 					}
 				}
 
@@ -2129,6 +2148,14 @@ namespace Mono.CSharp
 			}
 		}
 
+		public TypeSpec GetAsyncMethodBuilder ()
+		{
+			if (cattrs == null)
+				ReadAttributes ();
+
+			return cattrs.AsyncMethodBuilder;
+		}
+
 		public TypeSpec GetAttributeCoClass ()
 		{
 			if (cattrs == null)
@@ -2445,6 +2472,11 @@ namespace Mono.CSharp
 
 		#endregion
 
+		public TypeSpec GetAsyncMethodBuilder ()
+		{
+			return null;
+		}
+
 		public TypeSpec GetAttributeCoClass ()
 		{
 			return null;
diff --git a/mcs/mcs/membercache.cs b/mcs/mcs/membercache.cs
index eebf71b844b..ca05d2d7afc 100644
--- a/mcs/mcs/membercache.cs
+++ b/mcs/mcs/membercache.cs
@@ -309,7 +309,6 @@ namespace Mono.CSharp {
 				//
 				if (!BuiltinTypeSpec.IsPrimitiveType (dt) || dt.BuiltinType == BuiltinTypeSpec.Type.Char) {
 					switch (dt.BuiltinType) {
-					case BuiltinTypeSpec.Type.String:
 					case BuiltinTypeSpec.Type.Delegate:
 					case BuiltinTypeSpec.Type.MulticastDelegate:
 						break;
@@ -317,6 +316,9 @@ namespace Mono.CSharp {
 						if (name == Operator.GetMetadataName (Operator.OpType.Implicit) || name == Operator.GetMetadataName (Operator.OpType.Explicit)) {
 							state |= StateFlags.HasConversionOperator;
 						} else {
+							if (dt.BuiltinType == BuiltinTypeSpec.Type.String)
+								break;
+
 							state |= StateFlags.HasUserOperator;
 						}
 
diff --git a/mcs/mcs/method.cs b/mcs/mcs/method.cs
index ccd4898e91c..1fca10dd6d0 100644
--- a/mcs/mcs/method.cs
+++ b/mcs/mcs/method.cs
@@ -701,6 +701,10 @@ namespace Mono.CSharp {
 			if (MemberType.IsStatic) {
 				Error_StaticReturnType ();
 			}
+
+			if (MemberType.IsSpecialRuntimeType && Compiler.Settings.StdLib) {
+				Error_ReturnTypeCantBeRefAny (Location, ReturnType, Report);
+			}
 		}
 
 		public override void Emit ()
@@ -716,6 +720,8 @@ namespace Mono.CSharp {
 				Module.PredefinedAttributes.Dynamic.EmitAttribute (CreateReturnBuilder ().Builder);
 			} else if (ReturnType.HasDynamicElement) {
 				Module.PredefinedAttributes.Dynamic.EmitAttribute (CreateReturnBuilder ().Builder, ReturnType, Location);
+			} else if (ReturnType is ReadOnlyReferenceContainer) {
+				Module.PredefinedAttributes.IsReadOnly.EmitAttribute (CreateReturnBuilder ().Builder);
 			}
 
 			if (ReturnType.HasNamedTupleElement) {
@@ -764,6 +770,11 @@ namespace Mono.CSharp {
 				GetSignatureForError ());
 		}
 
+		public static void Error_ReturnTypeCantBeRefAny (Location loc, TypeSpec t, Report Report)
+		{
+			Report.Error (1599, loc, "The return type of `{0}' is not allowed", t.GetSignatureForError ());
+		}
+
 		public bool IsPartialDefinition {
 			get {
 				return (ModFlags & Modifiers.PARTIAL) != 0 && Block == null;
@@ -1231,11 +1242,6 @@ namespace Mono.CSharp {
 					"Introducing `Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
 			}
 
-			if (Compiler.Settings.StdLib && ReturnType.IsSpecialRuntimeType) {
-				Error1599 (Location, ReturnType, Report);
-				return false;
-			}
-
 			if (CurrentTypeParameters == null) {
 				if (base_method != null && !IsExplicitImpl) {
 					if (parameters.Count == 1 && ParameterTypes[0].BuiltinType == BuiltinTypeSpec.Type.Object && MemberName.Name == "Equals")
@@ -1261,8 +1267,9 @@ namespace Mono.CSharp {
 				if ((ModFlags & Modifiers.ASYNC) != 0) {
 					if (ReturnType.Kind != MemberKind.Void &&
 						ReturnType != Module.PredefinedTypes.Task.TypeSpec &&
-						!ReturnType.IsGenericTask) {
-						Report.Error (1983, Location, "The return type of an async method must be void, Task, or Task<T>");
+						!ReturnType.IsGenericTask &&
+					    !ReturnType.IsCustomTaskType ()) {
+						Report.Error (1983, Location, "The return type of an async method must be void or task type");
 					}
 
 					block = (ToplevelBlock) block.ConvertToAsyncTask (this, Parent.PartialContainer, parameters, ReturnType, null, Location);
@@ -1396,11 +1403,6 @@ namespace Mono.CSharp {
 			return base.EnableOverloadChecks (overload);
 		}
 
-		public static void Error1599 (Location loc, TypeSpec t, Report Report)
-		{
-			Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", t.GetSignatureForError ());
-		}
-
 		protected override bool ResolveMemberType ()
 		{
 			if (CurrentTypeParameters != null) {
@@ -2467,6 +2469,8 @@ namespace Mono.CSharp {
 				Module.PredefinedAttributes.Dynamic.EmitAttribute (CreateReturnBuilder ().Builder);
 			} else if (ReturnType.HasDynamicElement) {
 				Module.PredefinedAttributes.Dynamic.EmitAttribute (CreateReturnBuilder ().Builder, ReturnType, Location);
+			} else if (ReturnType is ReadOnlyReferenceContainer) {
+				Module.PredefinedAttributes.IsReadOnly.EmitAttribute (CreateReturnBuilder ().Builder);
 			}
 
 			if (ReturnType.HasNamedTupleElement) {
diff --git a/mcs/mcs/modifiers.cs b/mcs/mcs/modifiers.cs
index bfae5985a03..926ab5d1848 100644
--- a/mcs/mcs/modifiers.cs
+++ b/mcs/mcs/modifiers.cs
@@ -53,6 +53,7 @@ namespace Mono.CSharp
 		DEBUGGER_HIDDEN			= 0x400000,
 		DEBUGGER_STEP_THROUGH	= 0x800000,
 		AutoProperty			= 0x1000000,
+		REF                     = 0x2000000,
 
 		AccessibilityMask = PUBLIC | PROTECTED | INTERNAL | PRIVATE,
 		AllowedExplicitImplFlags = UNSAFE | EXTERN,
diff --git a/mcs/mcs/module.cs b/mcs/mcs/module.cs
index 00afac6c604..2293d825b36 100644
--- a/mcs/mcs/module.cs
+++ b/mcs/mcs/module.cs
@@ -265,6 +265,7 @@ namespace Mono.CSharp
 		readonly Dictionary<ArrayContainer.TypeRankPair, ArrayContainer> array_types;
 		readonly Dictionary<TypeSpec, PointerContainer> pointer_types;
 		readonly Dictionary<TypeSpec, ReferenceContainer> reference_types;
+		readonly Dictionary<TypeSpec, ReadOnlyReferenceContainer> readonly_reference_types;
 		readonly Dictionary<TypeSpec, MethodSpec> attrs_cache;
 		readonly Dictionary<TypeSpec, AwaiterDefinition> awaiters;
 		readonly Dictionary<TypeSpec, TypeInfo> type_info_cache;
@@ -301,6 +302,7 @@ namespace Mono.CSharp
 			array_types = new Dictionary<ArrayContainer.TypeRankPair, ArrayContainer> ();
 			pointer_types = new Dictionary<TypeSpec, PointerContainer> ();
 			reference_types = new Dictionary<TypeSpec, ReferenceContainer> ();
+			readonly_reference_types = new Dictionary<TypeSpec, ReadOnlyReferenceContainer> ();
 			attrs_cache = new Dictionary<TypeSpec, MethodSpec> ();
 			awaiters = new Dictionary<TypeSpec, AwaiterDefinition> ();
 			type_info_cache = new Dictionary<TypeSpec, TypeInfo> ();
@@ -427,6 +429,12 @@ namespace Mono.CSharp
 			}
 		}
 
+		internal Dictionary<TypeSpec, ReadOnlyReferenceContainer> ReadonlyReferenceTypesCache {
+			get {
+				return readonly_reference_types;
+			}
+		}
+
 		internal Dictionary<TypeSpec, TypeInfo> TypeInfoCache {
 			get {
 				return type_info_cache;
diff --git a/mcs/mcs/parameter.cs b/mcs/mcs/parameter.cs
index 2bd2a498a91..cc10eee162b 100644
--- a/mcs/mcs/parameter.cs
+++ b/mcs/mcs/parameter.cs
@@ -1447,7 +1447,7 @@ namespace Mono.CSharp {
 
 			expr = Child;
 
-			if (!(expr is Constant || expr is DefaultValueExpression || (expr is New && ((New) expr).IsGeneratedStructConstructor))) {
+			if (!(expr is Constant || expr is DefaultValueExpression || expr is DefaultLiteralExpression || (expr is New && ((New) expr).IsGeneratedStructConstructor))) {
 				if (!(expr is ErrorExpression)) {
 					rc.Report.Error (1736, Location,
 						"The expression being assigned to optional parameter `{0}' must be a constant or default value",
diff --git a/mcs/mcs/statement.cs b/mcs/mcs/statement.cs
index 58ba2795e4b..9c51128548f 100644
--- a/mcs/mcs/statement.cs
+++ b/mcs/mcs/statement.cs
@@ -1160,7 +1160,8 @@ namespace Mono.CSharp {
 				//
 				if (ec.CurrentAnonymousMethod is AsyncInitializer) {
 					var storey = (AsyncTaskStorey) ec.CurrentAnonymousMethod.Storey;
-					if (storey.ReturnType == ec.Module.PredefinedTypes.Task.TypeSpec) {
+					var s_return_type = storey.ReturnType;
+					if (s_return_type == ec.Module.PredefinedTypes.Task.TypeSpec) {
 						//
 						// Extra trick not to emit ret/leave inside awaiter body
 						//
@@ -1168,8 +1169,8 @@ namespace Mono.CSharp {
 						return true;
 					}
 
-					if (storey.ReturnType.IsGenericTask)
-						block_return_type = storey.ReturnType.TypeArguments[0];
+					if (s_return_type.IsGenericTask || (s_return_type.Arity == 1 && s_return_type.IsCustomTaskType ()))
+					    block_return_type = s_return_type.TypeArguments[0];
 				}
 
 				if (ec.CurrentIterator != null) {
@@ -1220,7 +1221,7 @@ namespace Mono.CSharp {
 							return false;
 						}
 
-						if (!async_type.IsGenericTask) {
+						if (!async_type.IsGeneric) {
 							if (this is ContextualReturn)
 								return true;
 
@@ -2368,7 +2369,12 @@ namespace Mono.CSharp {
 			if (initializer == null)
 				return null;
 
-			var c = initializer as Constant;
+			Constant c;
+			if (initializer.Type == InternalType.DefaultType)
+				c = New.Constantify (li.Type, initializer.Location);
+			else
+				c = initializer as Constant;
+
 			if (c == null) {
 				initializer.Error_ExpressionMustBeConstant (bc, initializer.Location, li.Name);
 				return null;
@@ -2407,14 +2413,14 @@ namespace Mono.CSharp {
 			AddressTaken = 1 << 2,
 			CompilerGenerated = 1 << 3,
 			Constant = 1 << 4,
-			ForeachVariable = 1 << 5,
-			FixedVariable = 1 << 6,
-			UsingVariable = 1 << 7,
+			ForeachVariable = 1 << 5 | ReadonlyMask,
+			FixedVariable = 1 << 6 | ReadonlyMask,
+			UsingVariable = 1 << 7 | ReadonlyMask,
 			IsLocked = 1 << 8,
 			SymbolFileHidden = 1 << 9,
 			ByRef = 1 << 10,
 
-			ReadonlyMask = ForeachVariable | FixedVariable | UsingVariable
+			ReadonlyMask = 1 << 20
 		}
 
 		TypeSpec type;
@@ -2534,7 +2540,7 @@ namespace Mono.CSharp {
 
 		public bool IsFixed {
 			get {
-				return (flags & Flags.FixedVariable) != 0;
+				return (flags & Flags.FixedVariable) == Flags.FixedVariable;
 			}
 			set {
 				flags = value ? flags | Flags.FixedVariable : flags & ~Flags.FixedVariable;
@@ -2672,7 +2678,7 @@ namespace Mono.CSharp {
 
 		public string GetReadOnlyContext ()
 		{
-			switch (flags & Flags.ReadonlyMask) {
+			switch (flags & (Flags.ForeachVariable | Flags.FixedVariable | Flags.UsingVariable)) {
 			case Flags.FixedVariable:
 				return "fixed variable";
 			case Flags.ForeachVariable:
@@ -8191,7 +8197,9 @@ namespace Mono.CSharp {
 				}
 
 				if (iface_candidate == null) {
-					if (expr.Type != InternalType.ErrorType) {
+					if (expr.Type == InternalType.DefaultType) {
+						rc.Report.Error (8312, loc, "Use of default literal is not valid in this context");
+					} else if (expr.Type != InternalType.ErrorType) {
 						rc.Report.Error (1579, loc,
 							"foreach statement cannot operate on variables of type `{0}' because it does not contain a definition for `{1}' or is inaccessible",
 							expr.Type.GetSignatureForError (), "GetEnumerator");
diff --git a/mcs/mcs/tuples.cs b/mcs/mcs/tuples.cs
index bb7faf734df..901efdc9541 100644
--- a/mcs/mcs/tuples.cs
+++ b/mcs/mcs/tuples.cs
@@ -432,7 +432,7 @@ namespace Mono.CSharp
 	{
 		Expression source;
 		List<Expression> targetExprs;
-		List<LocalVariable> variablesToInfer;
+		List<BlockVariable> variables;
 		Expression instance;
 
 		public TupleDeconstruct (List<Expression> targetExprs, Expression source, Location loc)
@@ -442,10 +442,11 @@ namespace Mono.CSharp
 			this.loc = loc;
 		}
 
-		public TupleDeconstruct (List<Expression> targetExprs, List<LocalVariable> variables, Expression source, Location loc)
-			: this (targetExprs, source, loc)
+		public TupleDeconstruct (List<BlockVariable> variables, Expression source, Location loc)
 		{
-			this.variablesToInfer = variables;
+			this.source = source;
+			this.variables = variables;
+			this.loc = loc;
 		}
 
 		public override Expression CreateExpressionTree (ResolveContext ec)
@@ -469,9 +470,18 @@ namespace Mono.CSharp
 			var src_type = src.Type;
 
 			if (src_type.IsTupleType) {
-				if (src_type.Arity != targetExprs.Count) {
+				int target_count;
+
+				if (targetExprs == null) {
+					target_count = variables.Count;
+					targetExprs = new List<Expression> (target_count);
+				} else {
+					target_count = targetExprs.Count;
+				}
+
+				if (src_type.Arity != target_count) {
 					rc.Report.Error (8132, loc, "Cannot deconstruct a tuple of `{0}' elements into `{1}' variables",
-						src_type.Arity.ToString (), targetExprs.Count.ToString ());
+						src_type.Arity.ToString (CultureInfo.InvariantCulture), target_count.ToString (CultureInfo.InvariantCulture));
 					return null;
 				}
 
@@ -482,27 +492,44 @@ namespace Mono.CSharp
 					instance = expr_variable.CreateReferenceExpression (rc, loc);
 				}
 
-				for (int i = 0; i < targetExprs.Count; ++i) {
+				for (int i = 0; i < target_count; ++i) {
 					var tle = src_type.TypeArguments [i];
 
-					var lv = variablesToInfer? [i];
-					if (lv != null) {
-						if (InternalType.HasNoType (tle)) {
-							rc.Report.Error (8130, Location, "Cannot infer the type of implicitly-typed deconstruction variable `{0}'", lv.Name);
-							lv.Type = InternalType.ErrorType;
+					if (variables != null) {
+						var variable = variables [i].Variable;
+
+						if (variable.Type == InternalType.Discard) {
+							variables [i] = null;
+							targetExprs.Add (EmptyExpressionStatement.Instance);
 							continue;
 						}
 
-						lv.Type = tle;
-						lv.PrepareAssignmentAnalysis ((BlockContext) rc);
-					}
+						var variable_type = variables [i].TypeExpression;
+
+						targetExprs.Add (new LocalVariableReference (variable, variable.Location));
+
+						if (variable_type is VarExpr) {
+							if (InternalType.HasNoType (tle)) {
+								rc.Report.Error (8130, Location, "Cannot infer the type of implicitly-typed deconstruction variable `{0}'", variable.Name);
+								tle = InternalType.ErrorType;
+							}
 
+							variable.Type = tle;
+						} else {
+							variable.Type = variable_type.ResolveAsType (rc);
+						}
+
+						variable.PrepareAssignmentAnalysis ((BlockContext)rc);
+					}
 
 					var element_src = tupleLiteral == null ? new MemberAccess (instance, NamedTupleSpec.GetElementPropertyName (i)) : tupleLiteral.Elements [i].Expr;
 					targetExprs [i] = new SimpleAssign (targetExprs [i], element_src).Resolve (rc);
 				}
 
 				eclass = ExprClass.Value;
+
+				// TODO: The type is same only if there is no target element conversion
+				// var res = (/*byte*/ b, /*short*/ s) = (2, 4);
 				type = src.Type;
 				return this;
 			}
@@ -527,11 +554,24 @@ namespace Mono.CSharp
 
 		public override void Emit (EmitContext ec)
 		{
-			throw new NotImplementedException ();
+			if (instance != null)
+				((ExpressionStatement)source).EmitStatement (ec);
+
+			foreach (ExpressionStatement expr in targetExprs)
+				expr.Emit (ec);
+
+			var ctor = MemberCache.FindMember (type, MemberFilter.Constructor (null), BindingRestriction.DeclaredOnly | BindingRestriction.InstanceOnly) as MethodSpec;
+			ec.Emit (OpCodes.Newobj, ctor);
 		}
 
 		public override void EmitStatement (EmitContext ec)
 		{
+			if (variables != null) {
+				foreach (var lv in variables) {
+					lv?.Variable.CreateBuilder (ec);
+				}
+			}
+			
 			if (instance != null)
 				((ExpressionStatement) source).EmitStatement (ec);
 			
@@ -549,9 +589,6 @@ namespace Mono.CSharp
 			if (leave_copy)
 				throw new NotImplementedException ();
 
-			foreach (var lv in variablesToInfer)
-				lv.CreateBuilder (ec);
-
 			EmitStatement (ec);
 		}
 
@@ -563,11 +600,11 @@ namespace Mono.CSharp
 
 		public void SetGeneratedFieldAssigned (FlowAnalysisContext fc)
 		{
-			if (variablesToInfer == null)
+			if (variables == null)
 				return;
 
-			foreach (var lv in variablesToInfer)
-				fc.SetVariableAssigned (lv.VariableInfo);
+			foreach (var lv in variables)
+				fc.SetVariableAssigned (lv.Variable.VariableInfo);
 		}
 	}
 }
\ No newline at end of file
diff --git a/mcs/mcs/typemanager.cs b/mcs/mcs/typemanager.cs
index b6aff14e1c0..7a16cda2774 100644
--- a/mcs/mcs/typemanager.cs
+++ b/mcs/mcs/typemanager.cs
@@ -242,6 +242,7 @@ namespace Mono.CSharp
 
 		// C# 7.0
 		public readonly PredefinedType[] Tuples;
+		public readonly PredefinedType SpanGeneric;
 
 		public PredefinedTypes (ModuleContainer module)
 		{
@@ -301,6 +302,8 @@ namespace Mono.CSharp
 			FormattableString = new PredefinedType (module, MemberKind.Class, "System", "FormattableString");
 			FormattableStringFactory = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "FormattableStringFactory");
 
+			SpanGeneric = new PredefinedType (module, MemberKind.Struct, "System", "Span", 1);
+
 			//
 			// Define types which are used for comparison. It does not matter
 			// if they don't exist as no error report is needed
@@ -348,6 +351,8 @@ namespace Mono.CSharp
 				if (pt.Define ())
 					pt.TypeSpec.IsTupleType = true;
 			}
+
+			SpanGeneric.Define ();
 		}
 	}
 
@@ -430,6 +435,7 @@ namespace Mono.CSharp
 			ArrayEmpty = new PredefinedMember<MethodSpec> (module, types.Array,
 				MemberFilter.Method ("Empty", 1, ParametersCompiled.EmptyReadOnlyParameters, null));
 
+			// TODO: Must me static
 			AsyncTaskMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
 				MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncTaskMethodBuilder.TypeSpec));
 
@@ -485,6 +491,7 @@ namespace Mono.CSharp
 			AsyncTaskMethodBuilderTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilder,
 				MemberFilter.Property ("Task", null));
 
+			// TODO: Must me static
 			AsyncTaskMethodBuilderGenericCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
 				MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));
 
@@ -542,6 +549,7 @@ namespace Mono.CSharp
 			AsyncTaskMethodBuilderGenericTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilderGeneric,
 				MemberFilter.Property ("Task", null));
 
+			// TODO: Must me static
 			AsyncVoidMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
 				MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));
 
@@ -1006,9 +1014,6 @@ namespace Mono.CSharp
 
 		public T Resolve (Location loc)
 		{
-			if (member != null)
-				return member;
-
 			if (Get () != null)
 				return member;
 
diff --git a/mcs/mcs/typespec.cs b/mcs/mcs/typespec.cs
index d14e1ead3e3..a58a0fe5178 100644
--- a/mcs/mcs/typespec.cs
+++ b/mcs/mcs/typespec.cs
@@ -225,6 +225,8 @@ namespace Mono.CSharp
 			}
 		}
 
+		public bool IsByRefLike => (modifiers & Modifiers.REF) != 0;
+
 		//
 		// Returns true for instances of System.Threading.Tasks.Task<T>
 		//
@@ -1452,6 +1454,7 @@ namespace Mono.CSharp
 		int TypeParametersCount { get; }
 		TypeParameterSpec[] TypeParameters { get; }
 
+		TypeSpec GetAsyncMethodBuilder ();
 		TypeSpec GetAttributeCoClass ();
 		string GetAttributeDefaultMember ();
 		AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa);
@@ -1461,6 +1464,29 @@ namespace Mono.CSharp
 
 	class InternalType : TypeSpec, ITypeDefinition
 	{
+		sealed class InternalTypeAssembly : IAssemblyDefinition
+		{
+			public static readonly InternalTypeAssembly Instance = new InternalTypeAssembly ();
+
+			public string FullName => throw new NotImplementedException ();
+
+			public bool IsCLSCompliant => false;
+
+			public bool IsMissing => false;
+
+			public string Name => throw new NotImplementedException ();
+
+			public byte [] GetPublicKeyToken ()
+			{
+				throw new NotImplementedException ();
+			}
+
+			public bool IsFriendAssemblyTo (IAssemblyDefinition assembly)
+			{
+				return false;
+			}
+		}
+
 		public static readonly InternalType AnonymousMethod = new InternalType ("anonymous method");
 		public static readonly InternalType Arglist = new InternalType ("__arglist");
 		public static readonly InternalType MethodGroup = new InternalType ("method group");
@@ -1470,6 +1496,8 @@ namespace Mono.CSharp
 		public static readonly InternalType ErrorType = new InternalType ("<error>");
 		public static readonly InternalType VarOutType = new InternalType ("var out");
 		public static readonly InternalType ThrowExpr = new InternalType ("throw expression");
+		public static readonly InternalType DefaultType = new InternalType ("default");
+		public static readonly InternalType Discard = new InternalType ("discard");
 
 		readonly string name;
 
@@ -1494,7 +1522,7 @@ namespace Mono.CSharp
 
 		IAssemblyDefinition ITypeDefinition.DeclaringAssembly {
 			get {
-				throw new NotImplementedException ();
+				return InternalTypeAssembly.Instance;
 			}
 		}
 
@@ -1561,6 +1589,11 @@ namespace Mono.CSharp
 
 		#region ITypeDefinition Members
 
+		TypeSpec ITypeDefinition.GetAsyncMethodBuilder ()
+		{
+			return null;
+		}
+
 		TypeSpec ITypeDefinition.GetAttributeCoClass ()
 		{
 			return null;
@@ -1614,7 +1647,7 @@ namespace Mono.CSharp
 
 		public static bool HasNoType (TypeSpec type)
 		{
-			return type == AnonymousMethod || type == MethodGroup || type == NullLiteral || type == ThrowExpr;
+			return type == AnonymousMethod || type == MethodGroup || type == NullLiteral || type == ThrowExpr || type == DefaultType;
 		}
 	}
 
@@ -1749,6 +1782,11 @@ namespace Mono.CSharp
 			}
 		}
 
+		public TypeSpec GetAsyncMethodBuilder ()
+		{
+			return null;
+		}
+
 		public TypeSpec GetAttributeCoClass ()
 		{
 			return Element.MemberDefinition.GetAttributeCoClass ();
@@ -1996,9 +2034,10 @@ namespace Mono.CSharp
 	[System.Diagnostics.DebuggerDisplay("{DisplayDebugInfo()}")]
 	class ReferenceContainer : ElementTypeSpec
 	{
-		ReferenceContainer (TypeSpec element)
+		protected ReferenceContainer (TypeSpec element)
 			: base (MemberKind.ByRef, element, null)
 		{
+			cache = null;
 		}
 
 		public override IList<TypeSpec> Interfaces {
@@ -2039,6 +2078,39 @@ namespace Mono.CSharp
 
 			return pc;
 		}
+
+		protected override void InitializeMemberCache(bool onlyTypes)
+		{
+			cache = Element.MemberCache;
+		}
+	}
+
+	[System.Diagnostics.DebuggerDisplay ("{DisplayDebugInfo()}")]
+	class ReadOnlyReferenceContainer : ReferenceContainer
+	{
+		public ReadOnlyReferenceContainer (TypeSpec element)
+			: base (element)
+		{
+		}
+
+		string DisplayDebugInfo ()
+		{
+			return "ref readonly " + GetSignatureForError ();
+		}
+
+		public new static ReferenceContainer MakeType (ModuleContainer module, TypeSpec element)
+		{
+			if (element.Kind == MemberKind.ByRef)
+				throw new ArgumentException ();
+
+			ReadOnlyReferenceContainer pc;
+			if (!module.ReadonlyReferenceTypesCache.TryGetValue (element, out pc)) {
+				pc = new ReadOnlyReferenceContainer (element);
+				module.ReadonlyReferenceTypesCache.Add (element, pc);
+			}
+
+			return pc;
+		}
 	}
 
 	class PointerContainer : ElementTypeSpec
diff --git a/mcs/tests/gtest-409.cs b/mcs/tests/gtest-409.cs
index 8db59d7e48d..606ae3685d1 100644
--- a/mcs/tests/gtest-409.cs
+++ b/mcs/tests/gtest-409.cs
@@ -1,3 +1,4 @@
+// Compiler options: -langversion:latest
 using System;
 
 //
@@ -175,6 +176,11 @@ public class ConditionalParsing
 		var x = args ?.2f : -.2f;
 	}
 
+	void Test_23 (string args)
+	{
+		var x = args == null ? default : 1;
+	}
+
 	static void Helper<T> (T arg)
 	{
 	}
diff --git a/mcs/tests/test-948.cs b/mcs/tests/test-948.cs
new file mode 100644
index 00000000000..34b3ab9a0c4
--- /dev/null
+++ b/mcs/tests/test-948.cs
@@ -0,0 +1,16 @@
+// Compiler options: -langversion:7.2 -unsafe
+
+using System;
+
+class X
+{
+	public static void Main ()
+	{
+		Span<int> stackSpan = stackalloc int[100];
+	}
+
+	unsafe void Foo ()
+	{
+
+	}
+}
\ No newline at end of file
diff --git a/mcs/tests/test-async-94.cs b/mcs/tests/test-async-94.cs
new file mode 100644
index 00000000000..ce9a30409bb
--- /dev/null
+++ b/mcs/tests/test-async-94.cs
@@ -0,0 +1,127 @@
+using System;
+using System.Threading.Tasks;
+using System.Runtime.CompilerServices;
+
+[AsyncMethodBuilder (typeof(MyTaskMethodBuilder<>))]
+class MyTask<T>
+{
+}
+
+[AsyncMethodBuilder (typeof(MyTaskMethodBuilder))]
+class MyTask
+{
+}
+
+class MyTaskMethodBuilder
+{
+	public static MyTaskMethodBuilder Create()
+	{
+		return null;
+	}
+
+	public MyTask Task {
+		get {
+			return null;
+		}
+	}
+
+	public void SetException (Exception exception)
+	{
+
+	}
+
+	public void SetResult ()
+	{
+
+	}
+
+	public void AwaitOnCompleted<TAwaiter, TStateMachine> (ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine
+	{
+
+	}
+
+	public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine> (ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine
+	{
+
+	}
+
+	public void Start<TStateMachine> (ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
+	{
+
+	}
+
+	public void SetStateMachine (IAsyncStateMachine stateMachine)
+	{
+
+	}	
+}
+
+class MyTaskMethodBuilder<T>
+{
+	public static MyTaskMethodBuilder<T> Create()
+	{
+		return null;
+	}
+
+	public MyTask<T> Task {
+		get {
+			return null;
+		}
+	}
+
+	public void SetException (Exception exception)
+	{
+
+	}
+
+	public void SetResult (T result)
+	{
+
+	}
+
+	public void AwaitOnCompleted<TAwaiter, TStateMachine> (ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine
+	{
+
+	}
+
+	public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine> (ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine
+	{
+
+	}
+
+	public void Start<TStateMachine> (ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
+	{
+
+	}
+
+	public void SetStateMachine (IAsyncStateMachine stateMachine)
+	{
+
+	}
+}
+
+class X
+{
+	public async MyTask Test ()
+	{
+		await Task.Delay (1);
+	}
+
+	public async MyTask<int> Test2 ()
+	{
+		await Task.Delay (1);
+		return 2;
+	}
+
+	public async ValueTask<string> Test3 ()
+	{
+		await Task.Delay (1);
+		return "as";
+	}	
+
+	public static void Main ()
+	{
+		var x = new X ();
+		var r1 = x.Test3 ().Result;
+	}
+}
\ No newline at end of file
diff --git a/mcs/tests/test-default-01.cs b/mcs/tests/test-default-01.cs
new file mode 100644
index 00000000000..823e33c451b
--- /dev/null
+++ b/mcs/tests/test-default-01.cs
@@ -0,0 +1,52 @@
+// Compiler options: -langversion:latest
+
+static class X
+{
+	const int c1 = default;
+	const int c2 = default (int);
+
+	public static void Main ()
+	{
+		int a = default;
+		var b = (int) default;
+		const int c = default;
+		var d = new[] { 1, default };
+		dynamic e = default;
+		int f = checked (default);
+		(int a, int b) g = (1, default);
+		var h = 1 != default;
+		var i = default == M4 ();
+	}
+
+	static int M1 ()
+	{
+		return default;
+	}
+
+	static void M2 ()
+	{
+		try {
+			throw new System.Exception ();
+		} catch (System.Exception) when (default) {
+		}
+
+		if (default) {			
+		}
+	}
+
+	static void M3 (int x = default)
+	{
+	}
+
+	static System.Func<int> M4 ()
+	{
+		return () => default;
+	} 
+}
+/*
+enum E
+{
+	A = default,
+	B = default + 1
+}
+*/
\ No newline at end of file
diff --git a/mcs/tests/test-default-02.cs b/mcs/tests/test-default-02.cs
new file mode 100644
index 00000000000..0039782e5f2
--- /dev/null
+++ b/mcs/tests/test-default-02.cs
@@ -0,0 +1,33 @@
+// Compiler options: -langversion:latest
+
+class C
+{
+	static void Main()
+	{
+		M (default, 1);
+
+		M2 (default);
+		M2 (null);
+
+		var res = Test (default);
+	}
+
+
+	static void M<T> (T x, T y)
+	{
+	}
+
+	static void M2 (params object[] x)
+	{        
+	}
+
+	static byte[] Test (S<byte> x)
+	{
+		return null;
+	}
+}
+
+struct S<T>
+{
+
+}
\ No newline at end of file
diff --git a/mcs/tests/test-discards-01.cs b/mcs/tests/test-discards-01.cs
new file mode 100644
index 00000000000..54cf29779c6
--- /dev/null
+++ b/mcs/tests/test-discards-01.cs
@@ -0,0 +1,36 @@
+using System;
+
+class X
+{
+	public static void Main ()
+	{
+		string s = null;
+
+		_ = 1;
+		{
+			char _ = '4';
+		}
+
+		_ = TestValue ();
+
+		_ = _ = s;
+
+		byte k1;
+		var s1 = (k1, _) = (1, s);
+
+		Func<object> l1 = () => _ = (_, _) = (1, s);
+
+		TryGetValue (out _);
+	}
+
+	static bool TryGetValue (out int arg)
+	{
+		arg = 3;
+		return true;
+	}
+
+	static int TestValue ()
+	{
+		return 4;
+	}
+}
\ No newline at end of file
diff --git a/mcs/tests/test-named-11.cs b/mcs/tests/test-named-11.cs
new file mode 100644
index 00000000000..a01d2883b9c
--- /dev/null
+++ b/mcs/tests/test-named-11.cs
@@ -0,0 +1,13 @@
+// Compiler options: -langversion:7.2
+
+class X
+{
+	public static void Main ()
+	{
+		Test (arg: 1, "");
+	}
+
+	static void Test (int arg, string str)
+	{
+	}
+}
\ No newline at end of file
diff --git a/mcs/tests/test-readonly-02.cs b/mcs/tests/test-readonly-02.cs
new file mode 100644
index 00000000000..231b8cd8fda
--- /dev/null
+++ b/mcs/tests/test-readonly-02.cs
@@ -0,0 +1,27 @@
+// Compiler options: -langversion:latest
+using System;
+
+public delegate ref readonly int D (int x);
+
+class X
+{
+	public static void Main ()
+	{
+
+	}
+
+	Guid g;
+
+	ref readonly Guid TestMethod ()
+	{
+		return ref g;
+	}
+
+	ref readonly Guid TestProp {
+		get {
+			ref readonly var rg = ref g;
+			return ref rg;
+		}
+	}	
+
+}
\ No newline at end of file
diff --git a/mcs/tests/test-readonly-03.cs b/mcs/tests/test-readonly-03.cs
new file mode 100644
index 00000000000..14cb958b41a
--- /dev/null
+++ b/mcs/tests/test-readonly-03.cs
@@ -0,0 +1,16 @@
+// Compiler options: -langversion:latest
+using System;
+
+readonly struct S
+{
+	static S shared = new S ();
+
+	public S (int arg)
+	{
+		this = shared;
+	}
+
+	public static void Main ()
+	{
+	}
+}
\ No newline at end of file
diff --git a/mcs/tests/test-ref-07.cs b/mcs/tests/test-ref-07.cs
new file mode 100644
index 00000000000..4aa16579752
--- /dev/null
+++ b/mcs/tests/test-ref-07.cs
@@ -0,0 +1,30 @@
+// Compiler options: -langversion:latest
+
+public readonly partial ref struct Test
+{
+	public static void Main ()
+	{
+		var m = new Test ();
+		m.Method ();
+	}
+
+	Test Method ()
+	{
+		return new Test ();
+	}
+}
+
+ref struct Second
+{
+	Test field;
+}
+
+public abstract class P
+{
+	public abstract Test Span { get; }
+}
+
+public interface II
+{
+	Test Span { get; }
+}
diff --git a/mcs/tests/test-ref-08.cs b/mcs/tests/test-ref-08.cs
new file mode 100644
index 00000000000..f4ff50f4c5c
--- /dev/null
+++ b/mcs/tests/test-ref-08.cs
@@ -0,0 +1,101 @@
+using System;
+
+namespace ClassLibrary1
+{
+	public class C
+	{
+
+		class B
+		{
+			int v;
+			public ref int this[int index]
+			{
+				get
+				{
+					return ref v;
+				}
+			}
+		}
+
+
+		class Gen<T> where T : struct
+		{
+			T v;
+			public ref T this[int index]
+			{
+				get
+				{
+					return ref v;
+				}
+			}
+		}
+
+		struct Val
+		{
+		}
+
+		class BB
+		{
+			Val v;
+			public ref Val this[int index]
+			{
+				get
+				{
+					return ref v;
+				}
+			}
+		}
+
+		void MM ()
+		{
+			var bbb = new BB();
+			Val v1 = bbb[0];
+			bbb[1] = v1;
+
+			ref Val v2 = ref bbb[2];
+			bbb[2] = v2;
+		}
+
+		static int[] a = new int[1];
+		public static void Main()
+		{
+			var bb = new B();
+			int b = 1;
+			bb[0] = b;
+			a[0] = Add2(ref b, 2);
+
+			var bbb = new BB();
+			bbb[0] = new Val();
+
+			var v = new Val();
+			bbb[1] = v;
+
+			var v2 = bbb[2];
+
+			bbb[3] = v2;
+
+
+			bbb[3] = bbb[2];
+
+
+
+			var ggg = new Gen<Val>();
+			ggg[0] = new Val();
+
+			var g = new Val();
+			ggg[1] = v;
+
+			var g2 = ggg[2];
+
+			ggg[3] = v2;
+
+
+			ggg[3] = ggg[2];
+		}
+
+		public static ref int Add2(ref int a, int b)
+		{
+			return ref a;
+		}
+	}
+}
\ No newline at end of file
diff --git a/mcs/tests/test-ref-09.cs b/mcs/tests/test-ref-09.cs
new file mode 100644
index 00000000000..5d0e89e5c1a
--- /dev/null
+++ b/mcs/tests/test-ref-09.cs
@@ -0,0 +1,12 @@
+struct rigidbody { public float x; }
+
+class Program
+{
+	static rigidbody a;
+	static ref rigidbody property_returning_struct_by_ref => ref a;
+
+	static void Main()
+	{
+		System.Console.WriteLine (property_returning_struct_by_ref.x);
+	}
+}
\ No newline at end of file
diff --git a/mcs/tests/test-ref-10.cs b/mcs/tests/test-ref-10.cs
new file mode 100644
index 00000000000..88e201d3174
--- /dev/null
+++ b/mcs/tests/test-ref-10.cs
@@ -0,0 +1,24 @@
+// Compiler options: -langversion:latest
+
+using System;
+
+ref struct ValueStringBuilder
+{
+	public override string ToString ()
+	{
+		return "aaa";
+	}
+}
+
+
+class X
+{
+	public static int Main ()
+	{
+		var s = new ValueStringBuilder ();
+		if (s.ToString () != "aaa")
+			return 1;
+
+		return 0;
+	}
+}
\ No newline at end of file
diff --git a/mcs/tests/test-tuple-07.cs b/mcs/tests/test-tuple-07.cs
new file mode 100644
index 00000000000..cc7ce5837ce
--- /dev/null
+++ b/mcs/tests/test-tuple-07.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+
+// Parser tests
+
+class ParserTest
+{
+	IEnumerable<(Object vertex, int distance)> Test ()
+	{
+		return null;
+	}
+
+	public static void Main ()
+	{		
+	}
+}
\ No newline at end of file
diff --git a/mcs/tests/test-tuple-09.cs b/mcs/tests/test-tuple-09.cs
new file mode 100644
index 00000000000..3f15cae6cf1
--- /dev/null
+++ b/mcs/tests/test-tuple-09.cs
@@ -0,0 +1,19 @@
+using System;
+
+class TupleDeconstructionDeclaration
+{
+	public static int Main ()
+	{
+		(string s, long l) = GetValues ();
+		(var vs, var vl) = GetValues ();
+		(object o, var vl2) = GetValues ();
+		(string ds, _) = GetValues ();
+
+		return 0;
+	}
+
+	static (string, long) GetValues ()
+	{
+		return ("a", 3);
+	}
+}
\ No newline at end of file
diff --git a/mcs/tests/ver-il-net_4_x.xml b/mcs/tests/ver-il-net_4_x.xml
index c2c98123305..4dbc7042a8a 100644
--- a/mcs/tests/ver-il-net_4_x.xml
+++ b/mcs/tests/ver-il-net_4_x.xml
@@ -14659,6 +14659,9 @@
       <method name="Void Test_22(Boolean)" attrs="129">
         <size>24</size>
       </method>
+      <method name="Void Test_23(System.String)" attrs="129">
+        <size>16</size>
+      </method>
     </type>
   </test>
   <test name="gtest-410.cs">
@@ -52808,6 +52811,19 @@
       </method>
     </type>
   </test>
+  <test name="test-948.cs">
+    <type name="X">
+      <method name="Void Main()" attrs="150">
+        <size>16</size>
+      </method>
+      <method name="Void Foo()" attrs="129">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-95.cs">
     <type name="X">
       <method name="Int32 Main()" attrs="150">
@@ -66893,6 +66909,117 @@
       </method>
     </type>
   </test>
+  <test name="test-async-94.cs">
+    <type name="MyTask`1[T]">
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="MyTask">
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="MyTaskMethodBuilder">
+      <method name="MyTaskMethodBuilder Create()" attrs="150">
+        <size>10</size>
+      </method>
+      <method name="MyTask get_Task()" attrs="2182">
+        <size>10</size>
+      </method>
+      <method name="Void SetException(System.Exception)" attrs="134">
+        <size>2</size>
+      </method>
+      <method name="Void SetResult()" attrs="134">
+        <size>2</size>
+      </method>
+      <method name="Void AwaitOnCompleted[TAwaiter,TStateMachine](TAwaiter ByRef, TStateMachine ByRef)" attrs="134">
+        <size>2</size>
+      </method>
+      <method name="Void AwaitUnsafeOnCompleted[TAwaiter,TStateMachine](TAwaiter ByRef, TStateMachine ByRef)" attrs="134">
+        <size>2</size>
+      </method>
+      <method name="Void Start[TStateMachine](TStateMachine ByRef)" attrs="134">
+        <size>2</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="134">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="MyTaskMethodBuilder`1[T]">
+      <method name="MyTaskMethodBuilder`1[T] Create()" attrs="150">
+        <size>10</size>
+      </method>
+      <method name="MyTask`1[T] get_Task()" attrs="2182">
+        <size>10</size>
+      </method>
+      <method name="Void SetException(System.Exception)" attrs="134">
+        <size>2</size>
+      </method>
+      <method name="Void SetResult(T)" attrs="134">
+        <size>2</size>
+      </method>
+      <method name="Void AwaitOnCompleted[TAwaiter,TStateMachine](TAwaiter ByRef, TStateMachine ByRef)" attrs="134">
+        <size>2</size>
+      </method>
+      <method name="Void AwaitUnsafeOnCompleted[TAwaiter,TStateMachine](TAwaiter ByRef, TStateMachine ByRef)" attrs="134">
+        <size>2</size>
+      </method>
+      <method name="Void Start[TStateMachine](TStateMachine ByRef)" attrs="134">
+        <size>2</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="134">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="X">
+      <method name="MyTask Test()" attrs="134">
+        <size>33</size>
+      </method>
+      <method name="MyTask`1[System.Int32] Test2()" attrs="134">
+        <size>33</size>
+      </method>
+      <method name="System.Threading.Tasks.ValueTask`1[System.String] Test3()" attrs="134">
+        <size>33</size>
+      </method>
+      <method name="Void Main()" attrs="150">
+        <size>23</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="X+&lt;Test&gt;c__async0">
+      <method name="Void MoveNext()" attrs="486">
+        <size>157</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+    <type name="X+&lt;Test2&gt;c__async1">
+      <method name="Void MoveNext()" attrs="486">
+        <size>165</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+    <type name="X+&lt;Test3&gt;c__async2">
+      <method name="Void MoveNext()" attrs="486">
+        <size>169</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+  </test>
   <test name="test-cls-00.cs">
     <type name="CLSCLass_6">
       <method name="Void add_Disposed(Delegate)" attrs="2182">
@@ -68527,6 +68654,47 @@
       </method>
     </type>
   </test>
+  <test name="test-default-01.cs">
+    <type name="X">
+      <method name="Void Main()" attrs="150">
+        <size>53</size>
+      </method>
+      <method name="Int32 M1()" attrs="145">
+        <size>10</size>
+      </method>
+      <method name="Void M2()" attrs="145">
+        <size>31</size>
+      </method>
+      <method name="Void M3(Int32)" attrs="145">
+        <size>2</size>
+      </method>
+      <method name="System.Func`1[System.Int32] M4()" attrs="145">
+        <size>38</size>
+      </method>
+      <method name="Int32 &lt;M4&gt;m__0()" attrs="145">
+        <size>9</size>
+      </method>
+    </type>
+  </test>
+  <test name="test-default-02.cs">
+    <type name="C">
+      <method name="Void Main()" attrs="145">
+        <size>36</size>
+      </method>
+      <method name="Void M[T](T, T)" attrs="145">
+        <size>2</size>
+      </method>
+      <method name="Void M2(System.Object[])" attrs="145">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+      <method name="Byte[] Test(S`1[System.Byte])" attrs="145">
+        <size>10</size>
+      </method>
+    </type>
+  </test>
   <test name="test-dictinit-01.cs">
     <type name="Program">
       <method name="Int32 Main()" attrs="145">
@@ -68610,6 +68778,30 @@
       </method>
     </type>
   </test>
+  <test name="test-discards-01.cs">
+    <type name="X">
+      <method name="Void Main()" attrs="150">
+        <size>63</size>
+      </method>
+      <method name="Boolean TryGetValue(Int32 ByRef)" attrs="145">
+        <size>13</size>
+      </method>
+      <method name="Int32 TestValue()" attrs="145">
+        <size>10</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="X+&lt;Main&gt;c__AnonStorey0">
+      <method name="System.Object &lt;&gt;m__0()" attrs="131">
+        <size>25</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-ex-filter-01.cs">
     <type name="X">
       <method name="Int32 Main()" attrs="150">
@@ -70689,6 +70881,19 @@
       </method>
     </type>
   </test>
+  <test name="test-named-11.cs">
+    <type name="X">
+      <method name="Void Main()" attrs="150">
+        <size>13</size>
+      </method>
+      <method name="Void Test(Int32, System.String)" attrs="145">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-nameof-01.cs">
     <type name="X">
       <method name="Int32 Main()" attrs="150">
@@ -72778,6 +72983,49 @@
       </method>
     </type>
   </test>
+  <test name="test-readonly-02.cs">
+    <type name="D">
+      <method name="Int32&amp; Invoke(Int32)" attrs="454">
+        <size>0</size>
+      </method>
+      <method name="System.IAsyncResult BeginInvoke(Int32, System.AsyncCallback, System.Object)" attrs="454">
+        <size>0</size>
+      </method>
+      <method name="Int32&amp; EndInvoke(System.IAsyncResult)" attrs="454">
+        <size>0</size>
+      </method>
+      <method name="Void .ctor(Object, IntPtr)" attrs="6278">
+        <size>0</size>
+      </method>
+    </type>
+    <type name="X">
+      <method name="Void Main()" attrs="150">
+        <size>2</size>
+      </method>
+      <method name="System.Guid&amp; TestMethod()" attrs="129">
+        <size>15</size>
+      </method>
+      <method name="System.Guid&amp; get_TestProp()" attrs="2177">
+        <size>17</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="test-readonly-03.cs">
+    <type name="S">
+      <method name="Void Main()" attrs="150">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor(Int32)" attrs="6278">
+        <size>13</size>
+      </method>
+      <method name="Void .cctor()" attrs="6289">
+        <size>15</size>
+      </method>
+    </type>
+  </test>
   <test name="test-ref-01.cs">
     <type name="X">
       <method name="Void Main()" attrs="150">
@@ -72906,6 +73154,95 @@
       </method>
     </type>
   </test>
+  <test name="test-ref-07.cs">
+    <type name="Test">
+      <method name="Void Main()" attrs="150">
+        <size>18</size>
+      </method>
+      <method name="Test Method()" attrs="129">
+        <size>18</size>
+      </method>
+    </type>
+    <type name="P">
+      <method name="Test get_Span()" attrs="3526">
+        <size>0</size>
+      </method>
+      <method name="Void .ctor()" attrs="6276">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="test-ref-08.cs">
+    <type name="ClassLibrary1.C">
+      <method name="Void MM()" attrs="129">
+        <size>60</size>
+      </method>
+      <method name="Void Main()" attrs="150">
+        <size>245</size>
+      </method>
+      <method name="Int32&amp; Add2(Int32 ByRef, Int32)" attrs="150">
+        <size>10</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+      <method name="Void .cctor()" attrs="6289">
+        <size>12</size>
+      </method>
+    </type>
+    <type name="ClassLibrary1.C+B">
+      <method name="Int32&amp; get_Item(Int32)" attrs="2182">
+        <size>15</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="ClassLibrary1.C+Gen`1[T]">
+      <method name="T&amp; get_Item(Int32)" attrs="2182">
+        <size>15</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="ClassLibrary1.C+BB">
+      <method name="Val&amp; get_Item(Int32)" attrs="2182">
+        <size>15</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="test-ref-09.cs">
+    <type name="Program">
+      <method name="rigidbody&amp; get_property_returning_struct_by_ref()" attrs="2193">
+        <size>13</size>
+      </method>
+      <method name="Void Main()" attrs="145">
+        <size>17</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="test-ref-10.cs">
+    <type name="ValueStringBuilder">
+      <method name="System.String ToString()" attrs="198">
+        <size>14</size>
+      </method>
+    </type>
+    <type name="X">
+      <method name="Int32 Main()" attrs="150">
+        <size>47</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-static-using-01.cs">
     <type name="A.B.X">
       <method name="Int32 Test()" attrs="150">
@@ -73374,6 +73711,56 @@
       </method>
     </type>
   </test>
+  <test name="test-tuple-07.cs">
+    <type name="ParserTest">
+      <method name="System.Collections.Generic.IEnumerable`1[System.ValueTuple`2[System.Object,System.Int32]] Test()" attrs="129">
+        <size>10</size>
+      </method>
+      <method name="Void Main()" attrs="150">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="test-tuple-08.cs">
+    <type name="X">
+      <method name="Void Main()" attrs="150">
+        <size>19</size>
+      </method>
+      <method name="System.Threading.Tasks.Task Test()" attrs="129">
+        <size>41</size>
+      </method>
+      <method name="System.Threading.Tasks.Task`1[System.ValueTuple`2[System.Int32,System.Int32]] Waiting()" attrs="129">
+        <size>21</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="X+&lt;Test&gt;c__async0">
+      <method name="Void MoveNext()" attrs="486">
+        <size>212</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+  </test>
+  <test name="test-tuple-09.cs">
+    <type name="TupleDeconstructionDeclaration">
+      <method name="Int32 Main()" attrs="150">
+        <size>99</size>
+      </method>
+      <method name="System.ValueTuple`2[System.String,System.Int64] GetValues()" attrs="145">
+        <size>21</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-var-01.cs">
     <type name="Test">
       <method name="Int32 Main()" attrs="150">
